@kaelio/ktx 0.8.0 → 0.10.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.8.0-py3-none-any.whl → kaelio_ktx-0.10.0-py3-none-any.whl} +0 -0
- package/assets/python/manifest.json +4 -4
- package/dist/.tsbuildinfo +1 -1
- package/dist/clack.d.ts +6 -0
- package/dist/clack.js +17 -2
- package/dist/cli-program.d.ts +3 -0
- package/dist/cli-program.js +42 -2
- package/dist/cli-runtime.d.ts +3 -0
- package/dist/cli-runtime.js +94 -3
- package/dist/commands/setup-commands.js +3 -4
- package/dist/connection-recovery.d.ts +34 -0
- package/dist/connection-recovery.js +82 -0
- package/dist/connection.js +26 -2
- package/dist/connectors/bigquery/connector.d.ts +2 -5
- package/dist/connectors/bigquery/connector.js +2 -2
- package/dist/connectors/clickhouse/connector.d.ts +2 -5
- package/dist/connectors/clickhouse/connector.js +2 -2
- package/dist/connectors/mysql/connector.d.ts +7 -6
- package/dist/connectors/mysql/connector.js +25 -5
- package/dist/connectors/mysql/dialect.d.ts +1 -1
- package/dist/connectors/mysql/dialect.js +12 -2
- package/dist/connectors/postgres/connector.d.ts +2 -5
- package/dist/connectors/postgres/connector.js +2 -2
- package/dist/connectors/snowflake/connector.d.ts +2 -5
- package/dist/connectors/snowflake/connector.js +2 -2
- package/dist/connectors/sqlite/connector.d.ts +2 -5
- package/dist/connectors/sqlite/connector.js +2 -2
- package/dist/connectors/sqlserver/connector.d.ts +2 -5
- package/dist/connectors/sqlserver/connector.js +2 -2
- package/dist/context/connections/drivers.d.ts +0 -1
- package/dist/context/connections/drivers.js +0 -7
- package/dist/context/connections/query-executor.d.ts +2 -1
- package/dist/context/core/abort.d.ts +9 -0
- package/dist/context/core/abort.js +36 -0
- package/dist/context/ingest/adapters/historic-sql/bigquery-query-history-reader.js +71 -20
- package/dist/context/ingest/adapters/historic-sql/chunk-unified.js +2 -1
- package/dist/context/ingest/adapters/historic-sql/connection-dialect.d.ts +9 -0
- package/dist/context/ingest/adapters/historic-sql/connection-dialect.js +15 -4
- package/dist/context/ingest/adapters/historic-sql/pattern-inputs.js +8 -2
- package/dist/context/ingest/adapters/historic-sql/query-history-filter-picker.d.ts +30 -0
- package/dist/context/ingest/adapters/historic-sql/query-history-filter-picker.js +194 -0
- package/dist/context/ingest/adapters/historic-sql/scope-floor.d.ts +18 -0
- package/dist/context/ingest/adapters/historic-sql/scope-floor.js +229 -0
- package/dist/context/ingest/adapters/historic-sql/scope-membership.d.ts +8 -0
- package/dist/context/ingest/adapters/historic-sql/scope-membership.js +29 -0
- package/dist/context/ingest/adapters/historic-sql/snowflake-query-history-reader.js +68 -19
- package/dist/context/ingest/adapters/historic-sql/stage-unified.js +57 -50
- package/dist/context/ingest/adapters/historic-sql/types.d.ts +36 -3
- package/dist/context/ingest/adapters/historic-sql/types.js +14 -2
- package/dist/context/ingest/context-candidates/curator-pagination.service.d.ts +1 -5
- package/dist/context/ingest/context-candidates/curator-pagination.service.js +1 -3
- package/dist/context/ingest/context-evidence/sqlite-context-evidence-store.d.ts +1 -1
- package/dist/context/ingest/final-gate-repair.d.ts +1 -0
- package/dist/context/ingest/final-gate-repair.js +1 -0
- package/dist/context/ingest/ingest-bundle.runner.d.ts +3 -0
- package/dist/context/ingest/ingest-bundle.runner.js +127 -53
- package/dist/context/ingest/isolated-diff/patch-integrator.js +75 -5
- package/dist/context/ingest/isolated-diff/textual-conflict-resolver.d.ts +1 -0
- package/dist/context/ingest/isolated-diff/textual-conflict-resolver.js +1 -0
- package/dist/context/ingest/isolated-diff/work-unit-executor.d.ts +1 -0
- package/dist/context/ingest/local-adapters.js +21 -4
- package/dist/context/ingest/local-bundle-runtime.js +13 -5
- package/dist/context/ingest/local-ingest.d.ts +1 -0
- package/dist/context/ingest/local-ingest.js +13 -3
- package/dist/context/ingest/memory-flow/events.js +1 -1
- package/dist/context/ingest/memory-flow/schema.js +8 -3
- package/dist/context/ingest/memory-flow/types.d.ts +7 -3
- package/dist/context/ingest/ports.d.ts +3 -5
- package/dist/context/ingest/stages/stage-3-work-units.d.ts +1 -4
- package/dist/context/ingest/stages/stage-3-work-units.js +5 -1
- package/dist/context/ingest/stages/stage-4-reconciliation.d.ts +1 -4
- package/dist/context/ingest/stages/stage-4-reconciliation.js +1 -1
- package/dist/context/ingest/types.d.ts +1 -0
- package/dist/context/llm/ai-sdk-runtime.d.ts +3 -0
- package/dist/context/llm/ai-sdk-runtime.js +152 -16
- package/dist/context/llm/claude-code-runtime.d.ts +6 -4
- package/dist/context/llm/claude-code-runtime.js +127 -48
- package/dist/context/llm/codex-exec-events.d.ts +20 -0
- package/dist/context/llm/codex-exec-events.js +155 -0
- package/dist/context/llm/codex-isolation.d.ts +3 -0
- package/dist/context/llm/codex-isolation.js +5 -0
- package/dist/context/llm/codex-mcp-runtime-server.d.ts +24 -0
- package/dist/context/llm/codex-mcp-runtime-server.js +51 -0
- package/dist/context/llm/codex-models.d.ts +2 -0
- package/dist/context/llm/codex-models.js +17 -0
- package/dist/context/llm/codex-runtime-config.d.ts +16 -0
- package/dist/context/llm/codex-runtime-config.js +19 -0
- package/dist/context/llm/codex-runtime.d.ts +37 -0
- package/dist/context/llm/codex-runtime.js +347 -0
- package/dist/context/llm/codex-sdk-runner.d.ts +21 -0
- package/dist/context/llm/codex-sdk-runner.js +63 -0
- package/dist/context/llm/local-config.d.ts +16 -4
- package/dist/context/llm/local-config.js +18 -2
- package/dist/context/llm/rate-limit-governor.d.ts +103 -0
- package/dist/context/llm/rate-limit-governor.js +285 -0
- package/dist/context/llm/runtime-port.d.ts +3 -6
- package/dist/context/mcp/context-tools.js +43 -13
- package/dist/context/project/config.d.ts +14 -0
- package/dist/context/project/config.js +37 -2
- package/dist/context/scan/types.d.ts +15 -2
- package/dist/context/scan/types.js +12 -0
- package/dist/context/sl/description-normalization.js +4 -14
- package/dist/context/sql-analysis/http-sql-analysis-port.js +32 -2
- package/dist/context/sql-analysis/ports.d.ts +12 -2
- package/dist/context/tools/context-candidate-mark.tool.d.ts +2 -2
- package/dist/context-build-view.d.ts +13 -0
- package/dist/context-build-view.js +63 -32
- package/dist/demo-metrics.d.ts +0 -2
- package/dist/demo-metrics.js +1 -11
- package/dist/ingest.d.ts +1 -0
- package/dist/ingest.js +32 -3
- package/dist/io/buffered-command-io.d.ts +11 -0
- package/dist/io/buffered-command-io.js +28 -0
- package/dist/io/symbols.d.ts +2 -0
- package/dist/io/symbols.js +2 -0
- package/dist/llm/types.d.ts +1 -1
- package/dist/local-adapters.d.ts +10 -2
- package/dist/local-adapters.js +19 -3
- package/dist/memory-flow-hud.js +8 -16
- package/dist/next-steps.js +1 -2
- package/dist/progress-port-adapter.d.ts +6 -0
- package/dist/progress-port-adapter.js +18 -0
- package/dist/public-ingest.d.ts +20 -1
- package/dist/public-ingest.js +228 -42
- package/dist/reveal-password-prompt.d.ts +24 -0
- package/dist/reveal-password-prompt.js +78 -0
- package/dist/scan.js +21 -3
- package/dist/setup-context.d.ts +2 -0
- package/dist/setup-context.js +133 -27
- package/dist/setup-databases.d.ts +18 -1
- package/dist/setup-databases.js +378 -249
- package/dist/setup-demo-tour.js +1 -0
- package/dist/setup-embeddings.js +1 -1
- package/dist/setup-models.d.ts +11 -15
- package/dist/setup-models.js +140 -276
- package/dist/setup-prompts.js +3 -2
- package/dist/setup-ready-menu.d.ts +16 -2
- package/dist/setup-ready-menu.js +37 -5
- package/dist/setup-sources.js +115 -35
- package/dist/setup.d.ts +1 -1
- package/dist/setup.js +23 -11
- package/dist/sl.d.ts +2 -2
- package/dist/sl.js +20 -4
- package/dist/sql.js +18 -2
- package/dist/star-prompt/cache.d.ts +16 -0
- package/dist/star-prompt/cache.js +45 -0
- package/dist/star-prompt/star-count.d.ts +7 -0
- package/dist/star-prompt/star-count.js +66 -0
- package/dist/star-prompt/star-line.d.ts +12 -0
- package/dist/star-prompt/star-line.js +26 -0
- package/dist/status-project.d.ts +11 -0
- package/dist/status-project.js +50 -1
- package/dist/telemetry/command-hook.d.ts +1 -0
- package/dist/telemetry/command-hook.js +3 -1
- package/dist/telemetry/emitter.d.ts +10 -0
- package/dist/telemetry/emitter.js +31 -0
- package/dist/telemetry/events.d.ts +35 -6
- package/dist/telemetry/events.js +25 -2
- package/dist/telemetry/exception.d.ts +18 -0
- package/dist/telemetry/exception.js +162 -0
- package/dist/telemetry/identity.d.ts +0 -1
- package/dist/telemetry/identity.js +6 -6
- package/dist/telemetry/index.d.ts +15 -2
- package/dist/telemetry/index.js +15 -3
- package/dist/telemetry/redaction-secrets.d.ts +11 -0
- package/dist/telemetry/redaction-secrets.js +92 -0
- package/dist/telemetry/scrubber.d.ts +10 -0
- package/dist/telemetry/scrubber.js +20 -0
- package/dist/update-check/cache.d.ts +21 -0
- package/dist/update-check/cache.js +38 -0
- package/dist/update-check/channel.d.ts +15 -0
- package/dist/update-check/channel.js +30 -0
- package/dist/update-check/registry.d.ts +1 -0
- package/dist/update-check/registry.js +45 -0
- package/dist/update-check/update-check.d.ts +43 -0
- package/dist/update-check/update-check.js +116 -0
- package/package.json +12 -4
- package/dist/context/connections/local-query-executor.d.ts +0 -6
- package/dist/context/connections/local-query-executor.js +0 -39
- package/dist/context/connections/postgres-query-executor.d.ts +0 -25
- package/dist/context/connections/postgres-query-executor.js +0 -53
- package/dist/context/connections/sqlite-query-executor.d.ts +0 -4
- package/dist/context/connections/sqlite-query-executor.js +0 -74
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { request as httpsRequest } from 'node:https';
|
|
2
|
+
import { URL } from 'node:url';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
const GITHUB_REPO_URL = new URL('https://api.github.com/repos/Kaelio/ktx');
|
|
5
|
+
const DEFAULT_TIMEOUT_MS = 5000;
|
|
6
|
+
const githubRepoSchema = z.object({
|
|
7
|
+
stargazers_count: z.number().int().nonnegative(),
|
|
8
|
+
});
|
|
9
|
+
function parseStarCount(raw) {
|
|
10
|
+
return githubRepoSchema.parse(JSON.parse(raw)).stargazers_count;
|
|
11
|
+
}
|
|
12
|
+
export function fetchGitHubStarCount(options = {}) {
|
|
13
|
+
const requestImpl = options.request ?? httpsRequest;
|
|
14
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
15
|
+
return new Promise((resolve) => {
|
|
16
|
+
let settled = false;
|
|
17
|
+
const finish = (count) => {
|
|
18
|
+
if (settled) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
settled = true;
|
|
22
|
+
resolve(count);
|
|
23
|
+
};
|
|
24
|
+
try {
|
|
25
|
+
const request = requestImpl(GITHUB_REPO_URL, {
|
|
26
|
+
method: 'GET',
|
|
27
|
+
headers: {
|
|
28
|
+
accept: 'application/vnd.github+json',
|
|
29
|
+
'user-agent': 'ktx-star-prompt',
|
|
30
|
+
},
|
|
31
|
+
}, (response) => {
|
|
32
|
+
const chunks = [];
|
|
33
|
+
response.on('data', (chunk) => {
|
|
34
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
35
|
+
});
|
|
36
|
+
response.on('end', () => {
|
|
37
|
+
const statusCode = response.statusCode ?? 0;
|
|
38
|
+
if (statusCode < 200 || statusCode >= 300) {
|
|
39
|
+
finish(null);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
finish(parseStarCount(Buffer.concat(chunks).toString('utf8')));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
finish(null);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
request.on('socket', (socket) => {
|
|
51
|
+
socket.unref();
|
|
52
|
+
});
|
|
53
|
+
request.on('error', () => {
|
|
54
|
+
finish(null);
|
|
55
|
+
});
|
|
56
|
+
request.setTimeout(timeoutMs, () => {
|
|
57
|
+
request.destroy(new Error('GitHub star count request timed out'));
|
|
58
|
+
finish(null);
|
|
59
|
+
});
|
|
60
|
+
request.end();
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
finish(null);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface StarPromptSymbols {
|
|
2
|
+
star: string;
|
|
3
|
+
middot: string;
|
|
4
|
+
rightArrow: string;
|
|
5
|
+
}
|
|
6
|
+
export interface RenderStarPromptLineOptions {
|
|
7
|
+
columns: number;
|
|
8
|
+
count?: number | null;
|
|
9
|
+
symbols?: StarPromptSymbols;
|
|
10
|
+
}
|
|
11
|
+
export declare function renderStarPromptLine(options: RenderStarPromptLineOptions): string;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SYMBOLS } from '../io/symbols.js';
|
|
2
|
+
const STAR_PROMPT_URL = 'github.com/Kaelio/ktx';
|
|
3
|
+
const STAR_PROMPT_TEXT = 'This takes a few minutes - mind giving ktx a star while you wait?';
|
|
4
|
+
function usableColumns(columns) {
|
|
5
|
+
return Number.isFinite(columns) && columns > 0 ? Math.floor(columns) : 80;
|
|
6
|
+
}
|
|
7
|
+
function starCountSegment(count, symbols) {
|
|
8
|
+
if (typeof count !== 'number' || !Number.isFinite(count)) {
|
|
9
|
+
return '';
|
|
10
|
+
}
|
|
11
|
+
const formatted = new Intl.NumberFormat('en-US').format(count);
|
|
12
|
+
return ` ${symbols.middot} ${formatted} ${symbols.star}`;
|
|
13
|
+
}
|
|
14
|
+
export function renderStarPromptLine(options) {
|
|
15
|
+
const symbols = options.symbols ?? SYMBOLS;
|
|
16
|
+
const columns = usableColumns(options.columns);
|
|
17
|
+
const base = ` ${symbols.star} ${STAR_PROMPT_TEXT} ${STAR_PROMPT_URL}`;
|
|
18
|
+
const withCount = `${base}${starCountSegment(options.count, symbols)}`;
|
|
19
|
+
if (withCount.length <= columns) {
|
|
20
|
+
return withCount;
|
|
21
|
+
}
|
|
22
|
+
if (base.length <= columns) {
|
|
23
|
+
return base;
|
|
24
|
+
}
|
|
25
|
+
return ` ${symbols.star} Star ktx ${symbols.rightArrow} ${STAR_PROMPT_URL}`;
|
|
26
|
+
}
|
package/dist/status-project.d.ts
CHANGED
|
@@ -62,6 +62,16 @@ type ClaudeCodeAuthProbe = (input: {
|
|
|
62
62
|
ok: false;
|
|
63
63
|
message: string;
|
|
64
64
|
}>;
|
|
65
|
+
type CodexAuthProbe = (input: {
|
|
66
|
+
projectDir: string;
|
|
67
|
+
model: string;
|
|
68
|
+
}) => Promise<{
|
|
69
|
+
ok: true;
|
|
70
|
+
} | {
|
|
71
|
+
ok: false;
|
|
72
|
+
message: string;
|
|
73
|
+
fix: string;
|
|
74
|
+
}>;
|
|
65
75
|
interface LocalStatsIngestPerConnection {
|
|
66
76
|
connectionId: string;
|
|
67
77
|
adapter: string;
|
|
@@ -135,6 +145,7 @@ export interface BuildProjectStatusOptions {
|
|
|
135
145
|
env?: NodeJS.ProcessEnv;
|
|
136
146
|
queryHistoryReadinessProbe?: HistoricSqlReadinessProbe;
|
|
137
147
|
claudeCodeAuthProbe?: ClaudeCodeAuthProbe;
|
|
148
|
+
codexAuthProbe?: CodexAuthProbe;
|
|
138
149
|
configIssues?: KtxConfigIssue[];
|
|
139
150
|
fast?: boolean;
|
|
140
151
|
useSpinner?: boolean;
|
package/dist/status-project.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { stat as statAsync, readdir as readdirAsync } from 'node:fs/promises';
|
|
2
2
|
import { basename, join } from 'node:path';
|
|
3
3
|
import { runClaudeCodeAuthProbe } from './context/llm/claude-code-runtime.js';
|
|
4
|
+
import { CODEX_ISOLATION_WARNING, CODEX_ISOLATION_WARNING_FIX, } from './context/llm/codex-isolation.js';
|
|
5
|
+
import { runCodexAuthProbe } from './context/llm/codex-runtime.js';
|
|
4
6
|
import { ktxLocalStateDbPath } from './context/project/local-state-db.js';
|
|
5
7
|
import { isQueryHistoryEnabled, queryHistoryDialectForConnection, } from './context/ingest/adapters/historic-sql/connection-dialect.js';
|
|
6
8
|
import { historicSqlProbeCatalogName, runHistoricSqlReadinessProbe, } from './context/ingest/historic-sql-probes.js';
|
|
@@ -49,6 +51,18 @@ async function buildLlmStatus(config, options) {
|
|
|
49
51
|
fix: 'Run: ktx setup (choose an LLM provider)',
|
|
50
52
|
};
|
|
51
53
|
}
|
|
54
|
+
// The runtime (resolveModelSlots) hard-requires llm.models.default for every
|
|
55
|
+
// non-none backend; without it ingest/scan/memory throw. Report that here so
|
|
56
|
+
// status never marks a project ready that the runtime would refuse to run.
|
|
57
|
+
if (!model || model.trim().length === 0) {
|
|
58
|
+
return {
|
|
59
|
+
backend,
|
|
60
|
+
model,
|
|
61
|
+
status: 'fail',
|
|
62
|
+
detail: `llm.models.default is required for backend "${backend}"`,
|
|
63
|
+
fix: 'Set llm.models.default in ktx.yaml, then rerun `ktx status` (or rerun `ktx setup`).',
|
|
64
|
+
};
|
|
65
|
+
}
|
|
52
66
|
if (backend === 'anthropic') {
|
|
53
67
|
const ref = config.provider.anthropic?.api_key;
|
|
54
68
|
const resolved = resolveRef(ref, env);
|
|
@@ -90,7 +104,7 @@ async function buildLlmStatus(config, options) {
|
|
|
90
104
|
};
|
|
91
105
|
}
|
|
92
106
|
if (backend === 'claude-code') {
|
|
93
|
-
const modelName = model
|
|
107
|
+
const modelName = model;
|
|
94
108
|
if (options.fast === true) {
|
|
95
109
|
return {
|
|
96
110
|
backend,
|
|
@@ -117,6 +131,34 @@ async function buildLlmStatus(config, options) {
|
|
|
117
131
|
fix: 'Authenticate Claude Code locally with the Claude Code CLI, then rerun `ktx status`.',
|
|
118
132
|
};
|
|
119
133
|
}
|
|
134
|
+
if (backend === 'codex') {
|
|
135
|
+
const modelName = model;
|
|
136
|
+
if (options.fast === true) {
|
|
137
|
+
return {
|
|
138
|
+
backend,
|
|
139
|
+
model: modelName,
|
|
140
|
+
status: 'skipped',
|
|
141
|
+
detail: 'auth probe skipped (--fast)',
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const probe = options.codexAuthProbe ?? runCodexAuthProbe;
|
|
145
|
+
const auth = await withSpinner(options.useSpinner === true, 'Probing Codex authentication', () => probe({ projectDir: options.projectDir, model: modelName }));
|
|
146
|
+
if (auth.ok) {
|
|
147
|
+
return {
|
|
148
|
+
backend,
|
|
149
|
+
model: modelName,
|
|
150
|
+
status: 'ok',
|
|
151
|
+
detail: 'local Codex session authenticated',
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
backend,
|
|
156
|
+
model: modelName,
|
|
157
|
+
status: 'fail',
|
|
158
|
+
detail: auth.message,
|
|
159
|
+
fix: auth.fix,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
120
162
|
return { backend, model, status: 'warn', detail: 'unknown LLM backend' };
|
|
121
163
|
}
|
|
122
164
|
function buildEmbeddingsStatus(config, env) {
|
|
@@ -378,6 +420,12 @@ function buildWarnings(config, connections, llm, embeddings) {
|
|
|
378
420
|
fix: formatClaudeCodePromptCachingFix(),
|
|
379
421
|
});
|
|
380
422
|
}
|
|
423
|
+
if (llm.backend === 'codex') {
|
|
424
|
+
warnings.push({
|
|
425
|
+
message: CODEX_ISOLATION_WARNING,
|
|
426
|
+
fix: CODEX_ISOLATION_WARNING_FIX,
|
|
427
|
+
});
|
|
428
|
+
}
|
|
381
429
|
return warnings;
|
|
382
430
|
}
|
|
383
431
|
function buildVerdict(llm, embeddings, connections, queryHistory, warnings) {
|
|
@@ -625,6 +673,7 @@ export async function buildProjectStatus(project, options = {}) {
|
|
|
625
673
|
projectDir: project.projectDir,
|
|
626
674
|
env,
|
|
627
675
|
claudeCodeAuthProbe: options.claudeCodeAuthProbe,
|
|
676
|
+
codexAuthProbe: options.codexAuthProbe,
|
|
628
677
|
fast: options.fast,
|
|
629
678
|
useSpinner: options.useSpinner,
|
|
630
679
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { scrubErrorClass } from './scrubber.js';
|
|
1
|
+
import { formatErrorDetail, scrubErrorClass } from './scrubber.js';
|
|
2
2
|
let activeCommandSpan;
|
|
3
3
|
export function beginCommandSpan(input) {
|
|
4
4
|
activeCommandSpan = input;
|
|
@@ -10,11 +10,13 @@ export function completeCommandSpan(input) {
|
|
|
10
10
|
return undefined;
|
|
11
11
|
}
|
|
12
12
|
const errorClass = input.error ? scrubErrorClass(input.error) : undefined;
|
|
13
|
+
const errorDetail = input.error ? formatErrorDetail(input.error) : undefined;
|
|
13
14
|
return {
|
|
14
15
|
commandPath: span.commandPath,
|
|
15
16
|
durationMs: Math.max(0, input.completedAt - span.startedAt),
|
|
16
17
|
outcome: input.outcome,
|
|
17
18
|
...(errorClass ? { errorClass } : {}),
|
|
19
|
+
...(errorDetail ? { errorDetail } : {}),
|
|
18
20
|
flagsPresent: span.flagsPresent,
|
|
19
21
|
hasProject: span.hasProject,
|
|
20
22
|
projectDir: span.projectDir,
|
|
@@ -15,6 +15,16 @@ export declare function trackTelemetryEvent(input: {
|
|
|
15
15
|
projectApiKey?: string;
|
|
16
16
|
host?: string;
|
|
17
17
|
}): Promise<void>;
|
|
18
|
+
export declare function trackTelemetryException(input: {
|
|
19
|
+
error: Error;
|
|
20
|
+
distinctId: string;
|
|
21
|
+
properties: Record<string, unknown>;
|
|
22
|
+
env?: TelemetryEmitterEnv;
|
|
23
|
+
stderr: TelemetrySink;
|
|
24
|
+
projectApiKey?: string;
|
|
25
|
+
host?: string;
|
|
26
|
+
immediate?: boolean;
|
|
27
|
+
}): Promise<void>;
|
|
18
28
|
export declare function shutdownTelemetryEmitter(): Promise<void>;
|
|
19
29
|
/** @internal */
|
|
20
30
|
export declare function __resetTelemetryEmitterForTests(): void;
|
|
@@ -56,6 +56,37 @@ export async function trackTelemetryEvent(input) {
|
|
|
56
56
|
return;
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
|
+
function writeDebugExceptionPayload(input) {
|
|
60
|
+
input.stderr.write(`[telemetry-exception] ${JSON.stringify({
|
|
61
|
+
distinctId: input.distinctId,
|
|
62
|
+
message: input.error.message,
|
|
63
|
+
name: input.error.name,
|
|
64
|
+
properties: input.properties,
|
|
65
|
+
})}\n`);
|
|
66
|
+
}
|
|
67
|
+
export async function trackTelemetryException(input) {
|
|
68
|
+
const env = input.env ?? process.env;
|
|
69
|
+
if (debugEnabled(env)) {
|
|
70
|
+
writeDebugExceptionPayload(input);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const projectApiKey = telemetryProjectApiKey(input.projectApiKey);
|
|
74
|
+
const host = telemetryHost(env, input.host);
|
|
75
|
+
const client = await getPostHogClient(projectApiKey, host);
|
|
76
|
+
if (!client) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
if (input.immediate) {
|
|
81
|
+
await client.captureExceptionImmediate(input.error, input.distinctId, input.properties);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
client.captureException(input.error, input.distinctId, input.properties);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
59
90
|
export async function shutdownTelemetryEmitter() {
|
|
60
91
|
const client = await clientPromise;
|
|
61
92
|
if (!client) {
|
|
@@ -44,6 +44,7 @@ export declare const telemetryEventSchemas: {
|
|
|
44
44
|
aborted: "aborted";
|
|
45
45
|
}>;
|
|
46
46
|
errorClass: z.ZodOptional<z.ZodString>;
|
|
47
|
+
errorDetail: z.ZodOptional<z.ZodString>;
|
|
47
48
|
flagsPresent: z.ZodRecord<z.ZodString, z.ZodBoolean>;
|
|
48
49
|
hasProject: z.ZodBoolean;
|
|
49
50
|
projectGroupAttached: z.ZodBoolean;
|
|
@@ -67,8 +68,8 @@ export declare const telemetryEventSchemas: {
|
|
|
67
68
|
databases: "databases";
|
|
68
69
|
context: "context";
|
|
69
70
|
runtime: "runtime";
|
|
70
|
-
agents: "agents";
|
|
71
71
|
secrets: "secrets";
|
|
72
|
+
agents: "agents";
|
|
72
73
|
"demo-tour": "demo-tour";
|
|
73
74
|
}>;
|
|
74
75
|
outcome: z.ZodEnum<{
|
|
@@ -77,6 +78,7 @@ export declare const telemetryEventSchemas: {
|
|
|
77
78
|
abandoned: "abandoned";
|
|
78
79
|
}>;
|
|
79
80
|
durationMs: z.ZodNumber;
|
|
81
|
+
errorDetail: z.ZodOptional<z.ZodString>;
|
|
80
82
|
}, z.core.$strict>;
|
|
81
83
|
readonly connection_added: z.ZodObject<{
|
|
82
84
|
cliVersion: z.ZodString;
|
|
@@ -110,6 +112,7 @@ export declare const telemetryEventSchemas: {
|
|
|
110
112
|
error: "error";
|
|
111
113
|
}>;
|
|
112
114
|
errorClass: z.ZodOptional<z.ZodString>;
|
|
115
|
+
errorDetail: z.ZodOptional<z.ZodString>;
|
|
113
116
|
durationMs: z.ZodNumber;
|
|
114
117
|
serverVersion: z.ZodOptional<z.ZodString>;
|
|
115
118
|
}, z.core.$strict>;
|
|
@@ -163,6 +166,7 @@ export declare const telemetryEventSchemas: {
|
|
|
163
166
|
error: "error";
|
|
164
167
|
}>;
|
|
165
168
|
errorClass: z.ZodOptional<z.ZodString>;
|
|
169
|
+
errorDetail: z.ZodOptional<z.ZodString>;
|
|
166
170
|
}, z.core.$strict>;
|
|
167
171
|
readonly scan_completed: z.ZodObject<{
|
|
168
172
|
cliVersion: z.ZodString;
|
|
@@ -186,6 +190,7 @@ export declare const telemetryEventSchemas: {
|
|
|
186
190
|
error: "error";
|
|
187
191
|
}>;
|
|
188
192
|
errorClass: z.ZodOptional<z.ZodString>;
|
|
193
|
+
errorDetail: z.ZodOptional<z.ZodString>;
|
|
189
194
|
}, z.core.$strict>;
|
|
190
195
|
readonly sl_validate_completed: z.ZodObject<{
|
|
191
196
|
cliVersion: z.ZodString;
|
|
@@ -381,6 +386,26 @@ export declare const telemetryEventSchemas: {
|
|
|
381
386
|
errorClass: z.ZodOptional<z.ZodString>;
|
|
382
387
|
durationMs: z.ZodNumber;
|
|
383
388
|
}, z.core.$strict>;
|
|
389
|
+
readonly query_history_filter_completed: z.ZodObject<{
|
|
390
|
+
cliVersion: z.ZodString;
|
|
391
|
+
nodeVersion: z.ZodString;
|
|
392
|
+
osPlatform: z.ZodString;
|
|
393
|
+
osRelease: z.ZodString;
|
|
394
|
+
arch: z.ZodString;
|
|
395
|
+
runtime: z.ZodEnum<{
|
|
396
|
+
node: "node";
|
|
397
|
+
"daemon-py": "daemon-py";
|
|
398
|
+
}>;
|
|
399
|
+
isCi: z.ZodBoolean;
|
|
400
|
+
dialect: z.ZodString;
|
|
401
|
+
consideredRoleCount: z.ZodNumber;
|
|
402
|
+
excludedRoleCount: z.ZodNumber;
|
|
403
|
+
parseFailedCount: z.ZodNumber;
|
|
404
|
+
outcome: z.ZodEnum<{
|
|
405
|
+
ok: "ok";
|
|
406
|
+
error: "error";
|
|
407
|
+
}>;
|
|
408
|
+
}, z.core.$strict>;
|
|
384
409
|
};
|
|
385
410
|
/** @internal */
|
|
386
411
|
export declare const telemetryEventCatalog: readonly [{
|
|
@@ -390,11 +415,11 @@ export declare const telemetryEventCatalog: readonly [{
|
|
|
390
415
|
}, {
|
|
391
416
|
readonly name: "command";
|
|
392
417
|
readonly description: "Emitted once for each Commander action that reaches preAction.";
|
|
393
|
-
readonly fields: readonly ["commandPath", "durationMs", "outcome", "errorClass", "flagsPresent", "hasProject", "projectGroupAttached"];
|
|
418
|
+
readonly fields: readonly ["commandPath", "durationMs", "outcome", "errorClass", "errorDetail", "flagsPresent", "hasProject", "projectGroupAttached"];
|
|
394
419
|
}, {
|
|
395
420
|
readonly name: "setup_step";
|
|
396
421
|
readonly description: "Emitted after an interactive setup step completes, skips, or aborts.";
|
|
397
|
-
readonly fields: readonly ["step", "outcome", "durationMs"];
|
|
422
|
+
readonly fields: readonly ["step", "outcome", "durationMs", "errorDetail"];
|
|
398
423
|
}, {
|
|
399
424
|
readonly name: "connection_added";
|
|
400
425
|
readonly description: "Emitted when setup writes a database, source, or demo connection.";
|
|
@@ -402,7 +427,7 @@ export declare const telemetryEventCatalog: readonly [{
|
|
|
402
427
|
}, {
|
|
403
428
|
readonly name: "connection_test";
|
|
404
429
|
readonly description: "Emitted after ktx connection test completes.";
|
|
405
|
-
readonly fields: readonly ["driver", "isDemoConnection", "outcome", "errorClass", "durationMs", "serverVersion"];
|
|
430
|
+
readonly fields: readonly ["driver", "isDemoConnection", "outcome", "errorClass", "errorDetail", "durationMs", "serverVersion"];
|
|
406
431
|
}, {
|
|
407
432
|
readonly name: "project_stack_snapshot";
|
|
408
433
|
readonly description: "Emitted after commands that can summarize the local project stack.";
|
|
@@ -410,11 +435,11 @@ export declare const telemetryEventCatalog: readonly [{
|
|
|
410
435
|
}, {
|
|
411
436
|
readonly name: "ingest_completed";
|
|
412
437
|
readonly description: "Emitted after a public ingest target completes.";
|
|
413
|
-
readonly fields: readonly ["driver", "isDemoConnection", "schemaCount", "tableCount", "columnCount", "rowsBucket", "durationMs", "outcome", "errorClass"];
|
|
438
|
+
readonly fields: readonly ["driver", "isDemoConnection", "schemaCount", "tableCount", "columnCount", "rowsBucket", "durationMs", "outcome", "errorClass", "errorDetail"];
|
|
414
439
|
}, {
|
|
415
440
|
readonly name: "scan_completed";
|
|
416
441
|
readonly description: "Emitted after schema scan or relationship inference completes.";
|
|
417
|
-
readonly fields: readonly ["driver", "tableCount", "columnCount", "inferredFkCount", "declaredFkCount", "durationMs", "outcome", "errorClass"];
|
|
442
|
+
readonly fields: readonly ["driver", "tableCount", "columnCount", "inferredFkCount", "declaredFkCount", "durationMs", "outcome", "errorClass", "errorDetail"];
|
|
418
443
|
}, {
|
|
419
444
|
readonly name: "sl_validate_completed";
|
|
420
445
|
readonly description: "Emitted after ktx sl validate completes.";
|
|
@@ -451,6 +476,10 @@ export declare const telemetryEventCatalog: readonly [{
|
|
|
451
476
|
readonly name: "sql_gen_completed";
|
|
452
477
|
readonly description: "Emitted after daemon SQL generation completes.";
|
|
453
478
|
readonly fields: readonly ["outcome", "dialect", "errorClass", "durationMs"];
|
|
479
|
+
}, {
|
|
480
|
+
readonly name: "query_history_filter_completed";
|
|
481
|
+
readonly description: "Emitted after the setup query-history service-account filter picker runs.";
|
|
482
|
+
readonly fields: readonly ["dialect", "consideredRoleCount", "excludedRoleCount", "parseFailedCount", "outcome"];
|
|
454
483
|
}];
|
|
455
484
|
export type TelemetryEventName = keyof typeof telemetryEventSchemas;
|
|
456
485
|
export type TelemetryCommonEnvelope = z.infer<typeof telemetryCommonEnvelopeSchema>;
|
package/dist/telemetry/events.js
CHANGED
|
@@ -18,6 +18,7 @@ const commandSchema = telemetryCommonEnvelopeSchema
|
|
|
18
18
|
durationMs: z.number().nonnegative(),
|
|
19
19
|
outcome: z.enum(['ok', 'error', 'aborted']),
|
|
20
20
|
errorClass: z.string().optional(),
|
|
21
|
+
errorDetail: z.string().max(1000).optional(),
|
|
21
22
|
flagsPresent: z.record(z.string(), z.boolean()),
|
|
22
23
|
hasProject: z.boolean(),
|
|
23
24
|
projectGroupAttached: z.boolean(),
|
|
@@ -40,6 +41,7 @@ const setupStepSchema = telemetryCommonEnvelopeSchema
|
|
|
40
41
|
]),
|
|
41
42
|
outcome: z.enum(['completed', 'skipped', 'abandoned']),
|
|
42
43
|
durationMs: z.number().nonnegative(),
|
|
44
|
+
errorDetail: z.string().max(1000).optional(),
|
|
43
45
|
})
|
|
44
46
|
.strict();
|
|
45
47
|
const connectionAddedSchema = telemetryCommonEnvelopeSchema
|
|
@@ -54,6 +56,7 @@ const connectionTestSchema = telemetryCommonEnvelopeSchema
|
|
|
54
56
|
isDemoConnection: z.boolean(),
|
|
55
57
|
outcome: outcomeSchema,
|
|
56
58
|
errorClass: z.string().optional(),
|
|
59
|
+
errorDetail: z.string().max(1000).optional(),
|
|
57
60
|
durationMs: z.number().nonnegative(),
|
|
58
61
|
serverVersion: z.string().optional(),
|
|
59
62
|
})
|
|
@@ -80,6 +83,7 @@ const ingestCompletedSchema = telemetryCommonEnvelopeSchema
|
|
|
80
83
|
durationMs: z.number().nonnegative(),
|
|
81
84
|
outcome: outcomeSchema,
|
|
82
85
|
errorClass: z.string().optional(),
|
|
86
|
+
errorDetail: z.string().max(1000).optional(),
|
|
83
87
|
})
|
|
84
88
|
.strict();
|
|
85
89
|
const scanCompletedSchema = telemetryCommonEnvelopeSchema
|
|
@@ -92,6 +96,7 @@ const scanCompletedSchema = telemetryCommonEnvelopeSchema
|
|
|
92
96
|
durationMs: z.number().nonnegative(),
|
|
93
97
|
outcome: outcomeSchema,
|
|
94
98
|
errorClass: z.string().optional(),
|
|
99
|
+
errorDetail: z.string().max(1000).optional(),
|
|
95
100
|
})
|
|
96
101
|
.strict();
|
|
97
102
|
const slValidateCompletedSchema = telemetryCommonEnvelopeSchema
|
|
@@ -180,6 +185,15 @@ const sqlGenCompletedSchema = telemetryCommonEnvelopeSchema
|
|
|
180
185
|
durationMs: z.number().nonnegative(),
|
|
181
186
|
})
|
|
182
187
|
.strict();
|
|
188
|
+
const queryHistoryFilterCompletedSchema = telemetryCommonEnvelopeSchema
|
|
189
|
+
.extend({
|
|
190
|
+
dialect: z.string(),
|
|
191
|
+
consideredRoleCount: z.number().int().nonnegative(),
|
|
192
|
+
excludedRoleCount: z.number().int().nonnegative(),
|
|
193
|
+
parseFailedCount: z.number().int().nonnegative(),
|
|
194
|
+
outcome: outcomeSchema,
|
|
195
|
+
})
|
|
196
|
+
.strict();
|
|
183
197
|
/** @internal */
|
|
184
198
|
export const telemetryEventSchemas = {
|
|
185
199
|
install_first_run: installFirstRunSchema,
|
|
@@ -199,6 +213,7 @@ export const telemetryEventSchemas = {
|
|
|
199
213
|
daemon_stopped: daemonStoppedSchema,
|
|
200
214
|
sl_plan_completed: slPlanCompletedSchema,
|
|
201
215
|
sql_gen_completed: sqlGenCompletedSchema,
|
|
216
|
+
query_history_filter_completed: queryHistoryFilterCompletedSchema,
|
|
202
217
|
};
|
|
203
218
|
/** @internal */
|
|
204
219
|
export const telemetryEventCatalog = [
|
|
@@ -215,6 +230,7 @@ export const telemetryEventCatalog = [
|
|
|
215
230
|
'durationMs',
|
|
216
231
|
'outcome',
|
|
217
232
|
'errorClass',
|
|
233
|
+
'errorDetail',
|
|
218
234
|
'flagsPresent',
|
|
219
235
|
'hasProject',
|
|
220
236
|
'projectGroupAttached',
|
|
@@ -223,7 +239,7 @@ export const telemetryEventCatalog = [
|
|
|
223
239
|
{
|
|
224
240
|
name: 'setup_step',
|
|
225
241
|
description: 'Emitted after an interactive setup step completes, skips, or aborts.',
|
|
226
|
-
fields: ['step', 'outcome', 'durationMs'],
|
|
242
|
+
fields: ['step', 'outcome', 'durationMs', 'errorDetail'],
|
|
227
243
|
},
|
|
228
244
|
{
|
|
229
245
|
name: 'connection_added',
|
|
@@ -233,7 +249,7 @@ export const telemetryEventCatalog = [
|
|
|
233
249
|
{
|
|
234
250
|
name: 'connection_test',
|
|
235
251
|
description: 'Emitted after ktx connection test completes.',
|
|
236
|
-
fields: ['driver', 'isDemoConnection', 'outcome', 'errorClass', 'durationMs', 'serverVersion'],
|
|
252
|
+
fields: ['driver', 'isDemoConnection', 'outcome', 'errorClass', 'errorDetail', 'durationMs', 'serverVersion'],
|
|
237
253
|
},
|
|
238
254
|
{
|
|
239
255
|
name: 'project_stack_snapshot',
|
|
@@ -253,6 +269,7 @@ export const telemetryEventCatalog = [
|
|
|
253
269
|
'durationMs',
|
|
254
270
|
'outcome',
|
|
255
271
|
'errorClass',
|
|
272
|
+
'errorDetail',
|
|
256
273
|
],
|
|
257
274
|
},
|
|
258
275
|
{
|
|
@@ -267,6 +284,7 @@ export const telemetryEventCatalog = [
|
|
|
267
284
|
'durationMs',
|
|
268
285
|
'outcome',
|
|
269
286
|
'errorClass',
|
|
287
|
+
'errorDetail',
|
|
270
288
|
],
|
|
271
289
|
},
|
|
272
290
|
{
|
|
@@ -330,6 +348,11 @@ export const telemetryEventCatalog = [
|
|
|
330
348
|
description: 'Emitted after daemon SQL generation completes.',
|
|
331
349
|
fields: ['outcome', 'dialect', 'errorClass', 'durationMs'],
|
|
332
350
|
},
|
|
351
|
+
{
|
|
352
|
+
name: 'query_history_filter_completed',
|
|
353
|
+
description: 'Emitted after the setup query-history service-account filter picker runs.',
|
|
354
|
+
fields: ['dialect', 'consideredRoleCount', 'excludedRoleCount', 'parseFailedCount', 'outcome'],
|
|
355
|
+
},
|
|
333
356
|
];
|
|
334
357
|
export function buildCommonEnvelope(input) {
|
|
335
358
|
return {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type KtxCliIo, type KtxCliPackageInfo } from '../cli-runtime.js';
|
|
2
|
+
export interface ExceptionContext {
|
|
3
|
+
source: string;
|
|
4
|
+
handled: boolean;
|
|
5
|
+
fatal: boolean;
|
|
6
|
+
extra?: Record<string, string | number | boolean>;
|
|
7
|
+
}
|
|
8
|
+
export declare function reportException(input: {
|
|
9
|
+
error: unknown;
|
|
10
|
+
context: ExceptionContext;
|
|
11
|
+
io: KtxCliIo;
|
|
12
|
+
packageInfo?: KtxCliPackageInfo;
|
|
13
|
+
projectDir?: string;
|
|
14
|
+
immediate?: boolean;
|
|
15
|
+
redactionSecrets?: ReadonlyArray<string>;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
/** @internal */
|
|
18
|
+
export declare function __resetTelemetryExceptionStateForTests(): void;
|