@kaelio/ktx 0.1.0-rc.5 → 0.1.0
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 +0 -0
- package/assets/python/manifest.json +2 -2
- 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/mcp-commands.js +11 -3
- package/dist/commands/mcp-commands.test.js +30 -1
- package/dist/commands/sql-commands.d.ts +3 -0
- package/dist/commands/sql-commands.js +43 -0
- package/dist/commands/sql-commands.test.d.ts +1 -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 +206 -0
- 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/next-steps.js +1 -1
- package/dist/next-steps.test.js +2 -0
- 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 +23 -0
- package/dist/runtime-requirements.js +99 -0
- package/dist/runtime-requirements.test.d.ts +1 -0
- package/dist/runtime-requirements.test.js +63 -0
- package/dist/setup-agents.d.ts +11 -3
- package/dist/setup-agents.js +397 -134
- package/dist/setup-agents.test.js +359 -61
- 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 +45 -0
- package/dist/setup-runtime.js +47 -0
- package/dist/setup-runtime.test.d.ts +1 -0
- package/dist/setup-runtime.test.js +110 -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 +19 -1
- package/dist/setup.js +104 -29
- package/dist/setup.test.js +221 -57
- 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/connector-clickhouse/dist/package-exports.test.js +1 -1
- package/node_modules/@ktx/context/dist/connections/connection-type.d.ts +4 -4
- package/node_modules/@ktx/context/dist/core/git.service.d.ts +3 -0
- package/node_modules/@ktx/context/dist/core/git.service.js +47 -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/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/index.d.ts +8 -1
- package/node_modules/@ktx/context/dist/ingest/index.js +7 -0
- package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.d.ts +18 -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 +1761 -0
- package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.js +1695 -901
- package/node_modules/@ktx/context/dist/ingest/ingest-bundle.runner.test.js +135 -118
- 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 +7 -0
- package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.js +54 -10
- package/node_modules/@ktx/context/dist/ingest/local-bundle-runtime.test.js +65 -0
- package/node_modules/@ktx/context/dist/ingest/memory-flow/schema.d.ts +23 -5
- 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 +3 -0
- package/node_modules/@ktx/context/dist/ingest/report-snapshot.d.ts +32 -7
- package/node_modules/@ktx/context/dist/ingest/report-snapshot.js +25 -0
- package/node_modules/@ktx/context/dist/ingest/report-snapshot.test.js +124 -0
- package/node_modules/@ktx/context/dist/ingest/reports.d.ts +23 -0
- 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 +24 -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/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 +4 -4
|
@@ -145,9 +145,25 @@ describe('setup embeddings step', () => {
|
|
|
145
145
|
expect(config.scan.enrichment.embeddings).toMatchObject(config.ingest.embeddings);
|
|
146
146
|
expect(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')).not.toContain('completed_steps:');
|
|
147
147
|
expect((await readKtxSetupState(tempDir)).completed_steps).toContain('embeddings');
|
|
148
|
-
expect(spinnerEvents).toContainEqual('start:Testing local
|
|
148
|
+
expect(spinnerEvents).toContainEqual('start:Testing local embeddings (all-MiniLM-L6-v2)');
|
|
149
149
|
expect(io.stdout()).toContain('Embeddings ready: yes');
|
|
150
150
|
});
|
|
151
|
+
it('uses a short non-animated local embeddings health-check status by default', async () => {
|
|
152
|
+
const io = makeIo();
|
|
153
|
+
const healthCheck = vi.fn(async () => ({ ok: true }));
|
|
154
|
+
const prompts = makePromptAdapter({ selectValues: ['sentence-transformers'] });
|
|
155
|
+
const result = await runKtxSetupEmbeddingsStep({
|
|
156
|
+
projectDir: tempDir,
|
|
157
|
+
inputMode: 'auto',
|
|
158
|
+
cliVersion: '0.2.0',
|
|
159
|
+
runtimeInstallPolicy: 'auto',
|
|
160
|
+
skipEmbeddings: false,
|
|
161
|
+
}, io.io, { prompts, env: {}, healthCheck, ensureLocalEmbeddings: vi.fn(async () => managedDaemon()) });
|
|
162
|
+
expect(result.status).toBe('ready');
|
|
163
|
+
expect(io.stderr()).toContain('Testing local embeddings (all-MiniLM-L6-v2)');
|
|
164
|
+
expect(io.stderr()).not.toContain('First run may take up to 60 seconds');
|
|
165
|
+
expect(io.stderr().match(/Testing local embeddings/g)).toHaveLength(1);
|
|
166
|
+
});
|
|
151
167
|
it('shows live progress while local sentence-transformers embeddings are being tested', async () => {
|
|
152
168
|
const io = makeIo();
|
|
153
169
|
const prompts = makePromptAdapter({ selectValues: ['sentence-transformers'] });
|
|
@@ -170,7 +186,7 @@ describe('setup embeddings step', () => {
|
|
|
170
186
|
skipEmbeddings: false,
|
|
171
187
|
}, io.io, { prompts, env: {}, healthCheck, ensureLocalEmbeddings: vi.fn(async () => managedDaemon()), spinner });
|
|
172
188
|
await vi.waitFor(() => {
|
|
173
|
-
expect(spinnerEvents).toContainEqual('start:Testing local
|
|
189
|
+
expect(spinnerEvents).toContainEqual('start:Testing local embeddings (all-MiniLM-L6-v2)');
|
|
174
190
|
});
|
|
175
191
|
expect(resolveHealthCheck).toBeDefined();
|
|
176
192
|
resolveHealthCheck?.({ ok: true });
|
package/dist/setup-models.js
CHANGED
|
@@ -335,9 +335,9 @@ async function chooseBackend(args, io, deps) {
|
|
|
335
335
|
const choice = await prompts.select({
|
|
336
336
|
message: 'Which LLM provider should KTX use?',
|
|
337
337
|
options: [
|
|
338
|
-
{ value: '
|
|
338
|
+
{ value: 'claude-code', label: 'Claude subscription (Pro/Max)' },
|
|
339
|
+
{ value: 'anthropic', label: 'Anthropic API key' },
|
|
339
340
|
{ value: 'vertex', label: 'Google Vertex AI for Anthropic Claude' },
|
|
340
|
-
{ value: 'claude-code', label: 'Local Claude Code session' },
|
|
341
341
|
{ value: 'back', label: 'Back' },
|
|
342
342
|
],
|
|
343
343
|
});
|
|
@@ -120,16 +120,18 @@ describe('setup Anthropic model step', () => {
|
|
|
120
120
|
],
|
|
121
121
|
}));
|
|
122
122
|
});
|
|
123
|
-
it('offers
|
|
123
|
+
it('offers Anthropic provider paths in the preferred order', async () => {
|
|
124
124
|
const prompts = makePromptAdapter({ providerChoice: 'back' });
|
|
125
125
|
const result = await runKtxSetupAnthropicModelStep({ projectDir: tempDir, inputMode: 'auto', skipLlm: false }, makeIo().io, { prompts, env: {} });
|
|
126
126
|
expect(result.status).toBe('back');
|
|
127
127
|
expect(prompts.select).toHaveBeenCalledWith(expect.objectContaining({
|
|
128
128
|
message: expect.stringContaining('Which LLM provider should KTX use?'),
|
|
129
|
-
options:
|
|
129
|
+
options: [
|
|
130
|
+
{ value: 'claude-code', label: 'Claude subscription (Pro/Max)' },
|
|
131
|
+
{ value: 'anthropic', label: 'Anthropic API key' },
|
|
130
132
|
{ value: 'vertex', label: 'Google Vertex AI for Anthropic Claude' },
|
|
131
133
|
{ value: 'back', label: 'Back' },
|
|
132
|
-
]
|
|
134
|
+
],
|
|
133
135
|
}));
|
|
134
136
|
});
|
|
135
137
|
it('configures Claude Code backend and validates local auth', async () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type KtxSetupPromptOption } from './setup-prompts.js';
|
|
2
2
|
import type { KtxSetupStatus } from './setup.js';
|
|
3
|
-
export type KtxSetupReadyAction = 'models' | 'embeddings' | 'databases' | 'sources' | 'context' | 'agents' | 'exit';
|
|
3
|
+
export type KtxSetupReadyAction = 'models' | 'embeddings' | 'databases' | 'sources' | 'runtime' | 'context' | 'agents' | 'exit';
|
|
4
4
|
export interface KtxSetupReadyMenuPromptAdapter {
|
|
5
5
|
select(options: {
|
|
6
6
|
message: string;
|
package/dist/setup-ready-menu.js
CHANGED
|
@@ -5,6 +5,7 @@ export function isKtxPreAgentSetupReady(status) {
|
|
|
5
5
|
status.embeddings.ready &&
|
|
6
6
|
status.databases.every((database) => database.ready) &&
|
|
7
7
|
status.sources.every((source) => source.ready) &&
|
|
8
|
+
status.runtime.ready &&
|
|
8
9
|
status.context.ready);
|
|
9
10
|
}
|
|
10
11
|
export function isKtxSetupReady(status) {
|
|
@@ -22,6 +23,7 @@ export async function runKtxSetupReadyChangeMenu(status, deps = {}) {
|
|
|
22
23
|
{ value: 'embeddings', label: 'Embeddings' },
|
|
23
24
|
{ value: 'databases', label: 'Databases' },
|
|
24
25
|
{ value: 'sources', label: 'Context sources' },
|
|
26
|
+
...(status.runtime.required ? [{ value: 'runtime', label: 'Runtime' }] : []),
|
|
25
27
|
{ value: 'context', label: 'Rebuild KTX context' },
|
|
26
28
|
{ value: 'agents', label: 'Agent integration' },
|
|
27
29
|
{ value: 'exit', label: 'Exit' },
|
|
@@ -6,6 +6,7 @@ const readyStatus = {
|
|
|
6
6
|
embeddings: { backend: 'openai', ready: true, model: 'text-embedding-3-small', dimensions: 1536 },
|
|
7
7
|
databases: [{ connectionId: 'warehouse', ready: true }],
|
|
8
8
|
sources: [],
|
|
9
|
+
runtime: { required: false, ready: true, features: [] },
|
|
9
10
|
context: { ready: true, status: 'completed' },
|
|
10
11
|
agents: [{ target: 'codex', scope: 'project', ready: true }],
|
|
11
12
|
};
|
|
@@ -13,6 +14,7 @@ describe('setup ready menu', () => {
|
|
|
13
14
|
it('recognizes a ready setup only when required sections are ready', () => {
|
|
14
15
|
expect(isKtxSetupReady(readyStatus)).toBe(true);
|
|
15
16
|
expect(isKtxSetupReady({ ...readyStatus, embeddings: { ready: false } })).toBe(false);
|
|
17
|
+
expect(isKtxSetupReady({ ...readyStatus, runtime: { required: true, ready: false, features: ['core'] } })).toBe(false);
|
|
16
18
|
expect(isKtxSetupReady({ ...readyStatus, context: { ready: false, status: 'not_started' } })).toBe(false);
|
|
17
19
|
expect(isKtxSetupReady({ ...readyStatus, agents: [] })).toBe(false);
|
|
18
20
|
});
|
|
@@ -20,6 +22,7 @@ describe('setup ready menu', () => {
|
|
|
20
22
|
expect(isKtxPreAgentSetupReady(readyStatus)).toBe(true);
|
|
21
23
|
expect(isKtxPreAgentSetupReady({ ...readyStatus, agents: [] })).toBe(true);
|
|
22
24
|
expect(isKtxPreAgentSetupReady({ ...readyStatus, embeddings: { ready: false } })).toBe(false);
|
|
25
|
+
expect(isKtxPreAgentSetupReady({ ...readyStatus, runtime: { required: true, ready: false, features: ['core'] } })).toBe(false);
|
|
23
26
|
expect(isKtxPreAgentSetupReady({ ...readyStatus, context: { ready: false, status: 'not_started' } })).toBe(false);
|
|
24
27
|
});
|
|
25
28
|
it('maps ready-project menu choices to setup sections', async () => {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type KtxLocalProject } from '@ktx/context/project';
|
|
2
|
+
import type { KtxCliIo } from './cli-runtime.js';
|
|
3
|
+
import { type ManagedLocalEmbeddingsDaemon } from './managed-local-embeddings.js';
|
|
4
|
+
import { type KtxManagedPythonInstallPolicy, type ManagedPythonCommandRuntime } from './managed-python-command.js';
|
|
5
|
+
import type { KtxRuntimeFeature } from './managed-python-runtime.js';
|
|
6
|
+
import { type KtxRuntimeRequirements } from './runtime-requirements.js';
|
|
7
|
+
export interface KtxSetupRuntimeArgs {
|
|
8
|
+
projectDir: string;
|
|
9
|
+
inputMode: 'auto' | 'disabled';
|
|
10
|
+
cliVersion: string;
|
|
11
|
+
runtimeInstallPolicy: KtxManagedPythonInstallPolicy;
|
|
12
|
+
databaseIntrospectionFallback?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export type KtxSetupRuntimeResult = {
|
|
15
|
+
status: 'ready';
|
|
16
|
+
projectDir: string;
|
|
17
|
+
requirements: KtxRuntimeRequirements;
|
|
18
|
+
} | {
|
|
19
|
+
status: 'skipped';
|
|
20
|
+
projectDir: string;
|
|
21
|
+
requirements: KtxRuntimeRequirements;
|
|
22
|
+
} | {
|
|
23
|
+
status: 'failed';
|
|
24
|
+
projectDir: string;
|
|
25
|
+
requirements: KtxRuntimeRequirements;
|
|
26
|
+
};
|
|
27
|
+
export interface KtxSetupRuntimeDeps {
|
|
28
|
+
env?: NodeJS.ProcessEnv;
|
|
29
|
+
loadProject?: (options: {
|
|
30
|
+
projectDir: string;
|
|
31
|
+
}) => Promise<Pick<KtxLocalProject, 'config'>>;
|
|
32
|
+
ensureRuntime?: (options: {
|
|
33
|
+
cliVersion: string;
|
|
34
|
+
installPolicy: KtxManagedPythonInstallPolicy;
|
|
35
|
+
io: KtxCliIo;
|
|
36
|
+
feature: KtxRuntimeFeature;
|
|
37
|
+
}) => Promise<ManagedPythonCommandRuntime>;
|
|
38
|
+
ensureLocalEmbeddings?: (options: {
|
|
39
|
+
cliVersion: string;
|
|
40
|
+
projectDir: string;
|
|
41
|
+
installPolicy: KtxManagedPythonInstallPolicy;
|
|
42
|
+
io: KtxCliIo;
|
|
43
|
+
}) => Promise<ManagedLocalEmbeddingsDaemon>;
|
|
44
|
+
}
|
|
45
|
+
export declare function runKtxSetupRuntimeStep(args: KtxSetupRuntimeArgs, io: KtxCliIo, deps?: KtxSetupRuntimeDeps): Promise<KtxSetupRuntimeResult>;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { loadKtxProject, markKtxSetupStateStepComplete, } from '@ktx/context/project';
|
|
2
|
+
import { ensureManagedLocalEmbeddingsDaemon, } from './managed-local-embeddings.js';
|
|
3
|
+
import { ensureManagedPythonCommandRuntime, } from './managed-python-command.js';
|
|
4
|
+
import { resolveProjectRuntimeRequirements, } from './runtime-requirements.js';
|
|
5
|
+
function formatRuntimeFeature(feature) {
|
|
6
|
+
return feature === 'local-embeddings' ? 'local embeddings' : 'core';
|
|
7
|
+
}
|
|
8
|
+
export async function runKtxSetupRuntimeStep(args, io, deps = {}) {
|
|
9
|
+
const loadProjectForRuntime = deps.loadProject ?? loadKtxProject;
|
|
10
|
+
const project = await loadProjectForRuntime({ projectDir: args.projectDir });
|
|
11
|
+
const requirements = resolveProjectRuntimeRequirements(project.config, {
|
|
12
|
+
databaseIntrospectionFallback: args.databaseIntrospectionFallback,
|
|
13
|
+
env: deps.env ?? process.env,
|
|
14
|
+
});
|
|
15
|
+
if (requirements.features.length === 0) {
|
|
16
|
+
io.stdout.write('│ Runtime setup skipped.\n');
|
|
17
|
+
return { status: 'skipped', projectDir: args.projectDir, requirements };
|
|
18
|
+
}
|
|
19
|
+
const ensureRuntime = deps.ensureRuntime ?? ensureManagedPythonCommandRuntime;
|
|
20
|
+
const ensureLocalEmbeddings = deps.ensureLocalEmbeddings ?? ensureManagedLocalEmbeddingsDaemon;
|
|
21
|
+
try {
|
|
22
|
+
for (const feature of requirements.features) {
|
|
23
|
+
if (feature === 'local-embeddings') {
|
|
24
|
+
await ensureLocalEmbeddings({
|
|
25
|
+
cliVersion: args.cliVersion,
|
|
26
|
+
projectDir: args.projectDir,
|
|
27
|
+
installPolicy: args.runtimeInstallPolicy,
|
|
28
|
+
io,
|
|
29
|
+
});
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
await ensureRuntime({
|
|
33
|
+
cliVersion: args.cliVersion,
|
|
34
|
+
installPolicy: args.runtimeInstallPolicy,
|
|
35
|
+
io,
|
|
36
|
+
feature,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
io.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
|
|
42
|
+
return { status: 'failed', projectDir: args.projectDir, requirements };
|
|
43
|
+
}
|
|
44
|
+
await markKtxSetupStateStepComplete(args.projectDir, 'runtime');
|
|
45
|
+
io.stdout.write(`│ Runtime ready: yes (${requirements.features.map(formatRuntimeFeature).join(', ')})\n`);
|
|
46
|
+
return { status: 'ready', projectDir: args.projectDir, requirements };
|
|
47
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { MANAGED_SENTENCE_TRANSFORMERS_BASE_URL } from '@ktx/context';
|
|
5
|
+
import { buildDefaultKtxProjectConfig, readKtxSetupState } from '@ktx/context/project';
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { runKtxSetupRuntimeStep } from './setup-runtime.js';
|
|
8
|
+
function makeIo() {
|
|
9
|
+
let stdout = '';
|
|
10
|
+
let stderr = '';
|
|
11
|
+
return {
|
|
12
|
+
io: {
|
|
13
|
+
stdout: {
|
|
14
|
+
write: (chunk) => {
|
|
15
|
+
stdout += chunk;
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
stderr: {
|
|
19
|
+
write: (chunk) => {
|
|
20
|
+
stderr += chunk;
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
stdout: () => stdout,
|
|
25
|
+
stderr: () => stderr,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function projectConfig(config) {
|
|
29
|
+
return vi.fn(async () => ({ config }));
|
|
30
|
+
}
|
|
31
|
+
describe('runKtxSetupRuntimeStep', () => {
|
|
32
|
+
let tempDir;
|
|
33
|
+
beforeEach(async () => {
|
|
34
|
+
tempDir = await mkdtemp(join(tmpdir(), 'ktx-setup-runtime-'));
|
|
35
|
+
});
|
|
36
|
+
afterEach(async () => {
|
|
37
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
38
|
+
});
|
|
39
|
+
it('skips runtime setup when the project has no direct runtime requirements', async () => {
|
|
40
|
+
const io = makeIo();
|
|
41
|
+
const ensureRuntime = vi.fn();
|
|
42
|
+
await expect(runKtxSetupRuntimeStep({
|
|
43
|
+
projectDir: tempDir,
|
|
44
|
+
inputMode: 'auto',
|
|
45
|
+
cliVersion: '0.2.0',
|
|
46
|
+
runtimeInstallPolicy: 'prompt',
|
|
47
|
+
}, io.io, {
|
|
48
|
+
loadProject: projectConfig(buildDefaultKtxProjectConfig()),
|
|
49
|
+
ensureRuntime,
|
|
50
|
+
env: {},
|
|
51
|
+
})).resolves.toMatchObject({ status: 'skipped' });
|
|
52
|
+
expect(ensureRuntime).not.toHaveBeenCalled();
|
|
53
|
+
expect((await readKtxSetupState(tempDir)).completed_steps).not.toContain('runtime');
|
|
54
|
+
expect(io.stdout()).toContain('Runtime setup skipped.');
|
|
55
|
+
});
|
|
56
|
+
it('fails fast when required runtime features cannot be installed in no-input mode', async () => {
|
|
57
|
+
const io = makeIo();
|
|
58
|
+
const ensureRuntime = vi.fn(async () => {
|
|
59
|
+
throw new Error('KTX Python runtime is required for this command. Run: ktx dev runtime install --yes');
|
|
60
|
+
});
|
|
61
|
+
await expect(runKtxSetupRuntimeStep({
|
|
62
|
+
projectDir: tempDir,
|
|
63
|
+
inputMode: 'disabled',
|
|
64
|
+
cliVersion: '0.2.0',
|
|
65
|
+
runtimeInstallPolicy: 'never',
|
|
66
|
+
databaseIntrospectionFallback: true,
|
|
67
|
+
}, io.io, {
|
|
68
|
+
loadProject: projectConfig(buildDefaultKtxProjectConfig()),
|
|
69
|
+
ensureRuntime,
|
|
70
|
+
env: {},
|
|
71
|
+
})).resolves.toMatchObject({ status: 'failed' });
|
|
72
|
+
expect(ensureRuntime).toHaveBeenCalledWith(expect.objectContaining({ installPolicy: 'never' }));
|
|
73
|
+
expect((await readKtxSetupState(tempDir)).completed_steps).not.toContain('runtime');
|
|
74
|
+
expect(io.stderr()).toContain('ktx dev runtime install --yes');
|
|
75
|
+
});
|
|
76
|
+
it('starts the managed local embeddings daemon for configured sentence-transformers embeddings', async () => {
|
|
77
|
+
const io = makeIo();
|
|
78
|
+
const ensureLocalEmbeddings = vi.fn(async () => ({
|
|
79
|
+
baseUrl: 'http://127.0.0.1:61234',
|
|
80
|
+
env: { KTX_MANAGED_SENTENCE_TRANSFORMERS_BASE_URL: 'http://127.0.0.1:61234' },
|
|
81
|
+
}));
|
|
82
|
+
const config = {
|
|
83
|
+
...buildDefaultKtxProjectConfig(),
|
|
84
|
+
ingest: {
|
|
85
|
+
...buildDefaultKtxProjectConfig().ingest,
|
|
86
|
+
embeddings: {
|
|
87
|
+
backend: 'sentence-transformers',
|
|
88
|
+
model: 'all-MiniLM-L6-v2',
|
|
89
|
+
dimensions: 384,
|
|
90
|
+
sentenceTransformers: { base_url: MANAGED_SENTENCE_TRANSFORMERS_BASE_URL },
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
await expect(runKtxSetupRuntimeStep({
|
|
95
|
+
projectDir: tempDir,
|
|
96
|
+
inputMode: 'auto',
|
|
97
|
+
cliVersion: '0.2.0',
|
|
98
|
+
runtimeInstallPolicy: 'auto',
|
|
99
|
+
}, io.io, {
|
|
100
|
+
loadProject: projectConfig(config),
|
|
101
|
+
ensureLocalEmbeddings,
|
|
102
|
+
env: {},
|
|
103
|
+
})).resolves.toMatchObject({ status: 'ready' });
|
|
104
|
+
expect(ensureLocalEmbeddings).toHaveBeenCalledWith(expect.objectContaining({
|
|
105
|
+
projectDir: tempDir,
|
|
106
|
+
installPolicy: 'auto',
|
|
107
|
+
}));
|
|
108
|
+
expect(io.stdout()).toContain('Runtime ready: yes (local embeddings)');
|
|
109
|
+
});
|
|
110
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { initKtxProject, parseKtxProjectConfig, serializeKtxProjectConfig, } from '@ktx/context/project';
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
6
|
+
import { runKtxSetupSourcesStep, } from './setup-sources.js';
|
|
7
|
+
const notionMocks = vi.hoisted(() => ({
|
|
8
|
+
tokens: [],
|
|
9
|
+
retrieveBotUser: vi.fn(async () => ({ name: 'Docs Bot' })),
|
|
10
|
+
retrievePage: vi.fn(async () => ({ id: 'page-1' })),
|
|
11
|
+
}));
|
|
12
|
+
vi.mock('@ktx/context/ingest', async (importOriginal) => {
|
|
13
|
+
const actual = await importOriginal();
|
|
14
|
+
return {
|
|
15
|
+
...actual,
|
|
16
|
+
NotionClient: vi.fn().mockImplementation(function NotionClient(token) {
|
|
17
|
+
notionMocks.tokens.push(token);
|
|
18
|
+
return {
|
|
19
|
+
retrieveBotUser: notionMocks.retrieveBotUser,
|
|
20
|
+
retrievePage: notionMocks.retrievePage,
|
|
21
|
+
};
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
function makeIo() {
|
|
26
|
+
let stdout = '';
|
|
27
|
+
let stderr = '';
|
|
28
|
+
return {
|
|
29
|
+
io: {
|
|
30
|
+
stdout: {
|
|
31
|
+
isTTY: true,
|
|
32
|
+
write: (chunk) => {
|
|
33
|
+
stdout += chunk;
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
stderr: {
|
|
37
|
+
write: (chunk) => {
|
|
38
|
+
stderr += chunk;
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
stdout: () => stdout,
|
|
43
|
+
stderr: () => stderr,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function prompts(values) {
|
|
47
|
+
const multiselectValues = [...(values.multiselect ?? [])];
|
|
48
|
+
const selectValues = [...(values.select ?? [])];
|
|
49
|
+
return {
|
|
50
|
+
multiselect: vi.fn(async () => multiselectValues.shift() ?? []),
|
|
51
|
+
select: vi.fn(async () => selectValues.shift() ?? 'back'),
|
|
52
|
+
text: vi.fn(async () => ''),
|
|
53
|
+
password: vi.fn(async () => undefined),
|
|
54
|
+
cancel: vi.fn(),
|
|
55
|
+
log: vi.fn(),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
describe('setup sources Notion validation', () => {
|
|
59
|
+
let tempDir;
|
|
60
|
+
let projectDir;
|
|
61
|
+
beforeEach(async () => {
|
|
62
|
+
notionMocks.tokens.length = 0;
|
|
63
|
+
notionMocks.retrieveBotUser.mockClear();
|
|
64
|
+
notionMocks.retrievePage.mockClear();
|
|
65
|
+
tempDir = await mkdtemp(join(tmpdir(), 'ktx-setup-sources-notion-'));
|
|
66
|
+
projectDir = join(tempDir, 'project');
|
|
67
|
+
await initKtxProject({ projectDir });
|
|
68
|
+
});
|
|
69
|
+
afterEach(async () => {
|
|
70
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
71
|
+
});
|
|
72
|
+
async function readConfig() {
|
|
73
|
+
return parseKtxProjectConfig(await readFile(join(projectDir, 'ktx.yaml'), 'utf-8'));
|
|
74
|
+
}
|
|
75
|
+
async function writeConfigConnection(connectionId, connection) {
|
|
76
|
+
const config = await readConfig();
|
|
77
|
+
await writeFile(join(projectDir, 'ktx.yaml'), serializeKtxProjectConfig({
|
|
78
|
+
...config,
|
|
79
|
+
connections: {
|
|
80
|
+
...config.connections,
|
|
81
|
+
warehouse: { driver: 'postgres', url: 'env:DATABASE_URL' },
|
|
82
|
+
[connectionId]: connection,
|
|
83
|
+
},
|
|
84
|
+
setup: {
|
|
85
|
+
...config.setup,
|
|
86
|
+
database_connection_ids: ['warehouse'],
|
|
87
|
+
},
|
|
88
|
+
}), 'utf-8');
|
|
89
|
+
}
|
|
90
|
+
it('validates an existing Notion source that uses an inline auth token', async () => {
|
|
91
|
+
await writeConfigConnection('notion', {
|
|
92
|
+
driver: 'notion',
|
|
93
|
+
auth_token: 'ntn_inline_token',
|
|
94
|
+
crawl_mode: 'all_accessible',
|
|
95
|
+
});
|
|
96
|
+
const io = makeIo();
|
|
97
|
+
await expect(runKtxSetupSourcesStep({ projectDir, inputMode: 'auto', runInitialSourceIngest: false, skipSources: false }, io.io, {
|
|
98
|
+
prompts: prompts({
|
|
99
|
+
multiselect: [['notion']],
|
|
100
|
+
select: ['existing:notion'],
|
|
101
|
+
}),
|
|
102
|
+
})).resolves.toEqual({ status: 'ready', projectDir, connectionIds: ['notion'] });
|
|
103
|
+
expect(notionMocks.tokens).toEqual(['ntn_inline_token']);
|
|
104
|
+
expect(notionMocks.retrieveBotUser).toHaveBeenCalledOnce();
|
|
105
|
+
expect(io.stderr()).toBe('');
|
|
106
|
+
});
|
|
107
|
+
});
|
package/dist/setup-sources.js
CHANGED
|
@@ -2,7 +2,7 @@ import { mkdtemp, readdir, readFile, writeFile } from 'node:fs/promises';
|
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import { join, relative, resolve } from 'node:path';
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
-
import { localConnectionTypeForConfig,
|
|
5
|
+
import { localConnectionTypeForConfig, resolveNotionConnectionAuthToken, } from '@ktx/context/connections';
|
|
6
6
|
import { resolveKtxConfigReference } from '@ktx/context/core';
|
|
7
7
|
import { cloneOrPull, DEFAULT_METABASE_CLIENT_CONFIG, discoverMetabaseDatabases, loadDbtSchemaFiles, loadProjectInfo, MetabaseClient, NotionClient, parseLookmlStagedDir, parseMetricflowFiles, testRepoConnection, } from '@ktx/context/ingest';
|
|
8
8
|
import { loadKtxProject, markKtxSetupStateStepComplete, serializeKtxProjectConfig, } from '@ktx/context/project';
|
|
@@ -467,7 +467,10 @@ async function defaultValidateLookml(connection) {
|
|
|
467
467
|
return count > 0 ? { ok: true, detail: `lookmlFiles=${count}` } : { ok: false, message: 'No LookML files found' };
|
|
468
468
|
}
|
|
469
469
|
async function defaultValidateNotion(connection) {
|
|
470
|
-
const token = await
|
|
470
|
+
const token = await resolveNotionConnectionAuthToken({
|
|
471
|
+
auth_token: stringField(connection.auth_token) ?? null,
|
|
472
|
+
auth_token_ref: stringField(connection.auth_token_ref) ?? null,
|
|
473
|
+
});
|
|
471
474
|
const client = new NotionClient(token);
|
|
472
475
|
await client.retrieveBotUser();
|
|
473
476
|
const roots = Array.isArray(connection.root_page_ids)
|
package/dist/setup.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { KtxCliIo } from './cli-runtime.js';
|
|
2
|
+
import { readManagedPythonRuntimeStatus } from './managed-python-runtime.js';
|
|
2
3
|
import { type KtxAgentScope, type KtxAgentTarget, type KtxSetupAgentsDeps, runKtxSetupAgentsStep } from './setup-agents.js';
|
|
3
4
|
import { type KtxSetupDatabaseDriver, type KtxSetupDatabasesDeps, runKtxSetupDatabasesStep } from './setup-databases.js';
|
|
4
5
|
import { type KtxSetupEmbeddingsDeps, runKtxSetupEmbeddingsStep } from './setup-embeddings.js';
|
|
@@ -6,6 +7,7 @@ import { type KtxSetupLlmBackend, type KtxSetupModelDeps, runKtxSetupAnthropicMo
|
|
|
6
7
|
import { type KtxSetupProjectDeps } from './setup-project.js';
|
|
7
8
|
import { type KtxSetupReadyMenuDeps } from './setup-ready-menu.js';
|
|
8
9
|
import { type KtxSetupSourcesDeps, type KtxSetupSourceType, runKtxSetupSourcesStep } from './setup-sources.js';
|
|
10
|
+
import { type KtxSetupRuntimeDeps, type KtxSetupRuntimeResult, runKtxSetupRuntimeStep } from './setup-runtime.js';
|
|
9
11
|
import { type KtxSetupPromptOption, type KtxSetupUiAdapter } from './setup-prompts.js';
|
|
10
12
|
import { type KtxSetupContextDeps, type KtxSetupContextResult, runKtxSetupContextStep, type KtxSetupContextStatusSummary } from './setup-context.js';
|
|
11
13
|
export interface KtxSetupStatus {
|
|
@@ -34,6 +36,12 @@ export interface KtxSetupStatus {
|
|
|
34
36
|
type: string;
|
|
35
37
|
ready: boolean;
|
|
36
38
|
}>;
|
|
39
|
+
runtime: {
|
|
40
|
+
required: boolean;
|
|
41
|
+
ready: boolean;
|
|
42
|
+
features: string[];
|
|
43
|
+
detail?: string;
|
|
44
|
+
};
|
|
37
45
|
context: KtxSetupContextStatusSummary;
|
|
38
46
|
agents: Array<{
|
|
39
47
|
target: string;
|
|
@@ -108,6 +116,8 @@ export interface KtxSetupDeps {
|
|
|
108
116
|
databasesDeps?: KtxSetupDatabasesDeps;
|
|
109
117
|
sources?: (args: Parameters<typeof runKtxSetupSourcesStep>[0], io: KtxCliIo) => Promise<Awaited<ReturnType<typeof runKtxSetupSourcesStep>>>;
|
|
110
118
|
sourcesDeps?: KtxSetupSourcesDeps;
|
|
119
|
+
runtime?: (args: Parameters<typeof runKtxSetupRuntimeStep>[0], io: KtxCliIo) => Promise<KtxSetupRuntimeResult>;
|
|
120
|
+
runtimeDeps?: KtxSetupRuntimeDeps;
|
|
111
121
|
agents?: (args: Parameters<typeof runKtxSetupAgentsStep>[0], io: KtxCliIo) => Promise<Awaited<ReturnType<typeof runKtxSetupAgentsStep>>>;
|
|
112
122
|
agentsDeps?: KtxSetupAgentsDeps;
|
|
113
123
|
context?: (args: Parameters<typeof runKtxSetupContextStep>[0], io: KtxCliIo) => Promise<KtxSetupContextResult>;
|
|
@@ -126,6 +136,14 @@ export interface KtxSetupEntryMenuPromptAdapter {
|
|
|
126
136
|
export interface KtxSetupEntryMenuDeps {
|
|
127
137
|
prompts?: KtxSetupEntryMenuPromptAdapter;
|
|
128
138
|
}
|
|
129
|
-
export
|
|
139
|
+
export interface ReadKtxSetupStatusOptions {
|
|
140
|
+
cliVersion?: string;
|
|
141
|
+
env?: NodeJS.ProcessEnv;
|
|
142
|
+
readRuntimeStatus?: typeof readManagedPythonRuntimeStatus;
|
|
143
|
+
}
|
|
144
|
+
export declare function readKtxSetupStatus(projectDir: string, options?: ReadKtxSetupStatusOptions): Promise<KtxSetupStatus>;
|
|
130
145
|
export declare function formatKtxSetupStatus(status: KtxSetupStatus): string;
|
|
146
|
+
export declare function formatKtxSetupCompletionSummary(status: KtxSetupStatus, options?: {
|
|
147
|
+
agentNextActions?: string;
|
|
148
|
+
}): string;
|
|
131
149
|
export declare function runKtxSetup(args: KtxSetupArgs, io: KtxCliIo, deps?: KtxSetupDeps): Promise<number>;
|