rename klo to ktx

This commit is contained in:
Andrey Avtomonov 2026-05-10 23:51:24 +02:00
parent 1a42152e6f
commit 3ce510b55b
704 changed files with 10205 additions and 10255 deletions

View file

@ -1,6 +1,6 @@
import { createHash } from 'node:crypto';
import YAML from 'yaml';
import type { KloEmbeddingPort, KloFileStorePort, KloLogger } from '../core/index.js';
import type { KtxEmbeddingPort, KtxFileStorePort, KtxLogger } from '../core/index.js';
import { noopLogger } from '../core/index.js';
import { buildKnowledgeSearchText } from './knowledge-search-text.js';
import type { KnowledgeGitDiffPort, KnowledgeIndexPort, UpsertPageParams } from './ports.js';
@ -14,11 +14,11 @@ export class KnowledgeWikiService {
private isWorktreeScoped = false;
constructor(
private readonly configService: KloFileStorePort,
private readonly embeddingService: KloEmbeddingPort,
private readonly configService: KtxFileStorePort,
private readonly embeddingService: KtxEmbeddingPort,
private readonly pagesRepository: KnowledgeIndexPort,
private readonly gitService: KnowledgeGitDiffPort,
private readonly logger: KloLogger = noopLogger,
private readonly logger: KtxLogger = noopLogger,
) {}
/**
@ -30,7 +30,7 @@ export class KnowledgeWikiService {
*/
forWorktree(workdir: string): KnowledgeWikiService {
return new KnowledgeWikiService(
this.configService.forWorktree(workdir) as KloFileStorePort,
this.configService.forWorktree(workdir) as KtxFileStorePort,
this.embeddingService,
this.pagesRepository,
this.gitService,

View file

@ -2,7 +2,7 @@ import { access, mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { initKloProject, type KloLocalProject } from '../project/index.js';
import { initKtxProject, type KtxLocalProject } from '../project/index.js';
import {
listLocalKnowledgePages,
readLocalKnowledgePage,
@ -24,11 +24,11 @@ class FakeEmbeddingPort {
describe('local knowledge helpers', () => {
let tempDir: string;
let project: KloLocalProject;
let project: KtxLocalProject;
beforeEach(async () => {
tempDir = await mkdtemp(join(tmpdir(), 'klo-local-knowledge-'));
project = await initKloProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
tempDir = await mkdtemp(join(tmpdir(), 'ktx-local-knowledge-'));
project = await initKtxProject({ projectDir: join(tempDir, 'project'), projectName: 'warehouse' });
});
afterEach(async () => {
@ -80,7 +80,7 @@ describe('local knowledge helpers', () => {
}),
]);
expect(search[0]?.score).toBeGreaterThan(0);
await expect(access(join(project.projectDir, '.klo', 'db.sqlite'))).resolves.toBeUndefined();
await expect(access(join(project.projectDir, '.ktx', 'db.sqlite'))).resolves.toBeUndefined();
});
it('adds the token lane alongside lexical wiki matches', async () => {

View file

@ -1,7 +1,7 @@
import { join } from 'node:path';
import YAML from 'yaml';
import type { KloEmbeddingPort, KloFileWriteResult } from '../core/index.js';
import type { KloLocalProject } from '../project/index.js';
import type { KtxEmbeddingPort, KtxFileWriteResult } from '../core/index.js';
import type { KtxLocalProject } from '../project/index.js';
import { HybridSearchCore, type SearchCandidateGenerator } from '../search/index.js';
import { buildKnowledgeSearchText } from './knowledge-search-text.js';
import { SqliteKnowledgeIndex, type SqliteKnowledgeIndexPage } from './sqlite-knowledge-index.js';
@ -50,8 +50,8 @@ export interface WriteLocalKnowledgePageInput {
fingerprints?: string[];
}
const LOCAL_AUTHOR = 'klo';
const LOCAL_AUTHOR_EMAIL = 'klo@example.com';
const LOCAL_AUTHOR = 'ktx';
const LOCAL_AUTHOR_EMAIL = 'ktx@example.com';
function assertSafePathToken(kind: string, value: string): string {
if (
@ -137,7 +137,7 @@ function serializeKnowledgePage(input: WriteLocalKnowledgePageInput): string {
}
async function readPageAtPath(
project: KloLocalProject,
project: KtxLocalProject,
key: string,
path: string,
scope: LocalKnowledgeScope,
@ -151,9 +151,9 @@ async function readPageAtPath(
}
export async function writeLocalKnowledgePage(
project: KloLocalProject,
project: KtxLocalProject,
input: WriteLocalKnowledgePageInput,
): Promise<KloFileWriteResult> {
): Promise<KtxFileWriteResult> {
const path = knowledgePath(input.scope, input.userId, input.key);
return project.fileStore.writeFile(
path,
@ -165,7 +165,7 @@ export async function writeLocalKnowledgePage(
}
export async function readLocalKnowledgePage(
project: KloLocalProject,
project: KtxLocalProject,
input: { key: string; userId?: string },
): Promise<LocalKnowledgePage | null> {
const userPath = knowledgePath('USER', input.userId, input.key);
@ -177,7 +177,7 @@ export async function readLocalKnowledgePage(
}
export async function listLocalKnowledgePages(
project: KloLocalProject,
project: KtxLocalProject,
input: { userId?: string } = {},
): Promise<LocalKnowledgeSummary[]> {
const userId = input.userId ?? 'local';
@ -201,8 +201,8 @@ function scorePage(page: LocalKnowledgePage, terms: string[]): number {
return terms.some((term) => haystack.includes(term)) ? 3 : 0;
}
function sqliteKnowledgeDbPath(project: KloLocalProject): string {
return join(project.projectDir, '.klo', 'db.sqlite');
function sqliteKnowledgeDbPath(project: KtxLocalProject): string {
return join(project.projectDir, '.ktx', 'db.sqlite');
}
function pageSearchText(page: LocalKnowledgePage): string {
@ -211,7 +211,7 @@ function pageSearchText(page: LocalKnowledgePage): string {
async function embeddingForPageSearchText(
searchText: string,
embeddingService: KloEmbeddingPort | null,
embeddingService: KtxEmbeddingPort | null,
): Promise<number[] | null> {
if (!embeddingService) {
return null;
@ -234,7 +234,7 @@ function tokenLaneCandidates(pages: LocalKnowledgePage[], terms: string[]) {
}
async function loadAllKnowledgePages(
project: KloLocalProject,
project: KtxLocalProject,
input: { userId?: string } = {},
): Promise<LocalKnowledgePage[]> {
const summaries = await listLocalKnowledgePages(project, { userId: input.userId });
@ -249,8 +249,8 @@ async function loadAllKnowledgePages(
}
async function searchLocalKnowledgePagesWithSqlite(
project: KloLocalProject,
input: { query: string; userId?: string; embeddingService?: KloEmbeddingPort | null; limit?: number },
project: KtxLocalProject,
input: { query: string; userId?: string; embeddingService?: KtxEmbeddingPort | null; limit?: number },
): Promise<LocalKnowledgeSearchResult[]> {
const pages = await loadAllKnowledgePages(project, { userId: input.userId });
const byPath = new Map(pages.map((page) => [page.path, page]));
@ -352,7 +352,7 @@ async function searchLocalKnowledgePagesWithSqlite(
}
async function searchLocalKnowledgePagesWithScan(
project: KloLocalProject,
project: KtxLocalProject,
input: { query: string; userId?: string; limit?: number },
): Promise<LocalKnowledgeSearchResult[]> {
const terms = input.query
@ -381,8 +381,8 @@ async function searchLocalKnowledgePagesWithScan(
}
export async function searchLocalKnowledgePages(
project: KloLocalProject,
input: { query: string; userId?: string; embeddingService?: KloEmbeddingPort | null; limit?: number },
project: KtxLocalProject,
input: { query: string; userId?: string; embeddingService?: KtxEmbeddingPort | null; limit?: number },
): Promise<LocalKnowledgeSearchResult[]> {
if (project.config.storage.search === 'sqlite-fts5') {
return searchLocalKnowledgePagesWithSqlite(project, input);

View file

@ -1,4 +1,4 @@
import type { KloFileStorePort } from '../core/file-store.js';
import type { KtxFileStorePort } from '../core/file-store.js';
export interface UpsertPageParams {
scope: string;
@ -65,4 +65,4 @@ export interface KnowledgeGitDiffPort {
getFileAtCommit(path: string, sha: string): Promise<string>;
}
export type WikiFileStorePort = KloFileStorePort<WikiFileStorePort>;
export type WikiFileStorePort = KtxFileStorePort<WikiFileStorePort>;

View file

@ -9,7 +9,7 @@ describe('SqliteKnowledgeIndex', () => {
let dbPath: string;
beforeEach(async () => {
tempDir = await mkdtemp(join(tmpdir(), 'klo-sqlite-knowledge-index-'));
tempDir = await mkdtemp(join(tmpdir(), 'ktx-sqlite-knowledge-index-'));
dbPath = join(tempDir, 'db.sqlite');
});