feat(cli): clean up wiki and sl commands (#65)

* feat(cli): clean up wiki and sl commands

* test(scripts): update package artifact CLI smoke assertion
This commit is contained in:
Andrey Avtomonov 2026-05-13 15:41:10 +02:00 committed by GitHub
parent e1e9c4af91
commit c202202e6b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 312 additions and 586 deletions

View file

@ -1,11 +1,9 @@
import { type Command, Option } from '@commander-js/extra-typings';
import { type Command } from '@commander-js/extra-typings';
import {
collectOption,
type KtxCliCommandContext,
parsePositiveIntegerOption,
resolveCommandProjectDir,
} from '../cli-program.js';
import { wikiWriteCommandSchema } from '../command-schemas.js';
import type { KtxKnowledgeArgs } from '../knowledge.js';
import { profileMark } from '../startup-profile.js';
@ -19,7 +17,7 @@ async function runKnowledgeArgs(context: KtxCliCommandContext, args: KtxKnowledg
export function registerWikiCommands(program: Command, context: KtxCliCommandContext): void {
const wiki = program
.command('wiki')
.description('List, read, search, or write local wiki pages')
.description('List or search local wiki pages')
.showHelpAfterError()
.addHelpText(
'after',
@ -40,22 +38,6 @@ export function registerWikiCommands(program: Command, context: KtxCliCommandCon
});
});
wiki
.command('read')
.description('Read one local wiki page')
.argument('<key>', 'Wiki page key')
.option('--json', 'Print JSON output', false)
.option('--user-id <id>', 'Local user id', 'local')
.action(async (key: string, options: { userId: string; json?: boolean }, command) => {
await runKnowledgeArgs(context, {
command: 'read',
projectDir: resolveCommandProjectDir(command),
key,
userId: options.userId,
json: options.json,
});
});
wiki
.command('search')
.description('Search local wiki pages')
@ -73,31 +55,4 @@ export function registerWikiCommands(program: Command, context: KtxCliCommandCon
...(options.limit !== undefined ? { limit: options.limit } : {}),
});
});
wiki
.command('write')
.description('Write one local wiki page')
.argument('<key>', 'Wiki page key')
.option('--user-id <id>', 'Local user id', 'local')
.addOption(new Option('--scope <scope>', 'global or user').choices(['global', 'user']).default('global'))
.requiredOption('--summary <summary>', 'Wiki summary')
.requiredOption('--content <content>', 'Wiki content')
.option('--tag <tag>', 'Wiki tag; repeatable', collectOption, [])
.option('--ref <ref>', 'Wiki ref; repeatable', collectOption, [])
.option('--sl-ref <ref>', 'Semantic-layer ref; repeatable', collectOption, [])
.action(async (key: string, options, command) => {
const args = wikiWriteCommandSchema.parse({
command: 'write',
projectDir: resolveCommandProjectDir(command),
key,
scope: options.scope === 'user' ? 'USER' : 'GLOBAL',
userId: options.userId,
summary: options.summary,
content: options.content,
tags: options.tag,
refs: options.ref,
slRefs: options.slRef,
});
await runKnowledgeArgs(context, args);
});
}

View file

@ -41,7 +41,7 @@ async function runSlArgs(context: KtxCliCommandContext, args: KtxSlArgs): Promis
export function registerSlCommands(program: Command, context: KtxCliCommandContext, commandName = 'sl'): void {
const sl = program
.command(commandName)
.description('List, read, validate, query, or write local semantic-layer sources')
.description('List, search, validate, or query local semantic-layer sources')
.showHelpAfterError()
.addHelpText(
'after',
@ -51,7 +51,31 @@ export function registerSlCommands(program: Command, context: KtxCliCommandConte
sl.command('list')
.description('List semantic-layer sources')
.option('--connection-id <id>', 'KTX connection id')
.option('--query <text>', 'Search source names and descriptions')
.addOption(
new Option('--output <mode>', 'Output mode: pretty (default in TTY), plain (TSV), or json').choices([
'pretty',
'plain',
'json',
]),
)
.option('--json', 'Shortcut for --output=json (overrides --output)', false)
.action(
async (options: { connectionId?: string; output?: 'pretty' | 'plain' | 'json'; json?: boolean }, command) => {
await runSlArgs(context, {
command: 'list',
projectDir: resolveCommandProjectDir(command),
connectionId: options.connectionId,
output: options.output,
json: options.json,
});
},
);
sl.command('search')
.description('Search semantic-layer sources')
.argument('<query>', 'Search query')
.option('--connection-id <id>', 'KTX connection id')
.option('--limit <number>', 'Maximum search results', parsePositiveIntegerOption)
.addOption(
new Option('--output <mode>', 'Output mode: pretty (default in TTY), plain (TSV), or json').choices([
'pretty',
@ -62,35 +86,22 @@ export function registerSlCommands(program: Command, context: KtxCliCommandConte
.option('--json', 'Shortcut for --output=json (overrides --output)', false)
.action(
async (
options: { connectionId?: string; query?: string; output?: 'pretty' | 'plain' | 'json'; json?: boolean },
query: string,
options: { connectionId?: string; limit?: number; output?: 'pretty' | 'plain' | 'json'; json?: boolean },
command,
) => {
await runSlArgs(context, {
command: 'list',
projectDir: resolveCommandProjectDir(command),
connectionId: options.connectionId,
query: options.query,
output: options.output,
json: options.json,
});
await runSlArgs(context, {
command: 'search',
projectDir: resolveCommandProjectDir(command),
connectionId: options.connectionId,
query,
...(options.limit !== undefined ? { limit: options.limit } : {}),
output: options.output,
json: options.json,
});
},
);
sl.command('read')
.description('Read a semantic-layer source')
.argument('<sourceName>', 'Semantic-layer source name')
.requiredOption('--connection-id <id>', 'KTX connection id')
.option('--json', 'Print JSON output', false)
.action(async (sourceName: string, options: { connectionId: string; json?: boolean }, command) => {
await runSlArgs(context, {
command: 'read',
projectDir: resolveCommandProjectDir(command),
connectionId: options.connectionId,
sourceName,
json: options.json,
});
});
sl.command('validate')
.description('Validate a semantic-layer source')
.argument('<sourceName>', 'Semantic-layer source name')
@ -104,21 +115,6 @@ export function registerSlCommands(program: Command, context: KtxCliCommandConte
});
});
sl.command('write')
.description('Write a semantic-layer source')
.argument('<sourceName>', 'Semantic-layer source name')
.requiredOption('--connection-id <id>', 'KTX connection id')
.requiredOption('--yaml <yaml>', 'Semantic-layer source YAML')
.action(async (sourceName: string, options: { connectionId: string; yaml: string }, command) => {
await runSlArgs(context, {
command: 'write',
projectDir: resolveCommandProjectDir(command),
connectionId: options.connectionId,
sourceName,
yaml: options.yaml,
});
});
sl.command('query')
.description('Compile or execute a semantic-layer query')
.option('--connection-id <id>', 'KTX connection id')