From 239e9eb9e81bb9d619fdfe5a302088cf32075af3 Mon Sep 17 00:00:00 2001 From: Luca Martial Date: Thu, 14 May 2026 16:02:26 -0700 Subject: [PATCH] refactor(cli): drop removed wiki command internals --- packages/cli/src/io/print-list.ts | 4 +- packages/cli/src/knowledge.test.ts | 143 +++++++---------------------- packages/cli/src/knowledge.ts | 49 +--------- 3 files changed, 38 insertions(+), 158 deletions(-) diff --git a/packages/cli/src/io/print-list.ts b/packages/cli/src/io/print-list.ts index bd7ab20a..b05e12f2 100644 --- a/packages/cli/src/io/print-list.ts +++ b/packages/cli/src/io/print-list.ts @@ -43,13 +43,13 @@ export interface PrintListArgs { io: KtxCliIo; } -export interface KtxJsonResultEnvelope { +interface KtxJsonResultEnvelope { kind: string; data: T; meta?: Record; } -export function writeJsonResult(io: KtxCliIo, envelope: KtxJsonResultEnvelope): void { +function writeJsonResult(io: KtxCliIo, envelope: KtxJsonResultEnvelope): void { io.stdout.write(`${JSON.stringify(envelope, null, 2)}\n`); } diff --git a/packages/cli/src/knowledge.test.ts b/packages/cli/src/knowledge.test.ts index 04f367c0..523d8a1b 100644 --- a/packages/cli/src/knowledge.test.ts +++ b/packages/cli/src/knowledge.test.ts @@ -1,8 +1,9 @@ import { mkdtemp, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; -import { initKtxProject } from '@ktx/context/project'; +import { initKtxProject, loadKtxProject } from '@ktx/context/project'; import type { KtxEmbeddingPort } from '@ktx/context'; +import { writeLocalKnowledgePage } from '@ktx/context/wiki'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { runKtxKnowledge } from './knowledge.js'; @@ -40,6 +41,28 @@ class FakeEmbeddingPort implements KtxEmbeddingPort { } } +interface WikiPageFixture { + key?: string; + summary?: string; + content?: string; + tags?: string[]; + slRefs?: string[]; +} + +async function seedWikiPage(projectDir: string, fixture: WikiPageFixture = {}): Promise { + const project = await loadKtxProject({ projectDir }); + await writeLocalKnowledgePage(project, { + key: fixture.key ?? 'metrics-revenue', + scope: 'GLOBAL', + userId: 'local', + summary: fixture.summary ?? 'Revenue', + content: fixture.content ?? 'Revenue is paid order value.', + tags: fixture.tags ?? ['finance'], + refs: [], + slRefs: fixture.slRefs ?? ['orders'], + }); +} + describe('runKtxKnowledge', () => { let tempDir: string; @@ -51,36 +74,10 @@ describe('runKtxKnowledge', () => { await rm(tempDir, { recursive: true, force: true }); }); - it('writes, reads, lists, and searches wiki pages', async () => { + it('lists and searches wiki pages', async () => { const projectDir = join(tempDir, 'project'); await initKtxProject({ projectDir }); - - const writeIo = makeIo(); - await expect( - runKtxKnowledge( - { - command: 'write', - projectDir, - key: 'metrics-revenue', - scope: 'GLOBAL', - userId: 'local', - summary: 'Revenue', - content: 'Revenue is paid order value.', - tags: ['finance'], - refs: [], - slRefs: ['orders'], - }, - writeIo.io, - ), - ).resolves.toBe(0); - expect(writeIo.stdout()).toContain('Wrote wiki/global/metrics-revenue.md'); - - const readIo = makeIo(); - await expect( - runKtxKnowledge({ command: 'read', projectDir, key: 'metrics-revenue', userId: 'local' }, readIo.io), - ).resolves.toBe(0); - expect(readIo.stdout()).toContain('# metrics-revenue'); - expect(readIo.stdout()).toContain('Revenue is paid order value.'); + await seedWikiPage(projectDir); const listIo = makeIo(); await expect(runKtxKnowledge({ command: 'list', projectDir, userId: 'local' }, listIo.io)).resolves.toBe(0); @@ -93,27 +90,10 @@ describe('runKtxKnowledge', () => { expect(searchIo.stdout()).toContain('metrics-revenue'); }); - it('prints wiki list, search, and read as public JSON envelopes', async () => { + it('prints wiki list and search as public JSON envelopes', async () => { const projectDir = join(tempDir, 'project'); await initKtxProject({ projectDir }); - - await expect( - runKtxKnowledge( - { - command: 'write', - projectDir, - key: 'metrics-revenue', - scope: 'GLOBAL', - userId: 'local', - summary: 'Revenue', - content: 'Revenue is paid order value.', - tags: ['finance'], - refs: [], - slRefs: ['orders'], - }, - makeIo().io, - ), - ).resolves.toBe(0); + await seedWikiPage(projectDir); const listIo = makeIo(); await expect(runKtxKnowledge({ command: 'list', projectDir, userId: 'local', json: true }, listIo.io)).resolves.toBe( @@ -137,48 +117,6 @@ describe('runKtxKnowledge', () => { data: { items: [expect.objectContaining({ key: 'metrics-revenue', summary: 'Revenue' })] }, meta: { command: 'wiki search' }, }); - - const readIo = makeIo(); - await expect( - runKtxKnowledge({ command: 'read', projectDir, key: 'metrics-revenue', userId: 'local', json: true }, readIo.io), - ).resolves.toBe(0); - expect(JSON.parse(readIo.stdout())).toMatchObject({ - kind: 'wiki.page', - data: { - key: 'metrics-revenue', - summary: 'Revenue', - content: 'Revenue is paid order value.', - }, - }); - }); - - it('rejects slash-delimited write keys with a flat-key suggestion', async () => { - const projectDir = join(tempDir, 'project'); - await initKtxProject({ projectDir }); - - const writeIo = makeIo(); - await expect( - runKtxKnowledge( - { - command: 'write', - projectDir, - key: 'orbit/company-overview', - scope: 'GLOBAL', - userId: 'local', - summary: 'Orbit', - content: 'Orbit overview.', - tags: [], - refs: [], - slRefs: [], - }, - writeIo.io, - ), - ).resolves.toBe(1); - - expect(writeIo.stderr()).toContain( - 'Invalid wiki key "orbit/company-overview". Wiki keys must be flat; use "orbit-company-overview".', - ); - expect(writeIo.stdout()).toBe(''); }); it('explains empty search results for a project without wiki pages', async () => { @@ -198,24 +136,13 @@ describe('runKtxKnowledge', () => { it('uses configured embeddings for semantic wiki search', async () => { const projectDir = join(tempDir, 'semantic-project'); await initKtxProject({ projectDir }); - - await expect( - runKtxKnowledge( - { - command: 'write', - projectDir, - key: 'active-contract-arr-open-tickets', - scope: 'GLOBAL', - userId: 'local', - summary: 'Active Contract ARR Ranked by Open Support Ticket Count', - content: 'Accounts ranked by annual recurring contract value and support ticket load.', - tags: ['historic-sql'], - refs: [], - slRefs: [], - }, - makeIo().io, - ), - ).resolves.toBe(0); + await seedWikiPage(projectDir, { + key: 'active-contract-arr-open-tickets', + summary: 'Active Contract ARR Ranked by Open Support Ticket Count', + content: 'Accounts ranked by annual recurring contract value and support ticket load.', + tags: ['historic-sql'], + slRefs: [], + }); const searchIo = makeIo(); await expect( diff --git a/packages/cli/src/knowledge.ts b/packages/cli/src/knowledge.ts index 66109301..d98df9e8 100644 --- a/packages/cli/src/knowledge.ts +++ b/packages/cli/src/knowledge.ts @@ -5,20 +5,16 @@ import { } from '@ktx/context'; import { loadKtxProject } from '@ktx/context/project'; import { - type LocalKnowledgeScope, type LocalKnowledgeSearchResult, type LocalKnowledgeSummary, listLocalKnowledgePages, - readLocalKnowledgePage, searchLocalKnowledgePages, - writeLocalKnowledgePage, } from '@ktx/context/wiki'; import { resolveOutputMode } from './io/mode.js'; -import { printList, type PrintListColumn, writeJsonResult } from './io/print-list.js'; +import { printList, type PrintListColumn } from './io/print-list.js'; export type KtxKnowledgeArgs = | { command: 'list'; projectDir: string; userId: string; output?: string; json?: boolean } - | { command: 'read'; projectDir: string; key: string; userId: string; json?: boolean } | { command: 'search'; projectDir: string; @@ -27,18 +23,6 @@ export type KtxKnowledgeArgs = output?: string; json?: boolean; limit?: number; - } - | { - command: 'write'; - projectDir: string; - key: string; - scope: LocalKnowledgeScope; - userId: string; - summary: string; - content: string; - tags: string[]; - refs: string[]; - slRefs: string[]; }; type KtxKnowledgeIo = import('./cli-runtime.js').KtxCliIo; @@ -104,25 +88,6 @@ export async function runKtxKnowledge( }); return 0; } - if (args.command === 'read') { - const page = await readLocalKnowledgePage(project, { key: args.key, userId: args.userId }); - if (!page) { - throw new Error(`Wiki page "${args.key}" was not found`); - } - if (args.json) { - writeJsonResult(io, { - kind: 'wiki.page', - data: page, - meta: { command: 'wiki read' }, - }); - return 0; - } - io.stdout.write(`# ${page.key}\n\n`); - io.stdout.write(`Scope: ${page.scope}\n`); - io.stdout.write(`Summary: ${page.summary}\n\n`); - io.stdout.write(`${page.content}\n`); - return 0; - } if (args.command === 'search') { const results = await searchLocalKnowledgePages(project, { query: args.query, @@ -153,18 +118,6 @@ export async function runKtxKnowledge( }); return 0; } - - const write = await writeLocalKnowledgePage(project, { - key: args.key, - scope: args.scope, - userId: args.userId, - summary: args.summary, - content: args.content, - tags: args.tags, - refs: args.refs, - slRefs: args.slRefs, - }); - io.stdout.write(`Wrote ${write.path}\n`); return 0; } catch (error) { io.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);