@kaelio/ktx 0.10.0 → 0.12.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.10.0-py3-none-any.whl → kaelio_ktx-0.12.0-py3-none-any.whl} +0 -0
- package/assets/python/manifest.json +4 -4
- package/dist/.tsbuildinfo +1 -1
- package/dist/admin.js +1 -1
- package/dist/clack.d.ts +16 -0
- package/dist/clack.js +37 -6
- package/dist/claude-code-prompt-caching.js +1 -1
- package/dist/cli-program.js +7 -3
- package/dist/cli-runtime.d.ts +2 -0
- package/dist/cli-runtime.js +14 -8
- package/dist/commands/connection-commands.js +1 -1
- package/dist/commands/ingest-commands.js +4 -4
- package/dist/commands/mcp-commands.js +12 -12
- package/dist/commands/runtime-commands.js +4 -4
- package/dist/commands/setup-commands.js +6 -5
- package/dist/commands/sl-commands.js +1 -1
- package/dist/commands/sql-commands.js +1 -1
- package/dist/commands/status-commands.js +1 -1
- package/dist/community-cta.d.ts +11 -0
- package/dist/community-cta.js +19 -0
- package/dist/connection.js +1 -1
- package/dist/connectors/clickhouse/connector.js +1 -1
- package/dist/connectors/mysql/connector.js +1 -1
- package/dist/connectors/snowflake/connector.d.ts +1 -1
- package/dist/connectors/sqlite/connector.js +2 -25
- package/dist/connectors/sqlserver/connector.js +3 -3
- package/dist/context/connections/connection-type.d.ts +1 -1
- package/dist/context/connections/read-only-sql.d.ts +1 -0
- package/dist/context/connections/read-only-sql.js +116 -2
- package/dist/context/core/git-env.d.ts +12 -1
- package/dist/context/core/git-env.js +17 -2
- package/dist/context/core/git.service.d.ts +23 -0
- package/dist/context/core/git.service.js +86 -15
- package/dist/context/ingest/adapters/historic-sql/projection.js +2 -1
- package/dist/context/ingest/adapters/looker/client.js +7 -2
- package/dist/context/ingest/adapters/looker/factory.d.ts +8 -1
- package/dist/context/ingest/adapters/looker/factory.js +9 -0
- package/dist/context/ingest/adapters/looker/mapping.js +1 -1
- package/dist/context/ingest/adapters/looker/types.d.ts +1 -1
- package/dist/context/ingest/adapters/metabase/client.d.ts +1 -1
- package/dist/context/ingest/adapters/metabase/client.js +1 -1
- package/dist/context/ingest/adapters/metabase/local-metabase.adapter.js +1 -1
- package/dist/context/ingest/adapters/metabase/mapping.js +6 -6
- package/dist/context/ingest/artifact-gates.d.ts +2 -6
- package/dist/context/ingest/artifact-gates.js +5 -47
- package/dist/context/ingest/constrained-repair.d.ts +55 -0
- package/dist/context/ingest/constrained-repair.js +167 -0
- package/dist/context/ingest/final-gate-repair.d.ts +9 -11
- package/dist/context/ingest/final-gate-repair.js +40 -128
- package/dist/context/ingest/finalization-scope.d.ts +1 -1
- package/dist/context/ingest/finalization-scope.js +15 -15
- package/dist/context/ingest/ingest-bundle.runner.d.ts +1 -0
- package/dist/context/ingest/ingest-bundle.runner.js +101 -67
- package/dist/context/ingest/isolated-diff/patch-integrator.d.ts +6 -13
- package/dist/context/ingest/isolated-diff/patch-integrator.js +32 -109
- package/dist/context/ingest/isolated-diff/textual-conflict-resolver.d.ts +8 -9
- package/dist/context/ingest/isolated-diff/textual-conflict-resolver.js +63 -141
- package/dist/context/ingest/local-bundle-runtime.d.ts +2 -0
- package/dist/context/ingest/local-bundle-runtime.js +9 -10
- package/dist/context/ingest/local-ingest.d.ts +2 -0
- package/dist/context/ingest/local-ingest.js +2 -0
- package/dist/context/ingest/memory-flow/view-model.js +1 -1
- package/dist/context/ingest/stages/stage-3-work-units.d.ts +2 -6
- package/dist/context/ingest/stages/stage-3-work-units.js +2 -1
- package/dist/context/ingest/stages/validate-wu-sources.d.ts +7 -1
- package/dist/context/ingest/stages/validate-wu-sources.js +109 -4
- package/dist/context/ingest/tools/warehouse-verification/create-warehouse-verification-tools.d.ts +2 -0
- package/dist/context/ingest/tools/warehouse-verification/create-warehouse-verification-tools.js +1 -1
- package/dist/context/ingest/tools/warehouse-verification/discover-data.tool.js +3 -3
- package/dist/context/ingest/tools/warehouse-verification/sql-execution.tool.d.ts +3 -1
- package/dist/context/ingest/tools/warehouse-verification/sql-execution.tool.js +15 -1
- package/dist/context/llm/ai-sdk-runtime.js +2 -2
- package/dist/context/llm/claude-code-runtime.js +1 -1
- package/dist/context/llm/local-config.js +1 -1
- package/dist/context/llm/runtime-tools.js +2 -2
- package/dist/context/mcp/context-tools.js +7 -7
- package/dist/context/mcp/local-project-ports.js +23 -54
- package/dist/context/memory/local-memory.js +4 -1
- package/dist/context/memory/memory-agent.service.js +1 -1
- package/dist/context/project/config.d.ts +11 -4
- package/dist/context/project/config.js +85 -30
- package/dist/context/project/driver-schemas.js +1 -1
- package/dist/context/project/mappings-yaml-schema.js +2 -2
- package/dist/context/project/project.js +12 -4
- package/dist/context/scan/description-generation.js +4 -4
- package/dist/context/scan/local-enrichment-artifacts.js +2 -1
- package/dist/context/scan/local-scan.js +2 -2
- package/dist/context/scan/local-structural-artifacts.js +5 -5
- package/dist/context/scan/relationship-benchmark-report.js +1 -1
- package/dist/context/scan/relationship-discovery.js +3 -3
- package/dist/context/scan/relationship-llm-proposal.js +3 -3
- package/dist/context/sl/local-query.js +3 -33
- package/dist/context/sl/local-sl.d.ts +0 -8
- package/dist/context/sl/local-sl.js +44 -69
- package/dist/context/sl/semantic-layer.service.d.ts +25 -8
- package/dist/context/sl/semantic-layer.service.js +109 -56
- package/dist/context/sl/source-files.d.ts +46 -0
- package/dist/context/sl/source-files.js +131 -0
- package/dist/context/sl/tools/base-semantic-layer.tool.d.ts +2 -2
- package/dist/context/sl/tools/base-semantic-layer.tool.js +2 -7
- package/dist/context/sl/tools/sl-edit-source.tool.js +10 -8
- package/dist/context/sl/tools/sl-warehouse-validation.js +55 -27
- package/dist/context/sl/tools/sl-write-source.tool.js +12 -9
- package/dist/context/sql-analysis/dialect.d.ts +2 -0
- package/dist/context/sql-analysis/dialect.js +20 -0
- package/dist/context/tools/base-tool.d.ts +6 -19
- package/dist/context/tools/base-tool.js +0 -14
- package/dist/context-build-view.js +5 -5
- package/dist/database-tree-picker.js +18 -3
- package/dist/demo-assets.js +0 -1
- package/dist/doctor.d.ts +1 -1
- package/dist/doctor.js +31 -23
- package/dist/errors.d.ts +31 -0
- package/dist/errors.js +44 -0
- package/dist/ingest.d.ts +1 -1
- package/dist/ingest.js +8 -2
- package/dist/io/symbols.d.ts +2 -0
- package/dist/io/symbols.js +2 -0
- package/dist/io/tty.d.ts +17 -0
- package/dist/io/tty.js +21 -0
- package/dist/links.d.ts +1 -0
- package/dist/links.js +1 -0
- package/dist/llm/embedding-health.js +1 -1
- package/dist/llm/embedding-provider.js +3 -3
- package/dist/llm/model-provider.js +1 -1
- package/dist/local-adapters.d.ts +1 -0
- package/dist/local-adapters.js +2 -2
- package/dist/local-scan-connectors.js +1 -1
- package/dist/managed-local-embeddings.js +17 -8
- package/dist/managed-mcp-daemon.js +3 -3
- package/dist/managed-python-command.d.ts +7 -0
- package/dist/managed-python-command.js +34 -8
- package/dist/managed-python-daemon.js +2 -2
- package/dist/managed-python-http.js +3 -3
- package/dist/managed-python-runtime.d.ts +30 -1
- package/dist/managed-python-runtime.js +134 -18
- package/dist/managed-uv-release.d.ts +7 -0
- package/dist/managed-uv-release.js +11 -0
- package/dist/mcp-http-server.js +4 -4
- package/dist/mcp-server-factory.js +3 -3
- package/dist/mcp-stdio-server.js +1 -1
- package/dist/memory-flow-hud.js +2 -2
- package/dist/next-steps.js +2 -2
- package/dist/prompt-navigation.d.ts +17 -0
- package/dist/prompt-navigation.js +49 -3
- package/dist/prompts/memory_agent_bundle_ingest_work_unit.md +2 -2
- package/dist/prompts/memory_agent_external_ingest.md +2 -2
- package/dist/public-ingest-copy.js +1 -1
- package/dist/public-ingest.js +3 -3
- package/dist/release-version.js +1 -1
- package/dist/runtime-requirements.js +1 -1
- package/dist/runtime.js +9 -9
- package/dist/scan.js +1 -1
- package/dist/setup-agents.js +22 -35
- package/dist/setup-banner.d.ts +20 -0
- package/dist/setup-banner.js +39 -0
- package/dist/setup-context.js +24 -15
- package/dist/setup-databases.js +31 -59
- package/dist/setup-demo-tour.js +12 -8
- package/dist/setup-embeddings.js +9 -9
- package/dist/setup-interrupt.js +1 -1
- package/dist/setup-models.d.ts +4 -1
- package/dist/setup-models.js +54 -28
- package/dist/setup-project.js +29 -5
- package/dist/setup-prompts.js +16 -5
- package/dist/setup-ready-menu.js +1 -1
- package/dist/setup-sources.js +27 -7
- package/dist/setup.d.ts +25 -0
- package/dist/setup.js +90 -19
- package/dist/skills/analytics/SKILL.md +3 -3
- package/dist/skills/dbt_ingest/SKILL.md +3 -3
- package/dist/skills/looker_ingest/SKILL.md +3 -3
- package/dist/skills/lookml_ingest/SKILL.md +7 -7
- package/dist/skills/metabase_ingest/SKILL.md +4 -4
- package/dist/skills/metricflow_ingest/SKILL.md +15 -15
- package/dist/skills/notion_synthesize/SKILL.md +1 -1
- package/dist/skills/sl/SKILL.md +3 -3
- package/dist/skills/sl_capture/SKILL.md +1 -1
- package/dist/skills/wiki_capture/SKILL.md +1 -1
- package/dist/source-mapping.js +1 -1
- package/dist/startup-profile.js +1 -1
- package/dist/status-project.d.ts +0 -2
- package/dist/status-project.js +4 -6
- package/dist/telemetry/command-hook.d.ts +24 -0
- package/dist/telemetry/command-hook.js +37 -3
- package/dist/telemetry/events.d.ts +1 -1
- package/dist/telemetry/exception.js +14 -0
- package/dist/telemetry/index.d.ts +2 -2
- package/dist/telemetry/index.js +2 -2
- package/dist/text-ingest.js +1 -1
- package/dist/tree-picker-tui.d.ts +0 -1
- package/dist/tree-picker-tui.js +2 -3
- package/package.json +1 -1
package/dist/ingest.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ export interface KtxIngestDeps {
|
|
|
60
60
|
startLiveMemoryFlow?: typeof startLiveMemoryFlowTui;
|
|
61
61
|
abortSignal?: AbortSignal;
|
|
62
62
|
env?: NodeJS.ProcessEnv;
|
|
63
|
-
localIngestOptions?: Pick<RunLocalIngestOptions, 'agentRunner' | 'llmRuntime' | 'memoryModel' | 'semanticLayerCompute' | 'queryExecutor' | 'logger' | 'pullConfigOptions'>;
|
|
63
|
+
localIngestOptions?: Pick<RunLocalIngestOptions, 'agentRunner' | 'llmRuntime' | 'memoryModel' | 'semanticLayerCompute' | 'queryExecutor' | 'sqlAnalysis' | 'logger' | 'pullConfigOptions'>;
|
|
64
64
|
progress?: (update: KtxIngestProgressUpdate) => void;
|
|
65
65
|
runtimeIo?: KtxIngestIo;
|
|
66
66
|
}
|
package/dist/ingest.js
CHANGED
|
@@ -11,7 +11,7 @@ import { resolveProjectEmbeddingProvider } from './embedding-resolution.js';
|
|
|
11
11
|
import { createKtxCliIngestQueryExecutor } from './ingest-query-executor.js';
|
|
12
12
|
import { readIngestReportSnapshotFile } from './ingest-report-file.js';
|
|
13
13
|
import { createCliOperationalLogger } from './io/logger.js';
|
|
14
|
-
import { createKtxCliLocalIngestAdapters } from './local-adapters.js';
|
|
14
|
+
import { createKtxCliLocalIngestAdapters, resolveKtxCliSqlAnalysis } from './local-adapters.js';
|
|
15
15
|
import { renderMemoryFlowInteractively } from './memory-flow-interactive.js';
|
|
16
16
|
import { renderMemoryFlowTui, startLiveMemoryFlowTui, } from './memory-flow-tui.js';
|
|
17
17
|
import { resolveVizFallback, warnVizFallbackOnce } from './viz-fallback.js';
|
|
@@ -525,7 +525,7 @@ export async function runKtxIngest(args, io = process, deps = {}) {
|
|
|
525
525
|
const localIngestOptions = deps.localIngestOptions ?? {};
|
|
526
526
|
const managedDaemon = managedDaemonOptionsForIngestRun(args, deps.runtimeIo ?? io);
|
|
527
527
|
const operationalLogger = createCliOperationalLogger(io, args.outputMode);
|
|
528
|
-
const
|
|
528
|
+
const baseAdapterOptions = {
|
|
529
529
|
...(localIngestOptions.pullConfigOptions ?? {}),
|
|
530
530
|
...(args.databaseIntrospectionUrl ? { databaseIntrospectionUrl: args.databaseIntrospectionUrl } : {}),
|
|
531
531
|
...(managedDaemon ? { managedDaemon } : {}),
|
|
@@ -535,6 +535,10 @@ export async function runKtxIngest(args, io = process, deps = {}) {
|
|
|
535
535
|
: {}),
|
|
536
536
|
logger: operationalLogger,
|
|
537
537
|
};
|
|
538
|
+
// One parser-backed SQL analysis port per run: the historic-sql adapter and
|
|
539
|
+
// the ingest sql_execution tool share the same daemon-backed validator.
|
|
540
|
+
const sqlAnalysis = localIngestOptions.sqlAnalysis ?? resolveKtxCliSqlAnalysis(baseAdapterOptions);
|
|
541
|
+
const adapterOptions = { ...baseAdapterOptions, sqlAnalysis };
|
|
538
542
|
const queryExecutor = localIngestOptions.queryExecutor ??
|
|
539
543
|
(deps.createQueryExecutor ?? createKtxCliIngestQueryExecutor)(ingestProject);
|
|
540
544
|
if (args.adapter === 'metabase' && args.sourceDir) {
|
|
@@ -577,6 +581,7 @@ export async function runKtxIngest(args, io = process, deps = {}) {
|
|
|
577
581
|
metabaseConnectionId: args.connectionId,
|
|
578
582
|
...localIngestOptions,
|
|
579
583
|
queryExecutor,
|
|
584
|
+
sqlAnalysis,
|
|
580
585
|
trigger: 'manual_resync',
|
|
581
586
|
jobIdFactory: deps.jobIdFactory,
|
|
582
587
|
embeddingProvider,
|
|
@@ -650,6 +655,7 @@ export async function runKtxIngest(args, io = process, deps = {}) {
|
|
|
650
655
|
jobId,
|
|
651
656
|
...localIngestOptions,
|
|
652
657
|
queryExecutor,
|
|
658
|
+
sqlAnalysis,
|
|
653
659
|
pullConfigOptions: adapterOptions,
|
|
654
660
|
embeddingProvider,
|
|
655
661
|
...(args.debugLlmRequestFile ? { llmDebugRequestFile: args.debugLlmRequestFile } : {}),
|
package/dist/io/symbols.d.ts
CHANGED
package/dist/io/symbols.js
CHANGED
|
@@ -9,6 +9,8 @@ function detectUnicodeSupport(env = process.env) {
|
|
|
9
9
|
env.TERM === 'alacritty');
|
|
10
10
|
}
|
|
11
11
|
const unicode = detectUnicodeSupport();
|
|
12
|
+
/** Whether the active terminal renders Unicode glyphs (block/box drawing, arrows). */
|
|
13
|
+
export const unicodeSupported = unicode;
|
|
12
14
|
export const SYMBOLS = {
|
|
13
15
|
middot: unicode ? '·' : '-',
|
|
14
16
|
emDash: unicode ? '—' : '--',
|
package/dist/io/tty.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Writable } from 'node:stream';
|
|
2
|
+
import type { KtxCliIo } from '../cli-runtime.js';
|
|
3
|
+
type KtxCliOutput = (KtxCliIo['stdout'] | KtxCliIo['stderr']) & {
|
|
4
|
+
isTTY?: boolean;
|
|
5
|
+
columns?: number;
|
|
6
|
+
on?: unknown;
|
|
7
|
+
};
|
|
8
|
+
export declare function isWritableTtyOutput(output: KtxCliOutput): output is KtxCliOutput & Writable;
|
|
9
|
+
export declare function shouldUseColorOutput(output: {
|
|
10
|
+
isTTY?: boolean;
|
|
11
|
+
}): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Color depth in bits for the given output: 1 when color is disabled, the
|
|
14
|
+
* stream-reported depth when available, and a 16-color baseline otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export declare function colorDepthForOutput(output: KtxCliOutput): number;
|
|
17
|
+
export {};
|
package/dist/io/tty.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function isWritableTtyOutput(output) {
|
|
2
|
+
return (output.isTTY === true &&
|
|
3
|
+
typeof output.on === 'function' &&
|
|
4
|
+
typeof output.columns !== 'undefined');
|
|
5
|
+
}
|
|
6
|
+
export function shouldUseColorOutput(output) {
|
|
7
|
+
if (output.isTTY !== true)
|
|
8
|
+
return false;
|
|
9
|
+
const env = process.env;
|
|
10
|
+
return !env.NO_COLOR && env.TERM !== 'dumb' && !env.CI;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Color depth in bits for the given output: 1 when color is disabled, the
|
|
14
|
+
* stream-reported depth when available, and a 16-color baseline otherwise.
|
|
15
|
+
*/
|
|
16
|
+
export function colorDepthForOutput(output) {
|
|
17
|
+
if (!shouldUseColorOutput(output))
|
|
18
|
+
return 1;
|
|
19
|
+
const getColorDepth = output.getColorDepth;
|
|
20
|
+
return typeof getColorDepth === 'function' ? getColorDepth.call(output) : 4;
|
|
21
|
+
}
|
package/dist/links.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SLACK_URL = "https://ktx.sh/slack";
|
package/dist/links.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const SLACK_URL = 'https://ktx.sh/slack';
|
|
@@ -21,7 +21,7 @@ async function withTimeout(promise, timeoutMs) {
|
|
|
21
21
|
export async function runKtxEmbeddingHealthCheck(config, options = {}) {
|
|
22
22
|
try {
|
|
23
23
|
const provider = createKtxEmbeddingProvider(config, options.deps);
|
|
24
|
-
const embedding = await withTimeout(provider.embed(options.text ?? '
|
|
24
|
+
const embedding = await withTimeout(provider.embed(options.text ?? 'ktx embedding health check'), options.timeoutMs ?? 15_000);
|
|
25
25
|
if (embedding.length !== config.dimensions) {
|
|
26
26
|
return {
|
|
27
27
|
ok: false,
|
|
@@ -49,7 +49,7 @@ class OpenAIEmbeddingProvider {
|
|
|
49
49
|
this.dimensions = config.dimensions;
|
|
50
50
|
this.maxBatchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
51
51
|
if (!config.openai?.apiKey) {
|
|
52
|
-
throw new Error('openai.apiKey is required when
|
|
52
|
+
throw new Error('openai.apiKey is required when ktx embedding backend is openai');
|
|
53
53
|
}
|
|
54
54
|
this.client = deps.createOpenAIClient
|
|
55
55
|
? deps.createOpenAIClient({ apiKey: config.openai.apiKey, baseURL: config.openai.baseURL })
|
|
@@ -90,7 +90,7 @@ class SentenceTransformersEmbeddingProvider {
|
|
|
90
90
|
startupProbe;
|
|
91
91
|
constructor(config, deps) {
|
|
92
92
|
if (!config.sentenceTransformers?.baseURL) {
|
|
93
|
-
throw new Error('sentenceTransformers.baseURL is required when
|
|
93
|
+
throw new Error('sentenceTransformers.baseURL is required when ktx embedding backend is sentence-transformers');
|
|
94
94
|
}
|
|
95
95
|
this.dimensions = config.dimensions;
|
|
96
96
|
this.maxBatchSize = config.batchSize ?? DEFAULT_BATCH_SIZE;
|
|
@@ -156,6 +156,6 @@ export function createKtxEmbeddingProvider(config, deps = {}) {
|
|
|
156
156
|
case 'sentence-transformers':
|
|
157
157
|
return new SentenceTransformersEmbeddingProvider(config, deps);
|
|
158
158
|
default:
|
|
159
|
-
throw new Error(`Unsupported
|
|
159
|
+
throw new Error(`Unsupported ktx embedding backend: ${String(config.backend)}`);
|
|
160
160
|
}
|
|
161
161
|
}
|
|
@@ -121,7 +121,7 @@ class DefaultKtxLlmProvider {
|
|
|
121
121
|
}
|
|
122
122
|
if (config.backend === 'vertex') {
|
|
123
123
|
if (!config.vertex?.location) {
|
|
124
|
-
throw new Error('vertex.location is required when
|
|
124
|
+
throw new Error('vertex.location is required when ktx LLM backend is vertex');
|
|
125
125
|
}
|
|
126
126
|
const vertex = (deps.createVertexAnthropic ?? createVertexAnthropic)({
|
|
127
127
|
...(config.vertex.project ? { project: config.vertex.project } : {}),
|
package/dist/local-adapters.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import type { KtxLocalProject } from './context/project/project.js';
|
|
|
5
5
|
import type { SqlAnalysisPort } from './context/sql-analysis/ports.js';
|
|
6
6
|
import { type ManagedPythonDaemonHttpOptions } from './managed-python-http.js';
|
|
7
7
|
import type { KtxOperationalLogger } from './io/logger.js';
|
|
8
|
+
export declare function resolveKtxCliSqlAnalysis(options: KtxCliLocalIngestAdaptersOptions): SqlAnalysisPort;
|
|
8
9
|
export interface KtxCliLocalIngestAdaptersOptions extends DefaultLocalIngestAdaptersOptions {
|
|
9
10
|
historicSqlConnectionId?: string;
|
|
10
11
|
sqlAnalysis?: SqlAnalysisPort;
|
package/dist/local-adapters.js
CHANGED
|
@@ -45,7 +45,7 @@ function ktxCliLookerOptions(options) {
|
|
|
45
45
|
parser: createManagedDaemonLookerTableIdentifierParser(options.managedDaemon),
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
|
-
function
|
|
48
|
+
export function resolveKtxCliSqlAnalysis(options) {
|
|
49
49
|
if (options.sqlAnalysis) {
|
|
50
50
|
return options.sqlAnalysis;
|
|
51
51
|
}
|
|
@@ -234,7 +234,7 @@ function historicSqlOptionsForLocalRun(project, options) {
|
|
|
234
234
|
return undefined;
|
|
235
235
|
}
|
|
236
236
|
const base = {
|
|
237
|
-
sqlAnalysis:
|
|
237
|
+
sqlAnalysis: resolveKtxCliSqlAnalysis(options),
|
|
238
238
|
};
|
|
239
239
|
if (dialect === 'postgres') {
|
|
240
240
|
return {
|
|
@@ -11,7 +11,7 @@ export async function createKtxCliScanConnector(project, connectionId) {
|
|
|
11
11
|
}
|
|
12
12
|
const registration = getDriverRegistration(driver);
|
|
13
13
|
if (!registration) {
|
|
14
|
-
throw new Error(`Connection "${connectionId}" uses driver "${driver}", which has no native standalone
|
|
14
|
+
throw new Error(`Connection "${connectionId}" uses driver "${driver}", which has no native standalone ktx scan connector. Supported drivers: ${SUPPORTED_DRIVERS}.`);
|
|
15
15
|
}
|
|
16
16
|
const connectorModule = await registration.load();
|
|
17
17
|
if (!connectorModule.isConnectionConfig(connection)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createCliSpinner } from './clack.js';
|
|
2
2
|
import { ensureManagedPythonCommandRuntime, } from './managed-python-command.js';
|
|
3
3
|
import { readManagedPythonDaemonStatus, startManagedPythonDaemon, } from './managed-python-daemon.js';
|
|
4
4
|
export function managedLocalEmbeddingHealthConfig(input) {
|
|
@@ -21,14 +21,23 @@ export async function ensureManagedLocalEmbeddingsDaemon(options) {
|
|
|
21
21
|
io: options.io,
|
|
22
22
|
feature: 'local-embeddings',
|
|
23
23
|
});
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
const spinner = createCliSpinner(options.io);
|
|
25
|
+
spinner.start('Starting ktx embedding daemon (first run downloads the model)…');
|
|
26
|
+
let daemon;
|
|
27
|
+
try {
|
|
28
|
+
daemon = await startDaemon({
|
|
29
|
+
cliVersion: options.cliVersion,
|
|
30
|
+
projectDir: options.projectDir,
|
|
31
|
+
features: ['local-embeddings'],
|
|
32
|
+
force: false,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
spinner.error('ktx embedding daemon failed to start');
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
30
39
|
const verb = daemon.status === 'started' ? 'Started' : 'Using';
|
|
31
|
-
|
|
40
|
+
spinner.stop(`${verb} ktx daemon: ${daemon.baseUrl}`);
|
|
32
41
|
return {
|
|
33
42
|
baseUrl: daemon.baseUrl,
|
|
34
43
|
stdoutLog: daemon.state.stdoutLog,
|
|
@@ -92,7 +92,7 @@ export async function startKtxMcpDaemon(options) {
|
|
|
92
92
|
url: `http://${existing.host}:${existing.port}/mcp`,
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
|
-
throw new Error(`
|
|
95
|
+
throw new Error(`ktx MCP daemon is already running at http://${existing.host}:${existing.port}/mcp ` +
|
|
96
96
|
'with a different configuration. Run `ktx mcp stop` first, then start again.');
|
|
97
97
|
}
|
|
98
98
|
const portAvailable = options.portAvailable ?? defaultPortAvailable;
|
|
@@ -126,7 +126,7 @@ export async function startKtxMcpDaemon(options) {
|
|
|
126
126
|
}),
|
|
127
127
|
});
|
|
128
128
|
if (!child.pid) {
|
|
129
|
-
throw new Error('Failed to start
|
|
129
|
+
throw new Error('Failed to start ktx MCP daemon: child process pid was not available.');
|
|
130
130
|
}
|
|
131
131
|
child.unref();
|
|
132
132
|
const state = {
|
|
@@ -167,7 +167,7 @@ export async function readKtxMcpDaemonStatus(options) {
|
|
|
167
167
|
}
|
|
168
168
|
return {
|
|
169
169
|
kind: 'running',
|
|
170
|
-
detail: `
|
|
170
|
+
detail: `ktx MCP daemon running at http://${state.host}:${state.port}/mcp`,
|
|
171
171
|
state,
|
|
172
172
|
url: `http://${state.host}:${state.port}/mcp`,
|
|
173
173
|
};
|
|
@@ -31,4 +31,11 @@ export interface ManagedPythonSemanticLayerComputeOptions extends ManagedPythonC
|
|
|
31
31
|
export declare function managedRuntimeInstallCommand(feature: KtxRuntimeFeature): string;
|
|
32
32
|
export declare function ensureManagedPythonCommandRuntime(options: ManagedPythonCommandOptions): Promise<ManagedPythonCommandRuntime>;
|
|
33
33
|
export declare function createManagedPythonSemanticLayerComputePort(options: ManagedPythonSemanticLayerComputeOptions): Promise<KtxSemanticLayerComputePort>;
|
|
34
|
+
/**
|
|
35
|
+
* Defers the managed-runtime install to the first semantic-layer call so a
|
|
36
|
+
* long-lived server (the MCP server) can start and serve context tools that
|
|
37
|
+
* need no Python even when uv is absent. Caches on success only, so a runtime
|
|
38
|
+
* installed mid-session is picked up on the next call.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createLazyManagedPythonSemanticLayerComputePort(options: ManagedPythonSemanticLayerComputeOptions): KtxSemanticLayerComputePort;
|
|
34
41
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createPythonSemanticLayerComputePort } from './context/daemon/semantic-layer-compute.js';
|
|
2
|
-
import { createClackPromptAdapter,
|
|
2
|
+
import { createClackPromptAdapter, createCliSpinner } from './clack.js';
|
|
3
3
|
import { installManagedPythonRuntime, readManagedPythonRuntimeStatus, } from './managed-python-runtime.js';
|
|
4
4
|
import { readExistingTelemetryProjectId } from './telemetry/identity.js';
|
|
5
5
|
export function runtimeInstallPolicyFromFlags(options) {
|
|
@@ -19,10 +19,10 @@ export function managedRuntimeInstallCommand(feature) {
|
|
|
19
19
|
}
|
|
20
20
|
function installPrompt(feature) {
|
|
21
21
|
const label = feature === 'local-embeddings' ? 'local embeddings Python runtime' : 'core Python runtime';
|
|
22
|
-
return `
|
|
22
|
+
return `ktx needs to install the ${label}. This downloads a pinned, checksum-verified uv build, Python, and dependencies. Continue?`;
|
|
23
23
|
}
|
|
24
24
|
function runtimeRequiredMessage(feature) {
|
|
25
|
-
return `
|
|
25
|
+
return `ktx Python runtime is required for this command. Run: ${managedRuntimeInstallCommand(feature)}`;
|
|
26
26
|
}
|
|
27
27
|
function hasFeature(manifest, feature) {
|
|
28
28
|
return manifest.features.includes(feature);
|
|
@@ -49,22 +49,22 @@ export async function ensureManagedPythonCommandRuntime(options) {
|
|
|
49
49
|
const confirmInstall = options.confirmInstall ?? defaultConfirmInstall;
|
|
50
50
|
const confirmed = await confirmInstall(installPrompt(feature), options.io);
|
|
51
51
|
if (!confirmed) {
|
|
52
|
-
throw new Error(`
|
|
52
|
+
throw new Error(`ktx Python runtime installation was cancelled. Run: ${managedRuntimeInstallCommand(feature)}`);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
const progress = (options.spinner ?? (() =>
|
|
56
|
-
progress.start(`Installing
|
|
55
|
+
const progress = (options.spinner ?? (() => createCliSpinner(options.io)))();
|
|
56
|
+
progress.start(`Installing ktx Python runtime (${feature}) with uv...`);
|
|
57
57
|
try {
|
|
58
58
|
const installed = await installRuntime({
|
|
59
59
|
cliVersion: options.cliVersion,
|
|
60
60
|
features: [feature],
|
|
61
61
|
force: false,
|
|
62
62
|
});
|
|
63
|
-
progress.stop(`
|
|
63
|
+
progress.stop(`ktx Python runtime ready: ${installed.layout.versionDir}`);
|
|
64
64
|
return { layout: installed.layout, manifest: installed.manifest };
|
|
65
65
|
}
|
|
66
66
|
catch (error) {
|
|
67
|
-
progress.error(`
|
|
67
|
+
progress.error(`ktx Python runtime install failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
68
68
|
throw error;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
@@ -89,3 +89,29 @@ export async function createManagedPythonSemanticLayerComputePort(options) {
|
|
|
89
89
|
...(projectId ? { projectId } : {}),
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Defers the managed-runtime install to the first semantic-layer call so a
|
|
94
|
+
* long-lived server (the MCP server) can start and serve context tools that
|
|
95
|
+
* need no Python even when uv is absent. Caches on success only, so a runtime
|
|
96
|
+
* installed mid-session is picked up on the next call.
|
|
97
|
+
*/
|
|
98
|
+
export function createLazyManagedPythonSemanticLayerComputePort(options) {
|
|
99
|
+
let cached;
|
|
100
|
+
const resolve = async () => {
|
|
101
|
+
if (!cached) {
|
|
102
|
+
cached = await createManagedPythonSemanticLayerComputePort(options);
|
|
103
|
+
}
|
|
104
|
+
return cached;
|
|
105
|
+
};
|
|
106
|
+
return {
|
|
107
|
+
async query(input) {
|
|
108
|
+
return (await resolve()).query(input);
|
|
109
|
+
},
|
|
110
|
+
async validateSources(input) {
|
|
111
|
+
return (await resolve()).validateSources(input);
|
|
112
|
+
},
|
|
113
|
+
async generateSources(input) {
|
|
114
|
+
return (await resolve()).generateSources(input);
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
@@ -11,7 +11,7 @@ export class ManagedPythonDaemonStartError extends Error {
|
|
|
11
11
|
detail;
|
|
12
12
|
stderrLog;
|
|
13
13
|
constructor(detail, stderrLog) {
|
|
14
|
-
super(`
|
|
14
|
+
super(`ktx daemon failed to start: ${detail}. stderr: ${stderrLog}`);
|
|
15
15
|
this.name = 'ManagedPythonDaemonStartError';
|
|
16
16
|
this.detail = detail;
|
|
17
17
|
this.stderrLog = stderrLog;
|
|
@@ -502,7 +502,7 @@ export async function startManagedPythonDaemon(options) {
|
|
|
502
502
|
});
|
|
503
503
|
child.unref();
|
|
504
504
|
if (!child.pid) {
|
|
505
|
-
throw new Error(`
|
|
505
|
+
throw new Error(`ktx daemon did not report a pid. stderr: ${layout.daemonStderrPath}`);
|
|
506
506
|
}
|
|
507
507
|
const state = {
|
|
508
508
|
schemaVersion: 1,
|
|
@@ -12,7 +12,7 @@ function normalizedBaseUrl(baseUrl) {
|
|
|
12
12
|
function parseJsonObject(raw, path) {
|
|
13
13
|
const parsed = JSON.parse(raw);
|
|
14
14
|
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
15
|
-
throw new Error(`
|
|
15
|
+
throw new Error(`ktx daemon HTTP ${path} returned non-object JSON`);
|
|
16
16
|
}
|
|
17
17
|
return parsed;
|
|
18
18
|
}
|
|
@@ -35,7 +35,7 @@ async function postManagedDaemonJson(baseUrl, path, payload) {
|
|
|
35
35
|
const text = Buffer.concat(chunks).toString('utf8');
|
|
36
36
|
const statusCode = response.statusCode ?? 0;
|
|
37
37
|
if (statusCode < 200 || statusCode >= 300) {
|
|
38
|
-
reject(new Error(`
|
|
38
|
+
reject(new Error(`ktx daemon HTTP ${path} failed with ${statusCode}: ${text}`));
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
try {
|
|
@@ -72,7 +72,7 @@ export function createManagedPythonDaemonBaseUrlResolver(options) {
|
|
|
72
72
|
force: false,
|
|
73
73
|
});
|
|
74
74
|
const verb = daemon.status === 'started' ? 'Started' : 'Using existing';
|
|
75
|
-
writePrefixedLines((chunk) => options.io.stderr.write(chunk), `${verb}
|
|
75
|
+
writePrefixedLines((chunk) => options.io.stderr.write(chunk), `${verb} ktx daemon: ${daemon.baseUrl}`);
|
|
76
76
|
cachedBaseUrl = daemon.baseUrl;
|
|
77
77
|
return cachedBaseUrl;
|
|
78
78
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { type ManagedUvArtifact, type ManagedUvPlatformKey } from './managed-uv-release.js';
|
|
2
3
|
export declare const runtimeFeatureSchema: z.ZodEnum<{
|
|
3
4
|
core: "core";
|
|
4
5
|
"local-embeddings": "local-embeddings";
|
|
@@ -92,6 +93,7 @@ export interface ManagedPythonRuntimeInstallOptions extends ManagedPythonRuntime
|
|
|
92
93
|
features: KtxRuntimeFeature[];
|
|
93
94
|
force?: boolean;
|
|
94
95
|
exec?: ManagedPythonRuntimeExec;
|
|
96
|
+
fetchUvArtifact?: ManagedUvFetchArtifact;
|
|
95
97
|
}
|
|
96
98
|
export interface ManagedPythonRuntimeInstallResult {
|
|
97
99
|
status: 'ready' | 'installed';
|
|
@@ -113,8 +115,22 @@ export interface ManagedPythonRuntimeDoctorCheck {
|
|
|
113
115
|
detail: string;
|
|
114
116
|
fix?: string;
|
|
115
117
|
}
|
|
118
|
+
export type ManagedUvFetchArtifact = (url: string) => Promise<Uint8Array>;
|
|
116
119
|
/** @internal */
|
|
117
|
-
export
|
|
120
|
+
export interface ManagedUvRelease {
|
|
121
|
+
version: string;
|
|
122
|
+
artifacts: Partial<Record<ManagedUvPlatformKey, ManagedUvArtifact>>;
|
|
123
|
+
}
|
|
124
|
+
/** @internal */
|
|
125
|
+
export interface EnsureManagedUvOptions {
|
|
126
|
+
platform?: NodeJS.Platform;
|
|
127
|
+
arch?: string;
|
|
128
|
+
env?: NodeJS.ProcessEnv;
|
|
129
|
+
homeDir?: string;
|
|
130
|
+
runtimeRoot?: string;
|
|
131
|
+
fetchArtifact?: ManagedUvFetchArtifact;
|
|
132
|
+
release?: ManagedUvRelease;
|
|
133
|
+
}
|
|
118
134
|
/** @internal */
|
|
119
135
|
export declare function managedPythonRuntimeLayout(options: ManagedPythonRuntimeLayoutOptions): ManagedPythonRuntimeLayout;
|
|
120
136
|
export declare function managedPythonDaemonLayout(options: ManagedPythonDaemonLayoutOptions): ManagedPythonDaemonLayout;
|
|
@@ -122,9 +138,22 @@ export declare function managedPythonDaemonLayout(options: ManagedPythonDaemonLa
|
|
|
122
138
|
export declare function verifyRuntimeAsset(input: {
|
|
123
139
|
assetDir: string;
|
|
124
140
|
}): Promise<ManagedRuntimeAsset>;
|
|
141
|
+
/** @internal */
|
|
142
|
+
export declare function managedUvPath(options?: EnsureManagedUvOptions): string;
|
|
143
|
+
/**
|
|
144
|
+
* ktx provisions its own pinned uv under the runtime root; uv on PATH is never
|
|
145
|
+
* consulted, so runtime installs behave identically on every machine. All
|
|
146
|
+
* failures here are environment outcomes (offline host, intercepting proxy,
|
|
147
|
+
* unsupported platform) and stay out of Error Tracking via KtxExpectedError —
|
|
148
|
+
* except a pin/layout mismatch inside a checksum-verified archive, which is a
|
|
149
|
+
* ktx release fault and must reach Error Tracking.
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
export declare function ensureManagedUv(options?: EnsureManagedUvOptions): Promise<string>;
|
|
125
153
|
export declare function installManagedPythonRuntime(options: ManagedPythonRuntimeInstallOptions): Promise<ManagedPythonRuntimeInstallResult>;
|
|
126
154
|
export declare function readManagedPythonRuntimeStatus(options: ManagedPythonRuntimeLayoutOptions): Promise<ManagedPythonRuntimeStatus>;
|
|
127
155
|
export declare function doctorManagedPythonRuntime(options: ManagedPythonRuntimeLayoutOptions & {
|
|
128
156
|
exec?: ManagedPythonRuntimeExec;
|
|
157
|
+
fetchUvArtifact?: ManagedUvFetchArtifact;
|
|
129
158
|
}): Promise<ManagedPythonRuntimeDoctorCheck[]>;
|
|
130
159
|
export {};
|