@kaelio/ktx 0.1.0-rc.5 → 0.1.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/python/{kaelio_ktx-0.1.0-py3-none-any.whl → kaelio_ktx-0.1.0rc6-py3-none-any.whl} +0 -0
- package/assets/python/manifest.json +4 -4
- package/dist/clack.d.ts +6 -0
- package/dist/clack.js +23 -0
- package/dist/cli-program.js +5 -2
- package/dist/cli-program.test.js +7 -1
- package/dist/cli-runtime.d.ts +4 -0
- package/dist/cli-runtime.js +8 -1
- package/dist/command-schemas.d.ts +1 -1
- package/dist/commands/ingest-commands.js +1 -0
- package/dist/commands/knowledge-commands.js +5 -0
- package/dist/commands/sql-commands.d.ts +3 -0
- package/dist/commands/sql-commands.js +43 -0
- package/dist/commands/sql-commands.test.js +68 -0
- package/dist/context-build-view.js +5 -1
- package/dist/dev.test.js +27 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.test.js +56 -21
- package/dist/ingest.js +123 -18
- package/dist/ingest.test.js +232 -2
- package/dist/io/print-list.d.ts +2 -1
- package/dist/io/print-list.js +7 -0
- package/dist/io/print-list.test.js +13 -11
- package/dist/io/symbols.d.ts +2 -2
- package/dist/knowledge.d.ts +1 -0
- package/dist/knowledge.js +34 -16
- package/dist/knowledge.test.js +27 -0
- package/dist/managed-python-command.d.ts +2 -0
- package/dist/managed-python-command.js +17 -9
- package/dist/managed-python-command.test.js +59 -4
- package/dist/print-command-tree.js +7 -1
- package/dist/public-ingest.d.ts +9 -1
- package/dist/public-ingest.js +50 -7
- package/dist/public-ingest.test.js +69 -2
- package/dist/release-version.d.ts +5 -0
- package/dist/release-version.js +44 -0
- package/dist/runtime-requirements.d.ts +24 -0
- package/dist/runtime-requirements.js +106 -0
- package/dist/runtime-requirements.test.d.ts +1 -0
- package/dist/runtime-requirements.test.js +63 -0
- package/dist/setup-embeddings.js +3 -6
- package/dist/setup-embeddings.test.js +18 -2
- package/dist/setup-models.js +2 -2
- package/dist/setup-models.test.js +5 -3
- package/dist/setup-ready-menu.d.ts +1 -1
- package/dist/setup-ready-menu.js +2 -0
- package/dist/setup-ready-menu.test.js +3 -0
- package/dist/setup-runtime.d.ts +46 -0
- package/dist/setup-runtime.js +48 -0
- package/dist/setup-runtime.test.d.ts +1 -0
- package/dist/setup-runtime.test.js +116 -0
- package/dist/setup-sources-notion.test.d.ts +1 -0
- package/dist/setup-sources-notion.test.js +107 -0
- package/dist/setup-sources.js +5 -2
- package/dist/setup.d.ts +16 -1
- package/dist/setup.js +57 -8
- package/dist/setup.test.js +118 -50
- package/dist/sl.js +2 -2
- package/dist/sl.test.js +10 -0
- package/dist/source-mapping.js +9 -1
- package/dist/source-mapping.test.d.ts +1 -0
- package/dist/source-mapping.test.js +65 -0
- package/dist/sql.d.ts +22 -0
- package/dist/sql.js +125 -0
- package/dist/sql.test.d.ts +1 -0
- package/dist/sql.test.js +226 -0
- package/node_modules/@ktx/context/dist/connections/connection-type.d.ts +4 -4
- package/node_modules/@ktx/context/dist/core/git.service.d.ts +4 -0
- package/node_modules/@ktx/context/dist/core/git.service.js +59 -1
- package/node_modules/@ktx/context/dist/core/git.service.patch.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/core/git.service.patch.test.js +40 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/historic-sql.adapter.d.ts +2 -1
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/historic-sql.adapter.js +18 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/local-ingest-acceptance.test.js +6 -6
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/projection.d.ts +5 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/projection.js +48 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/projection.test.js +83 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/types.d.ts +5 -5
- package/node_modules/@ktx/context/dist/ingest/adapters/looker/looker.adapter.d.ts +2 -2
- package/node_modules/@ktx/context/dist/ingest/adapters/looker/tools/looker-query-to-sl.tool.d.ts +2 -2
- package/node_modules/@ktx/context/dist/ingest/adapters/looker/types.d.ts +16 -16
- package/node_modules/@ktx/context/dist/ingest/adapters/lookml/pull-config.d.ts +1 -1
- package/node_modules/@ktx/context/dist/ingest/adapters/metabase/fetch.js +16 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/metabase/fetch.test.js +41 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/metricflow.adapter.d.ts +2 -1
- package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/metricflow.adapter.js +40 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/metricflow.adapter.test.js +116 -1
- package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/projection-config.d.ts +29 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/projection-config.js +40 -0
- package/node_modules/@ktx/context/dist/ingest/adapters/metricflow/pull-config.d.ts +1 -1
- package/node_modules/@ktx/context/dist/ingest/artifact-gates.d.ts +25 -0
- package/node_modules/@ktx/context/dist/ingest/artifact-gates.js +149 -0
- package/node_modules/@ktx/context/dist/ingest/artifact-gates.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/artifact-gates.test.js +167 -0
- package/node_modules/@ktx/context/dist/ingest/final-gate-repair.d.ts +29 -0
- package/node_modules/@ktx/context/dist/ingest/final-gate-repair.js +178 -0
- package/node_modules/@ktx/context/dist/ingest/final-gate-repair.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/final-gate-repair.test.js +109 -0
- package/node_modules/@ktx/context/dist/ingest/finalization-scope.d.ts +22 -0
- package/node_modules/@ktx/context/dist/ingest/finalization-scope.js +95 -0
- package/node_modules/@ktx/context/dist/ingest/finalization-scope.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/finalization-scope.test.js +114 -0
- package/node_modules/@ktx/context/dist/ingest/index.d.ts +8 -2
- package/node_modules/@ktx/context/dist/ingest/index.js +7 -1
- package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.d.ts +20 -2
- package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.isolated-diff.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.isolated-diff.test.js +1927 -0
- package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.js +1881 -897
- package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.test.js +328 -156
- package/node_modules/@ktx/context/dist/ingest/ingest-trace.d.ts +50 -0
- package/node_modules/@ktx/context/dist/ingest/ingest-trace.js +88 -0
- package/node_modules/@ktx/context/dist/ingest/ingest-trace.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/ingest-trace.test.js +76 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/git-patch.d.ts +16 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/git-patch.js +78 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/git-patch.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/git-patch.test.js +76 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/patch-integrator.d.ts +58 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/patch-integrator.js +223 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/patch-integrator.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/patch-integrator.test.js +369 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/textual-conflict-resolver.d.ts +23 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/textual-conflict-resolver.js +190 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/textual-conflict-resolver.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/textual-conflict-resolver.test.js +101 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/work-unit-executor.d.ts +15 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/work-unit-executor.js +61 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/work-unit-executor.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/isolated-diff/work-unit-executor.test.js +137 -0
- package/node_modules/@ktx/context/dist/ingest/local-bundle-ingest.test.js +29 -3
- package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.js +54 -14
- package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.test.js +65 -0
- package/node_modules/@ktx/context/dist/ingest/local-ingest.js +0 -7
- package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.d.ts +21 -3
- package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.js +17 -0
- package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.test.js +1 -0
- package/node_modules/@ktx/context/dist/ingest/memory-flow/types.d.ts +6 -0
- package/node_modules/@ktx/context/dist/ingest/parsed-target-table.d.ts +1 -1
- package/node_modules/@ktx/context/dist/ingest/ports.d.ts +4 -20
- package/node_modules/@ktx/context/dist/ingest/report-snapshot.d.ts +101 -5
- package/node_modules/@ktx/context/dist/ingest/report-snapshot.js +52 -0
- package/node_modules/@ktx/context/dist/ingest/report-snapshot.test.js +124 -0
- package/node_modules/@ktx/context/dist/ingest/reports.d.ts +46 -5
- package/node_modules/@ktx/context/dist/ingest/reports.js +7 -24
- package/node_modules/@ktx/context/dist/ingest/semantic-layer-target-policy.d.ts +11 -0
- package/node_modules/@ktx/context/dist/ingest/semantic-layer-target-policy.js +26 -0
- package/node_modules/@ktx/context/dist/ingest/semantic-layer-target-policy.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/semantic-layer-target-policy.test.js +25 -0
- package/node_modules/@ktx/context/dist/ingest/stages/stage-3-work-units.d.ts +4 -0
- package/node_modules/@ktx/context/dist/ingest/stages/stage-3-work-units.js +4 -0
- package/node_modules/@ktx/context/dist/ingest/stages/stage-3-work-units.test.js +29 -0
- package/node_modules/@ktx/context/dist/ingest/tools/emit-unmapped-fallback.tool.d.ts +1 -1
- package/node_modules/@ktx/context/dist/ingest/types.d.ts +57 -0
- package/node_modules/@ktx/context/dist/ingest/wiki-body-refs.d.ts +24 -0
- package/node_modules/@ktx/context/dist/ingest/wiki-body-refs.js +111 -0
- package/node_modules/@ktx/context/dist/ingest/wiki-body-refs.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/ingest/wiki-body-refs.test.js +138 -0
- package/node_modules/@ktx/context/dist/llm/claude-code-runtime.js +19 -2
- package/node_modules/@ktx/context/dist/llm/claude-code-runtime.test.js +33 -0
- package/node_modules/@ktx/context/dist/package-exports.test.js +2 -1
- package/node_modules/@ktx/context/dist/project/setup-config.d.ts +1 -1
- package/node_modules/@ktx/context/dist/project/setup-config.js +10 -1
- package/node_modules/@ktx/context/dist/project/setup-config.test.js +3 -2
- package/node_modules/@ktx/context/dist/sl/tools/sl-edit-source.tool.js +5 -1
- package/node_modules/@ktx/context/dist/sl/tools/sl-edit-source.tool.test.js +15 -0
- package/node_modules/@ktx/context/dist/sl/tools/sl-write-source.tool.js +5 -1
- package/node_modules/@ktx/context/dist/sl/tools/sl-write-source.tool.test.js +22 -0
- package/node_modules/@ktx/context/dist/tools/action-target-connection.d.ts +9 -0
- package/node_modules/@ktx/context/dist/tools/action-target-connection.js +14 -0
- package/node_modules/@ktx/context/dist/tools/context-candidate-write.tool.d.ts +4 -4
- package/node_modules/@ktx/context/dist/tools/index.d.ts +1 -0
- package/node_modules/@ktx/context/dist/tools/index.js +1 -0
- package/node_modules/@ktx/context/dist/wiki/local-knowledge.js +4 -1
- package/node_modules/@ktx/context/dist/wiki/local-knowledge.test.js +44 -0
- package/node_modules/@ktx/context/dist/wiki/tools/wiki-write.tool.js +3 -48
- package/node_modules/@ktx/context/dist/wiki/tools/wiki-write.tool.test.js +28 -0
- package/node_modules/@ktx/context/dist/wiki/wiki-ref-validation.d.ts +17 -0
- package/node_modules/@ktx/context/dist/wiki/wiki-ref-validation.js +79 -0
- package/node_modules/@ktx/context/dist/wiki/wiki-ref-validation.test.d.ts +1 -0
- package/node_modules/@ktx/context/dist/wiki/wiki-ref-validation.test.js +64 -0
- package/node_modules/@ktx/context/prompts/memory_agent_bundle_ingest_work_unit.md +23 -4
- package/node_modules/@ktx/context/skills/ingest_triage/SKILL.md +7 -3
- package/package.json +1 -1
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.d.ts +0 -4
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.js +0 -38
- package/node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.test.js +0 -63
- /package/{node_modules/@ktx/context/dist/ingest/adapters/historic-sql/post-processor.test.d.ts → dist/commands/sql-commands.test.d.ts} +0 -0
package/assets/python/{kaelio_ktx-0.1.0-py3-none-any.whl → kaelio_ktx-0.1.0rc6-py3-none-any.whl}
RENAMED
|
Binary file
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"distributionName": "kaelio-ktx",
|
|
4
4
|
"normalizedName": "kaelio_ktx",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.0rc6",
|
|
6
6
|
"wheel": {
|
|
7
|
-
"file": "kaelio_ktx-0.1.
|
|
8
|
-
"sha256": "
|
|
9
|
-
"bytes":
|
|
7
|
+
"file": "kaelio_ktx-0.1.0rc6-py3-none-any.whl",
|
|
8
|
+
"sha256": "0515d73bf89eb1c32422eb1fab0b59b01b49a23ef7bd8749dc5114361ba17ccc",
|
|
9
|
+
"bytes": 80550
|
|
10
10
|
}
|
|
11
11
|
}
|
package/dist/clack.d.ts
CHANGED
|
@@ -4,6 +4,11 @@ export interface KtxCliSpinner {
|
|
|
4
4
|
stop(message: string): void;
|
|
5
5
|
error(message: string): void;
|
|
6
6
|
}
|
|
7
|
+
export interface KtxCliSpinnerIo {
|
|
8
|
+
stderr: {
|
|
9
|
+
write(chunk: string): void;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
7
12
|
export interface KtxCliPromptAdapter {
|
|
8
13
|
confirm(options: {
|
|
9
14
|
message: string;
|
|
@@ -23,4 +28,5 @@ export declare class KtxCliPromptCancelledError extends Error {
|
|
|
23
28
|
constructor(message?: string);
|
|
24
29
|
}
|
|
25
30
|
export declare function createClackSpinner(): KtxCliSpinner;
|
|
31
|
+
export declare function createStaticCliSpinner(io: KtxCliSpinnerIo): KtxCliSpinner;
|
|
26
32
|
export declare function createClackPromptAdapter(): KtxCliPromptAdapter;
|
package/dist/clack.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { cancel, confirm, isCancel, log, spinner } from '@clack/prompts';
|
|
2
|
+
const ESC = String.fromCharCode(0x1b);
|
|
2
3
|
export class KtxCliPromptCancelledError extends Error {
|
|
3
4
|
constructor(message = 'Operation cancelled.') {
|
|
4
5
|
super(message);
|
|
@@ -8,6 +9,28 @@ export class KtxCliPromptCancelledError extends Error {
|
|
|
8
9
|
export function createClackSpinner() {
|
|
9
10
|
return spinner();
|
|
10
11
|
}
|
|
12
|
+
function magenta(text) {
|
|
13
|
+
return `${ESC}[35m${text}${ESC}[39m`;
|
|
14
|
+
}
|
|
15
|
+
function red(text) {
|
|
16
|
+
return `${ESC}[31m${text}${ESC}[39m`;
|
|
17
|
+
}
|
|
18
|
+
export function createStaticCliSpinner(io) {
|
|
19
|
+
return {
|
|
20
|
+
start(message) {
|
|
21
|
+
io.stderr.write(`${magenta('◐')} ${message}\n`);
|
|
22
|
+
},
|
|
23
|
+
message(message) {
|
|
24
|
+
io.stderr.write(`${magenta('│')} ${message}\n`);
|
|
25
|
+
},
|
|
26
|
+
stop(message) {
|
|
27
|
+
io.stderr.write(`${magenta('◇')} ${message}\n`);
|
|
28
|
+
},
|
|
29
|
+
error(message) {
|
|
30
|
+
io.stderr.write(`${red('■')} ${message}\n`);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
11
34
|
export function createClackPromptAdapter() {
|
|
12
35
|
return {
|
|
13
36
|
async confirm(options) {
|
package/dist/cli-program.js
CHANGED
|
@@ -7,13 +7,15 @@ import { registerWikiCommands } from './commands/knowledge-commands.js';
|
|
|
7
7
|
import { registerMcpCommands } from './commands/mcp-commands.js';
|
|
8
8
|
import { registerSetupCommands } from './commands/setup-commands.js';
|
|
9
9
|
import { registerSlCommands } from './commands/sl-commands.js';
|
|
10
|
+
import { registerSqlCommands } from './commands/sql-commands.js';
|
|
10
11
|
import { registerStatusCommands } from './commands/status-commands.js';
|
|
11
12
|
import { registerDevCommands } from './dev.js';
|
|
12
13
|
import { renderMissingProjectMessage } from './doctor.js';
|
|
13
14
|
import { findNearestKtxProjectDir, resolveKtxProjectDir } from './project-resolver.js';
|
|
14
15
|
import { profileMark, profileSpan } from './startup-profile.js';
|
|
15
16
|
profileMark('module:cli-program');
|
|
16
|
-
const PROJECT_AWARE_ROOT_COMMANDS = new Set(['setup', 'connection', 'ingest', 'wiki', 'sl', 'status', 'mcp']);
|
|
17
|
+
const PROJECT_AWARE_ROOT_COMMANDS = new Set(['setup', 'connection', 'ingest', 'wiki', 'sl', 'sql', 'status', 'mcp']);
|
|
18
|
+
const PROJECT_INDEPENDENT_DEV_COMMANDS = new Set(['runtime', 'schema']);
|
|
17
19
|
const COMMANDS_THAT_CREATE_PROJECT = new Set(['setup', 'ktx dev init']);
|
|
18
20
|
const COMMANDS_WITH_OWN_MISSING_PROJECT_HANDLING = new Set(['status']);
|
|
19
21
|
const GLOBAL_OPTIONS_WITH_VALUE = new Set(['--project-dir']);
|
|
@@ -104,7 +106,7 @@ function isProjectAwareCommand(path) {
|
|
|
104
106
|
}
|
|
105
107
|
const rootCommand = path[1];
|
|
106
108
|
if (rootCommand === 'dev') {
|
|
107
|
-
return path[2] !== undefined && path[2]
|
|
109
|
+
return path[2] !== undefined && !PROJECT_INDEPENDENT_DEV_COMMANDS.has(path[2]);
|
|
108
110
|
}
|
|
109
111
|
return rootCommand !== undefined && PROJECT_AWARE_ROOT_COMMANDS.has(rootCommand);
|
|
110
112
|
}
|
|
@@ -310,6 +312,7 @@ export function buildKtxProgram(options) {
|
|
|
310
312
|
});
|
|
311
313
|
registerWikiCommands(program, context);
|
|
312
314
|
registerSlCommands(program, context);
|
|
315
|
+
registerSqlCommands(program, context);
|
|
313
316
|
registerStatusCommands(program, context);
|
|
314
317
|
registerMcpCommands(program, context);
|
|
315
318
|
registerDevCommands(program, context);
|
package/dist/cli-program.test.js
CHANGED
|
@@ -7,7 +7,13 @@ function stubIo() {
|
|
|
7
7
|
};
|
|
8
8
|
}
|
|
9
9
|
function stubPackageInfo() {
|
|
10
|
-
return {
|
|
10
|
+
return {
|
|
11
|
+
name: '@ktx/cli',
|
|
12
|
+
version: '0.0.0-test',
|
|
13
|
+
packageVersion: '0.0.0-private',
|
|
14
|
+
runtimeVersion: '0.0.0-test',
|
|
15
|
+
contextPackageName: '@ktx/context',
|
|
16
|
+
};
|
|
11
17
|
}
|
|
12
18
|
describe('buildKtxProgram', () => {
|
|
13
19
|
it('returns a Command named "ktx" with all registered top-level subcommands', () => {
|
package/dist/cli-runtime.d.ts
CHANGED
|
@@ -5,10 +5,13 @@ import type { KtxPublicIngestArgs } from './public-ingest.js';
|
|
|
5
5
|
import type { KtxRuntimeArgs } from './runtime.js';
|
|
6
6
|
import type { KtxSetupArgs } from './setup.js';
|
|
7
7
|
import type { KtxSlArgs } from './sl.js';
|
|
8
|
+
import type { KtxSqlArgs } from './sql.js';
|
|
8
9
|
import type { KtxTextIngestArgs } from './text-ingest.js';
|
|
9
10
|
export interface KtxCliPackageInfo {
|
|
10
11
|
name: string;
|
|
11
12
|
version: string;
|
|
13
|
+
packageVersion: string;
|
|
14
|
+
runtimeVersion: string;
|
|
12
15
|
contextPackageName: '@ktx/context';
|
|
13
16
|
}
|
|
14
17
|
export interface KtxCliIo {
|
|
@@ -30,6 +33,7 @@ export interface KtxCliDeps {
|
|
|
30
33
|
runtime?: (args: KtxRuntimeArgs, io: KtxCliIo) => Promise<number>;
|
|
31
34
|
knowledge?: (args: KtxKnowledgeArgs, io: KtxCliIo) => Promise<number>;
|
|
32
35
|
sl?: (args: KtxSlArgs, io: KtxCliIo) => Promise<number>;
|
|
36
|
+
sql?: (args: KtxSqlArgs, io: KtxCliIo) => Promise<number>;
|
|
33
37
|
mcp?: {
|
|
34
38
|
startDaemon?: typeof import('./managed-mcp-daemon.js').startKtxMcpDaemon;
|
|
35
39
|
stopDaemon?: typeof import('./managed-mcp-daemon.js').stopKtxMcpDaemon;
|
package/dist/cli-runtime.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRequire } from 'node:module';
|
|
2
2
|
import { profileMark, profileSpan } from './startup-profile.js';
|
|
3
|
+
import { resolveKtxRuntimeVersion } from './release-version.js';
|
|
3
4
|
profileMark('module:cli-runtime');
|
|
4
5
|
const requirePackageJson = createRequire(import.meta.url);
|
|
5
6
|
export function getKtxCliPackageInfo() {
|
|
@@ -14,9 +15,15 @@ export function packageInfoFromJson(packageJson) {
|
|
|
14
15
|
typeof packageJson.version !== 'string') {
|
|
15
16
|
throw new Error('Invalid KTX CLI package metadata');
|
|
16
17
|
}
|
|
18
|
+
const runtimeVersion = resolveKtxRuntimeVersion({
|
|
19
|
+
packageName: packageJson.name,
|
|
20
|
+
packageVersion: packageJson.version,
|
|
21
|
+
});
|
|
17
22
|
return {
|
|
18
23
|
name: packageJson.name,
|
|
19
|
-
version:
|
|
24
|
+
version: runtimeVersion,
|
|
25
|
+
packageVersion: packageJson.version,
|
|
26
|
+
runtimeVersion,
|
|
20
27
|
contextPackageName: '@ktx/context',
|
|
21
28
|
};
|
|
22
29
|
}
|
|
@@ -26,9 +26,9 @@ export declare const slQueryCommandSchema: z.ZodObject<{
|
|
|
26
26
|
execute: z.ZodBoolean;
|
|
27
27
|
cliVersion: z.ZodString;
|
|
28
28
|
runtimeInstallPolicy: z.ZodEnum<{
|
|
29
|
-
auto: "auto";
|
|
30
29
|
never: "never";
|
|
31
30
|
prompt: "prompt";
|
|
31
|
+
auto: "auto";
|
|
32
32
|
}>;
|
|
33
33
|
maxRows: z.ZodOptional<z.ZodNumber>;
|
|
34
34
|
}, z.core.$strip>;
|
|
@@ -17,6 +17,7 @@ export function registerIngestCommands(program, context, commandOptions) {
|
|
|
17
17
|
.option('--query-history-window-days <days>', 'Query-history lookback window for this run', parsePositiveIntegerOption)
|
|
18
18
|
.addOption(new Option('--plain', 'Print plain text output').conflicts(['json']))
|
|
19
19
|
.addOption(new Option('--json', 'Print JSON output').conflicts(['plain']))
|
|
20
|
+
.option('--yes', 'Install required managed runtime features without prompting')
|
|
20
21
|
.option('--no-input', 'Disable interactive terminal input')
|
|
21
22
|
.showHelpAfterError();
|
|
22
23
|
ingest.action(async (connectionId, options, command) => {
|
|
@@ -6,6 +6,10 @@ async function runKnowledgeArgs(context, args) {
|
|
|
6
6
|
const runner = context.deps.knowledge ?? (await import('../knowledge.js')).runKtxKnowledge;
|
|
7
7
|
context.setExitCode(await runner(args, context.io));
|
|
8
8
|
}
|
|
9
|
+
function isDebugEnabled(command) {
|
|
10
|
+
const options = (command.optsWithGlobals ? command.optsWithGlobals() : command.opts());
|
|
11
|
+
return options.debug === true;
|
|
12
|
+
}
|
|
9
13
|
export function registerWikiCommands(program, context) {
|
|
10
14
|
const wiki = program
|
|
11
15
|
.command('wiki')
|
|
@@ -51,6 +55,7 @@ export function registerWikiCommands(program, context) {
|
|
|
51
55
|
userId: options.userId,
|
|
52
56
|
output: options.output,
|
|
53
57
|
json: options.json,
|
|
58
|
+
...(isDebugEnabled(command) ? { debug: true } : {}),
|
|
54
59
|
...(options.limit !== undefined ? { limit: options.limit } : {}),
|
|
55
60
|
});
|
|
56
61
|
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { InvalidArgumentError, Option } from '@commander-js/extra-typings';
|
|
2
|
+
import { resolveCommandProjectDir } from '../cli-program.js';
|
|
3
|
+
import { profileMark } from '../startup-profile.js';
|
|
4
|
+
profileMark('module:commands/sql-commands');
|
|
5
|
+
const DEFAULT_MAX_ROWS = 1000;
|
|
6
|
+
const MAX_ROWS_CAP = 10_000;
|
|
7
|
+
function parseSqlMaxRowsOption(value) {
|
|
8
|
+
const parsed = Number(value);
|
|
9
|
+
if (!Number.isInteger(parsed) || parsed < 1 || parsed > MAX_ROWS_CAP) {
|
|
10
|
+
throw new InvalidArgumentError(`must be an integer between 1 and ${MAX_ROWS_CAP}`);
|
|
11
|
+
}
|
|
12
|
+
return parsed;
|
|
13
|
+
}
|
|
14
|
+
async function runSqlArgs(context, args) {
|
|
15
|
+
const runner = context.deps.sql ?? (await import('../sql.js')).runKtxSql;
|
|
16
|
+
context.setExitCode(await runner(args, context.io));
|
|
17
|
+
}
|
|
18
|
+
export function registerSqlCommands(program, context) {
|
|
19
|
+
program
|
|
20
|
+
.command('sql')
|
|
21
|
+
.description('Execute parser-validated read-only SQL against a configured connection')
|
|
22
|
+
.argument('<sql...>', 'SQL query to execute')
|
|
23
|
+
.requiredOption('-c, --connection <id>', 'KTX connection id')
|
|
24
|
+
.option('--max-rows <n>', 'Maximum rows to return', parseSqlMaxRowsOption, DEFAULT_MAX_ROWS)
|
|
25
|
+
.addOption(new Option('--output <mode>', 'Output mode: pretty (default), plain (TSV), or json').choices([
|
|
26
|
+
'pretty',
|
|
27
|
+
'plain',
|
|
28
|
+
'json',
|
|
29
|
+
]))
|
|
30
|
+
.option('--json', 'Shortcut for --output=json (overrides --output)', false)
|
|
31
|
+
.action(async (sqlParts, options, command) => {
|
|
32
|
+
await runSqlArgs(context, {
|
|
33
|
+
command: 'execute',
|
|
34
|
+
projectDir: resolveCommandProjectDir(command),
|
|
35
|
+
connectionId: options.connection,
|
|
36
|
+
sql: sqlParts.join(' '),
|
|
37
|
+
maxRows: options.maxRows,
|
|
38
|
+
output: options.output,
|
|
39
|
+
json: options.json === true,
|
|
40
|
+
cliVersion: context.packageInfo.version,
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Command } from '@commander-js/extra-typings';
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { registerSqlCommands } from './sql-commands.js';
|
|
4
|
+
function makeContext(overrides = {}) {
|
|
5
|
+
let exitCode = 0;
|
|
6
|
+
return {
|
|
7
|
+
io: {
|
|
8
|
+
stdout: { write: vi.fn() },
|
|
9
|
+
stderr: { write: vi.fn() },
|
|
10
|
+
},
|
|
11
|
+
deps: {},
|
|
12
|
+
packageInfo: { name: '@ktx/cli', version: '0.0.0-test', contextPackageName: '@ktx/context' },
|
|
13
|
+
setExitCode: (code) => {
|
|
14
|
+
exitCode = code;
|
|
15
|
+
},
|
|
16
|
+
runInit: vi.fn(),
|
|
17
|
+
writeDebug: vi.fn(),
|
|
18
|
+
...overrides,
|
|
19
|
+
get exitCode() {
|
|
20
|
+
return exitCode;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
describe('registerSqlCommands', () => {
|
|
25
|
+
it('routes positional SQL through the sql runner', async () => {
|
|
26
|
+
const program = new Command().exitOverride().option('--project-dir <path>');
|
|
27
|
+
const sql = vi.fn(async () => 0);
|
|
28
|
+
const context = makeContext({ deps: { sql } });
|
|
29
|
+
registerSqlCommands(program, context);
|
|
30
|
+
await expect(program.parseAsync(['--project-dir', '/tmp/ktx-sql', 'sql', '--connection', 'warehouse', 'select', '1'], { from: 'user' })).resolves.toBe(program);
|
|
31
|
+
expect(sql).toHaveBeenCalledWith({
|
|
32
|
+
command: 'execute',
|
|
33
|
+
projectDir: '/tmp/ktx-sql',
|
|
34
|
+
connectionId: 'warehouse',
|
|
35
|
+
sql: 'select 1',
|
|
36
|
+
maxRows: 1000,
|
|
37
|
+
output: undefined,
|
|
38
|
+
json: false,
|
|
39
|
+
cliVersion: '0.0.0-test',
|
|
40
|
+
}, context.io);
|
|
41
|
+
});
|
|
42
|
+
it('supports the short connection flag', async () => {
|
|
43
|
+
const program = new Command().exitOverride().option('--project-dir <path>');
|
|
44
|
+
const sql = vi.fn(async () => 0);
|
|
45
|
+
const context = makeContext({ deps: { sql } });
|
|
46
|
+
registerSqlCommands(program, context);
|
|
47
|
+
await expect(program.parseAsync(['--project-dir', '/tmp/ktx-sql', 'sql', '-c', 'warehouse', 'select 1'], {
|
|
48
|
+
from: 'user',
|
|
49
|
+
})).resolves.toBe(program);
|
|
50
|
+
expect(sql).toHaveBeenCalledWith(expect.objectContaining({ connectionId: 'warehouse', sql: 'select 1' }), context.io);
|
|
51
|
+
});
|
|
52
|
+
it('rejects missing SQL before invoking the runner', async () => {
|
|
53
|
+
const program = new Command().exitOverride().option('--project-dir <path>');
|
|
54
|
+
const sql = vi.fn(async () => 0);
|
|
55
|
+
registerSqlCommands(program, makeContext({ deps: { sql } }));
|
|
56
|
+
await expect(program.parseAsync(['--project-dir', '/tmp/ktx-sql', 'sql', '--connection', 'warehouse'], {
|
|
57
|
+
from: 'user',
|
|
58
|
+
})).rejects.toThrow('missing required argument');
|
|
59
|
+
expect(sql).not.toHaveBeenCalled();
|
|
60
|
+
});
|
|
61
|
+
it('rejects maxRows above the CLI cap', async () => {
|
|
62
|
+
const program = new Command().exitOverride().option('--project-dir <path>');
|
|
63
|
+
const sql = vi.fn(async () => 0);
|
|
64
|
+
registerSqlCommands(program, makeContext({ deps: { sql } }));
|
|
65
|
+
await expect(program.parseAsync(['--project-dir', '/tmp/ktx-sql', 'sql', '--connection', 'warehouse', '--max-rows', '10001', 'select 1'], { from: 'user' })).rejects.toThrow('must be an integer between 1 and 10000');
|
|
66
|
+
expect(sql).not.toHaveBeenCalled();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
@@ -533,6 +533,9 @@ function failedStepDetail(result) {
|
|
|
533
533
|
}
|
|
534
534
|
const INTERNAL_FAILURE_LINE_RE = /^(Report|Run|Job|Status|Adapter|Connection|Sync|Mode|Dry run|Diff|Tasks|Work units|Failed tasks|Saved memory|Provenance rows):\s*/;
|
|
535
535
|
const ACTIONABLE_FAILURE_LINE_RE = /^(Missing bundled Python runtime manifest|KTX Python runtime is required|KTX managed daemon|Error:|Failed\b|Could not\b|Cannot\b)/;
|
|
536
|
+
function trimErrorPrefix(line) {
|
|
537
|
+
return line.replace(/^Error:\s*/, '');
|
|
538
|
+
}
|
|
536
539
|
function firstCapturedFailureLine(output) {
|
|
537
540
|
const lines = (output ?? '')
|
|
538
541
|
.split(/\r?\n/)
|
|
@@ -540,7 +543,8 @@ function firstCapturedFailureLine(output) {
|
|
|
540
543
|
.filter((candidate) => candidate.length > 0)
|
|
541
544
|
.filter((candidate) => !candidate.startsWith('KTX scan completed'))
|
|
542
545
|
.filter((candidate) => !INTERNAL_FAILURE_LINE_RE.test(candidate));
|
|
543
|
-
|
|
546
|
+
const line = lines.find((candidate) => ACTIONABLE_FAILURE_LINE_RE.test(candidate)) ?? lines.at(-1) ?? null;
|
|
547
|
+
return line ? trimErrorPrefix(line) : null;
|
|
544
548
|
}
|
|
545
549
|
function isGenericFailedAtDetail(target, detail) {
|
|
546
550
|
return new RegExp(`^${target.connectionId} failed at [a-z-]+\\.?(?: Retry: .*)?$`).test(detail ?? '');
|
package/dist/dev.test.js
CHANGED
|
@@ -88,6 +88,33 @@ describe('dev Commander tree', () => {
|
|
|
88
88
|
await rm(tempDir, { recursive: true, force: true });
|
|
89
89
|
}
|
|
90
90
|
});
|
|
91
|
+
it('prints config schema without requiring a KTX project directory', async () => {
|
|
92
|
+
const { mkdtemp, rm } = await import('node:fs/promises');
|
|
93
|
+
const { tmpdir } = await import('node:os');
|
|
94
|
+
const { join } = await import('node:path');
|
|
95
|
+
const tempDir = await mkdtemp(join(tmpdir(), 'ktx-dev-schema-'));
|
|
96
|
+
const missingProjectDir = join(tempDir, 'missing-project');
|
|
97
|
+
const originalProjectDir = process.env.KTX_PROJECT_DIR;
|
|
98
|
+
const testIo = makeIo();
|
|
99
|
+
try {
|
|
100
|
+
process.env.KTX_PROJECT_DIR = missingProjectDir;
|
|
101
|
+
await expect(runKtxCli(['dev', 'schema'], testIo.io)).resolves.toBe(0);
|
|
102
|
+
expect(JSON.parse(testIo.stdout())).toMatchObject({
|
|
103
|
+
title: 'ktx.yaml',
|
|
104
|
+
type: 'object',
|
|
105
|
+
});
|
|
106
|
+
expect(testIo.stderr()).toBe('');
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
if (originalProjectDir === undefined) {
|
|
110
|
+
delete process.env.KTX_PROJECT_DIR;
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
process.env.KTX_PROJECT_DIR = originalProjectDir;
|
|
114
|
+
}
|
|
115
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
116
|
+
}
|
|
117
|
+
});
|
|
91
118
|
it('rejects removed dev command groups', async () => {
|
|
92
119
|
for (const argv of [
|
|
93
120
|
['dev', 'doctor', 'setup'],
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { runKtxSetupEmbeddingsStep } from './setup-embeddings.js';
|
|
|
7
7
|
export type { KtxSetupSourcesArgs, KtxSetupSourcesDeps, KtxSetupSourcesPromptAdapter, KtxSetupSourcesResult, KtxSetupSourceType, } from './setup-sources.js';
|
|
8
8
|
export { runKtxSetupSourcesStep } from './setup-sources.js';
|
|
9
9
|
export { runKtxRuntime, type KtxRuntimeArgs, type KtxRuntimeDeps } from './runtime.js';
|
|
10
|
+
export { runKtxSql, type KtxSqlArgs, type KtxSqlDeps } from './sql.js';
|
|
10
11
|
export { allocateDaemonPort, readManagedPythonDaemonStatus, stopAllManagedPythonDaemons, startManagedPythonDaemon, stopManagedPythonDaemon, } from './managed-python-daemon.js';
|
|
11
12
|
export type { ManagedPythonDaemonProcessInfo, ManagedPythonDaemonStartResult, ManagedPythonDaemonState, ManagedPythonDaemonStatus, ManagedPythonDaemonStopAllEntry, ManagedPythonDaemonStopAllFailure, ManagedPythonDaemonStopAllResult, ManagedPythonDaemonStopResult, } from './managed-python-daemon.js';
|
|
12
13
|
export { ensureManagedLocalEmbeddingsDaemon, managedLocalEmbeddingHealthConfig, managedLocalEmbeddingProjectConfig, type ManagedLocalEmbeddingsDaemon, type ManagedLocalEmbeddingsOptions, } from './managed-local-embeddings.js';
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ export { runKtxSetupDatabasesStep } from './setup-databases.js';
|
|
|
5
5
|
export { runKtxSetupEmbeddingsStep } from './setup-embeddings.js';
|
|
6
6
|
export { runKtxSetupSourcesStep } from './setup-sources.js';
|
|
7
7
|
export { runKtxRuntime } from './runtime.js';
|
|
8
|
+
export { runKtxSql } from './sql.js';
|
|
8
9
|
export { allocateDaemonPort, readManagedPythonDaemonStatus, stopAllManagedPythonDaemons, startManagedPythonDaemon, stopManagedPythonDaemon, } from './managed-python-daemon.js';
|
|
9
10
|
export { ensureManagedLocalEmbeddingsDaemon, managedLocalEmbeddingHealthConfig, managedLocalEmbeddingProjectConfig, } from './managed-local-embeddings.js';
|
|
10
11
|
export { renderMemoryFlowTui, sanitizeMemoryFlowTuiError, startLiveMemoryFlowTui, } from './memory-flow-tui.js';
|
package/dist/index.test.js
CHANGED
|
@@ -31,7 +31,9 @@ describe('getKtxCliPackageInfo', () => {
|
|
|
31
31
|
it('identifies the CLI package and its context dependency', () => {
|
|
32
32
|
expect(getKtxCliPackageInfo()).toEqual({
|
|
33
33
|
name: '@ktx/cli',
|
|
34
|
-
version: '0.
|
|
34
|
+
version: '0.1.0-rc.1',
|
|
35
|
+
packageVersion: '0.0.0-private',
|
|
36
|
+
runtimeVersion: '0.1.0-rc.1',
|
|
35
37
|
contextPackageName: '@ktx/context',
|
|
36
38
|
});
|
|
37
39
|
});
|
|
@@ -49,6 +51,8 @@ describe('getKtxCliPackageInfo', () => {
|
|
|
49
51
|
})).toEqual({
|
|
50
52
|
name: '@kaelio/ktx',
|
|
51
53
|
version: '0.1.0',
|
|
54
|
+
packageVersion: '0.1.0',
|
|
55
|
+
runtimeVersion: '0.1.0',
|
|
52
56
|
contextPackageName: '@ktx/context',
|
|
53
57
|
});
|
|
54
58
|
});
|
|
@@ -86,7 +90,7 @@ describe('runKtxCli', () => {
|
|
|
86
90
|
it('prints version information', async () => {
|
|
87
91
|
const testIo = makeIo();
|
|
88
92
|
await expect(runKtxCli(['--version'], testIo.io)).resolves.toBe(0);
|
|
89
|
-
expect(testIo.stdout()).toBe('@ktx/cli 0.
|
|
93
|
+
expect(testIo.stdout()).toBe('@ktx/cli 0.1.0-rc.1\n');
|
|
90
94
|
expect(testIo.stderr()).toBe('');
|
|
91
95
|
});
|
|
92
96
|
it('prints the public command surface in root help', async () => {
|
|
@@ -129,6 +133,16 @@ describe('runKtxCli', () => {
|
|
|
129
133
|
json: false,
|
|
130
134
|
limit: 5,
|
|
131
135
|
}, searchIo.io);
|
|
136
|
+
const debugSearchIo = makeIo();
|
|
137
|
+
await expect(runKtxCli(['--project-dir', tempDir, '--debug', 'wiki', 'search', 'revenue'], debugSearchIo.io, { knowledge })).resolves.toBe(0);
|
|
138
|
+
expect(knowledge).toHaveBeenLastCalledWith({
|
|
139
|
+
command: 'search',
|
|
140
|
+
projectDir: tempDir,
|
|
141
|
+
query: 'revenue',
|
|
142
|
+
userId: 'local',
|
|
143
|
+
json: false,
|
|
144
|
+
debug: true,
|
|
145
|
+
}, debugSearchIo.io);
|
|
132
146
|
});
|
|
133
147
|
it('rejects removed public wiki read and write commands', async () => {
|
|
134
148
|
const knowledge = vi.fn(async () => 0);
|
|
@@ -171,7 +185,7 @@ describe('runKtxCli', () => {
|
|
|
171
185
|
await expect(runKtxCli(['--project-dir', tempDir, 'sl', 'list', '--query', 'revenue'], listIo.io, { sl })).resolves.toBe(1);
|
|
172
186
|
expect(listIo.stderr()).toContain("unknown option '--query'");
|
|
173
187
|
});
|
|
174
|
-
it('routes runtime management commands with the
|
|
188
|
+
it('routes runtime management commands with the release runtime version', async () => {
|
|
175
189
|
const runtime = vi.fn(async () => 0);
|
|
176
190
|
const installIo = makeIo();
|
|
177
191
|
const startIo = makeIo();
|
|
@@ -189,32 +203,32 @@ describe('runKtxCli', () => {
|
|
|
189
203
|
await expect(runKtxCli(['dev', 'runtime', 'prune', '--dry-run'], pruneIo.io, { runtime })).resolves.toBe(1);
|
|
190
204
|
expect(runtime).toHaveBeenNthCalledWith(1, {
|
|
191
205
|
command: 'install',
|
|
192
|
-
cliVersion: '0.
|
|
206
|
+
cliVersion: '0.1.0-rc.1',
|
|
193
207
|
feature: 'local-embeddings',
|
|
194
208
|
force: true,
|
|
195
209
|
}, installIo.io);
|
|
196
210
|
expect(runtime).toHaveBeenNthCalledWith(2, {
|
|
197
211
|
command: 'start',
|
|
198
|
-
cliVersion: '0.
|
|
212
|
+
cliVersion: '0.1.0-rc.1',
|
|
199
213
|
projectDir: expect.any(String),
|
|
200
214
|
feature: 'local-embeddings',
|
|
201
215
|
force: true,
|
|
202
216
|
}, startIo.io);
|
|
203
217
|
expect(runtime).toHaveBeenNthCalledWith(3, {
|
|
204
218
|
command: 'stop',
|
|
205
|
-
cliVersion: '0.
|
|
219
|
+
cliVersion: '0.1.0-rc.1',
|
|
206
220
|
projectDir: expect.any(String),
|
|
207
221
|
all: false,
|
|
208
222
|
}, stopIo.io);
|
|
209
223
|
expect(runtime).toHaveBeenNthCalledWith(4, {
|
|
210
224
|
command: 'stop',
|
|
211
|
-
cliVersion: '0.
|
|
225
|
+
cliVersion: '0.1.0-rc.1',
|
|
212
226
|
projectDir: expect.any(String),
|
|
213
227
|
all: true,
|
|
214
228
|
}, stopAllIo.io);
|
|
215
229
|
expect(runtime).toHaveBeenNthCalledWith(5, {
|
|
216
230
|
command: 'status',
|
|
217
|
-
cliVersion: '0.
|
|
231
|
+
cliVersion: '0.1.0-rc.1',
|
|
218
232
|
json: true,
|
|
219
233
|
}, statusIo.io);
|
|
220
234
|
expect(runtime).toHaveBeenCalledTimes(5);
|
|
@@ -261,7 +275,7 @@ describe('runKtxCli', () => {
|
|
|
261
275
|
expect(sl).toHaveBeenLastCalledWith(expect.objectContaining({
|
|
262
276
|
command: 'query',
|
|
263
277
|
projectDir: tempDir,
|
|
264
|
-
cliVersion: '0.
|
|
278
|
+
cliVersion: '0.1.0-rc.1',
|
|
265
279
|
runtimeInstallPolicy: 'prompt',
|
|
266
280
|
query: expect.objectContaining({ measures: ['orders.order_count'], dimensions: [] }),
|
|
267
281
|
}), promptIo.io);
|
|
@@ -270,13 +284,13 @@ describe('runKtxCli', () => {
|
|
|
270
284
|
sl,
|
|
271
285
|
})).resolves.toBe(0);
|
|
272
286
|
expect(sl).toHaveBeenLastCalledWith(expect.objectContaining({
|
|
273
|
-
cliVersion: '0.
|
|
287
|
+
cliVersion: '0.1.0-rc.1',
|
|
274
288
|
runtimeInstallPolicy: 'auto',
|
|
275
289
|
}), autoIo.io);
|
|
276
290
|
const noInputIo = makeIo();
|
|
277
291
|
await expect(runKtxCli(['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count', '--no-input'], noInputIo.io, { sl })).resolves.toBe(0);
|
|
278
292
|
expect(sl).toHaveBeenLastCalledWith(expect.objectContaining({
|
|
279
|
-
cliVersion: '0.
|
|
293
|
+
cliVersion: '0.1.0-rc.1',
|
|
280
294
|
runtimeInstallPolicy: 'never',
|
|
281
295
|
}), noInputIo.io);
|
|
282
296
|
});
|
|
@@ -389,7 +403,7 @@ describe('runKtxCli', () => {
|
|
|
389
403
|
skipAgents: false,
|
|
390
404
|
inputMode: 'auto',
|
|
391
405
|
yes: false,
|
|
392
|
-
cliVersion: '0.
|
|
406
|
+
cliVersion: '0.1.0-rc.1',
|
|
393
407
|
skipLlm: false,
|
|
394
408
|
skipEmbeddings: false,
|
|
395
409
|
databaseSchemas: [],
|
|
@@ -498,7 +512,7 @@ describe('runKtxCli', () => {
|
|
|
498
512
|
inputMode: 'disabled',
|
|
499
513
|
depth: 'fast',
|
|
500
514
|
queryHistory: 'default',
|
|
501
|
-
cliVersion: '0.
|
|
515
|
+
cliVersion: '0.1.0-rc.1',
|
|
502
516
|
runtimeInstallPolicy: 'never',
|
|
503
517
|
}, testIo.io);
|
|
504
518
|
expect(testIo.stderr()).toBe(`Project: ${tempDir}\n`);
|
|
@@ -517,11 +531,32 @@ describe('runKtxCli', () => {
|
|
|
517
531
|
inputMode: 'auto',
|
|
518
532
|
depth: 'deep',
|
|
519
533
|
queryHistory: 'default',
|
|
520
|
-
cliVersion: '0.
|
|
534
|
+
cliVersion: '0.1.0-rc.1',
|
|
521
535
|
runtimeInstallPolicy: 'prompt',
|
|
522
536
|
}, testIo.io);
|
|
523
537
|
expect(testIo.stderr()).toBe('');
|
|
524
538
|
});
|
|
539
|
+
it('routes public ingest --yes as automatic runtime installation', async () => {
|
|
540
|
+
const testIo = makeIo();
|
|
541
|
+
const publicIngest = vi.fn().mockResolvedValue(0);
|
|
542
|
+
await expect(runKtxCli(['--project-dir', tempDir, 'ingest', 'warehouse', '--yes'], testIo.io, {
|
|
543
|
+
publicIngest,
|
|
544
|
+
})).resolves.toBe(0);
|
|
545
|
+
expect(publicIngest).toHaveBeenCalledWith(expect.objectContaining({
|
|
546
|
+
projectDir: tempDir,
|
|
547
|
+
targetConnectionId: 'warehouse',
|
|
548
|
+
runtimeInstallPolicy: 'auto',
|
|
549
|
+
}), testIo.io);
|
|
550
|
+
});
|
|
551
|
+
it('rejects conflicting public ingest runtime install modes', async () => {
|
|
552
|
+
const testIo = makeIo();
|
|
553
|
+
const publicIngest = vi.fn().mockResolvedValue(0);
|
|
554
|
+
await expect(runKtxCli(['--project-dir', tempDir, 'ingest', 'warehouse', '--yes', '--no-input'], testIo.io, {
|
|
555
|
+
publicIngest,
|
|
556
|
+
})).resolves.toBe(1);
|
|
557
|
+
expect(publicIngest).not.toHaveBeenCalled();
|
|
558
|
+
expect(testIo.stderr()).toContain('Choose only one runtime install mode: --yes or --no-input');
|
|
559
|
+
});
|
|
525
560
|
it('rejects mutually exclusive public ingest depth flags before dispatch', async () => {
|
|
526
561
|
const testIo = makeIo();
|
|
527
562
|
const publicIngest = vi.fn().mockResolvedValue(0);
|
|
@@ -545,7 +580,7 @@ describe('runKtxCli', () => {
|
|
|
545
580
|
json: false,
|
|
546
581
|
inputMode: 'disabled',
|
|
547
582
|
queryHistory: 'default',
|
|
548
|
-
cliVersion: '0.
|
|
583
|
+
cliVersion: '0.1.0-rc.1',
|
|
549
584
|
runtimeInstallPolicy: 'never',
|
|
550
585
|
}, testIo.io);
|
|
551
586
|
});
|
|
@@ -750,7 +785,7 @@ describe('runKtxCli', () => {
|
|
|
750
785
|
command: 'run',
|
|
751
786
|
projectDir: tempDir,
|
|
752
787
|
inputMode: 'disabled',
|
|
753
|
-
cliVersion: '0.
|
|
788
|
+
cliVersion: '0.1.0-rc.1',
|
|
754
789
|
anthropicApiKeyEnv: 'ANTHROPIC_API_KEY', // pragma: allowlist secret
|
|
755
790
|
anthropicModel: 'claude-sonnet-4-6',
|
|
756
791
|
skipLlm: false,
|
|
@@ -777,7 +812,7 @@ describe('runKtxCli', () => {
|
|
|
777
812
|
command: 'run',
|
|
778
813
|
projectDir: tempDir,
|
|
779
814
|
inputMode: 'disabled',
|
|
780
|
-
cliVersion: '0.
|
|
815
|
+
cliVersion: '0.1.0-rc.1',
|
|
781
816
|
llmBackend: 'vertex',
|
|
782
817
|
vertexProject: 'local-gcp-project',
|
|
783
818
|
vertexLocation: 'us-east5',
|
|
@@ -802,7 +837,7 @@ describe('runKtxCli', () => {
|
|
|
802
837
|
command: 'run',
|
|
803
838
|
projectDir: tempDir,
|
|
804
839
|
inputMode: 'disabled',
|
|
805
|
-
cliVersion: '0.
|
|
840
|
+
cliVersion: '0.1.0-rc.1',
|
|
806
841
|
llmBackend: 'claude-code',
|
|
807
842
|
llmModel: 'opus',
|
|
808
843
|
skipLlm: false,
|
|
@@ -877,7 +912,7 @@ describe('runKtxCli', () => {
|
|
|
877
912
|
projectDir: '/tmp/project',
|
|
878
913
|
inputMode: 'disabled',
|
|
879
914
|
yes: true,
|
|
880
|
-
cliVersion: '0.
|
|
915
|
+
cliVersion: '0.1.0-rc.1',
|
|
881
916
|
skipLlm: true,
|
|
882
917
|
skipEmbeddings: true,
|
|
883
918
|
databaseDrivers: ['postgres'],
|
|
@@ -1080,7 +1115,7 @@ describe('runKtxCli', () => {
|
|
|
1080
1115
|
queryFile: '/tmp/query.json',
|
|
1081
1116
|
execute: false,
|
|
1082
1117
|
format: 'json',
|
|
1083
|
-
cliVersion: '0.
|
|
1118
|
+
cliVersion: '0.1.0-rc.1',
|
|
1084
1119
|
runtimeInstallPolicy: 'auto',
|
|
1085
1120
|
}, autoIo.io);
|
|
1086
1121
|
expect(sl).toHaveBeenNthCalledWith(2, {
|
|
@@ -1090,7 +1125,7 @@ describe('runKtxCli', () => {
|
|
|
1090
1125
|
queryFile: '/tmp/query.json',
|
|
1091
1126
|
execute: false,
|
|
1092
1127
|
format: 'json',
|
|
1093
|
-
cliVersion: '0.
|
|
1128
|
+
cliVersion: '0.1.0-rc.1',
|
|
1094
1129
|
runtimeInstallPolicy: 'never',
|
|
1095
1130
|
}, neverIo.io);
|
|
1096
1131
|
expect(conflictIo.stderr()).toContain('Choose only one runtime install mode: --yes or --no-input');
|