chore: add TypeScript dead-code checks (#60)

* chore: add TypeScript dead-code checks

* chore: trim stale Knip ignores

* Fix CI smoke and artifact checks
This commit is contained in:
Andrey Avtomonov 2026-05-13 13:33:28 +02:00 committed by GitHub
parent 721f1a998f
commit bcb0d2f8f7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
29 changed files with 818 additions and 220 deletions

View file

@ -37,6 +37,9 @@ jobs:
- name: Install TypeScript dependencies - name: Install TypeScript dependencies
run: pnpm install --frozen-lockfile run: pnpm install --frozen-lockfile
- name: Run TypeScript dead-code checks
run: pnpm run dead-code
- name: Run TypeScript checks - name: Run TypeScript checks
run: pnpm run check run: pnpm run check

View file

@ -33,6 +33,19 @@ repos:
name: ruff format (python) name: ruff format (python)
files: ^python/ files: ^python/
- repo: local
hooks:
- id: biome-dead-code
name: biome dead-code check
entry: pnpm exec biome ci . --formatter-enabled=false --assist-enabled=false
language: system
pass_filenames: false
- id: knip-dead-code
name: knip dead-code check
entry: pnpm exec knip --reporter compact
language: system
pass_filenames: false
- repo: https://github.com/Yelp/detect-secrets - repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0 rev: v1.5.0
hooks: hooks:

View file

@ -86,6 +86,7 @@ pnpm run build
pnpm run type-check pnpm run type-check
pnpm run test pnpm run test
pnpm run check pnpm run check
pnpm run dead-code
pnpm --filter @ktx/cli run smoke pnpm --filter @ktx/cli run smoke
pnpm --filter './packages/*' run build pnpm --filter './packages/*' run build
pnpm --filter './packages/*' run test pnpm --filter './packages/*' run test
@ -127,6 +128,7 @@ shared contracts or package exports are affected.
- Build/export changes: `pnpm run build` - Build/export changes: `pnpm run build`
- Workspace scripts: `node --test scripts/*.test.mjs` or the specific script - Workspace scripts: `node --test scripts/*.test.mjs` or the specific script
test file test file
- TypeScript dead-code tooling/config changes: `pnpm run dead-code`
- Python semantic layer: `uv run pytest python/ktx-sl/tests -q` - Python semantic layer: `uv run pytest python/ktx-sl/tests -q`
- Python daemon: `uv run pytest python/ktx-daemon/tests -q` - Python daemon: `uv run pytest python/ktx-daemon/tests -q`
- Python files: also run `uv run pre-commit run --files [FILES]` when - Python files: also run `uv run pre-commit run --files [FILES]` when
@ -156,6 +158,23 @@ pnpm run test 2>&1 | tee /tmp/ktx-test-output.log
- Do not manually edit generated or built output under `dist/`; edit source and - Do not manually edit generated or built output under `dist/`; edit source and
rebuild. rebuild.
### Dead TypeScript Code Checks
KTX uses Biome for local unused-code linting and Knip for workspace graph
analysis. These checks are intentionally part of CI and pre-commit because the
normal development workflow is agent-based.
- Run `pnpm run dead-code` after TypeScript changes.
- Treat Knip findings as investigation prompts, not automatic deletion orders.
- Remove private dead code when you confirm there are no imports, dynamic
references, generated references, or tests that still need it.
- Preserve public package exports unless the task explicitly includes API
pruning.
- Add narrow `knip.json` ignores only for intentional dynamic or public cases.
Do not add broad package-level ignores to silence unrelated findings.
- Update `knip.json` when adding dynamic entrypoints, generated files, package
exports, CLI bins, or framework files that Knip cannot infer.
### CLI Standards ### CLI Standards
- Use Commander for CLI command trees, arguments, options, help text, custom - Use Commander for CLI command trees, arguments, options, help text, custom

36
biome.json Normal file
View file

@ -0,0 +1,36 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.15/schema.json",
"assist": {
"enabled": false
},
"formatter": {
"enabled": false
},
"files": {
"includes": [
"scripts/**/*.mjs",
"packages/**/*.ts",
"packages/**/*.tsx",
"docs-site/**/*.ts",
"docs-site/**/*.tsx",
"docs-site/**/*.mjs",
"!**/dist/**",
"!**/coverage/**",
"!**/.next/**",
"!**/node_modules/**",
"!**/*.gen.ts",
"!**/*.generated.ts"
]
},
"linter": {
"enabled": true,
"rules": {
"recommended": false,
"correctness": {
"noUnusedImports": "error",
"noUnusedVariables": "error",
"noUnusedPrivateClassMembers": "error"
}
}
}
}

114
knip.json Normal file
View file

@ -0,0 +1,114 @@
{
"$schema": "https://unpkg.com/knip@6/schema.json",
"workspaces": {
".": {
"entry": ["scripts/**/*.mjs"],
"project": ["scripts/**/*.mjs"]
},
"packages/cli": {
"entry": [
"src/index.ts",
"src/bin.ts",
"src/**/*.test.ts",
"src/**/*.test.tsx",
"scripts/**/*.mjs"
],
"project": ["src/**/*.{ts,tsx}", "scripts/**/*.mjs", "vitest.config.ts"]
},
"packages/context": {
"entry": [
"src/index.ts",
"src/agent/index.ts",
"src/core/index.ts",
"src/connections/index.ts",
"src/daemon/index.ts",
"src/ingest/index.ts",
"src/ingest/memory-flow/index.ts",
"src/ingest/metabase-mapping.ts",
"src/scan/index.ts",
"src/search/index.ts",
"src/sql-analysis/index.ts",
"src/memory/index.ts",
"src/mcp/index.ts",
"src/project/index.ts",
"src/prompts/index.ts",
"src/skills/index.ts",
"src/sl/index.ts",
"src/sl/descriptions.ts",
"src/tools/index.ts",
"src/wiki/index.ts",
"src/**/*.test.ts",
"scripts/**/*.mjs"
],
"project": ["src/**/*.ts", "scripts/**/*.mjs", "vitest.config.ts"]
},
"packages/llm": {
"entry": ["src/index.ts", "src/**/*.test.ts"],
"project": ["src/**/*.ts", "vitest.config.ts"]
},
"packages/connector-*": {
"entry": ["src/index.ts", "src/**/*.test.ts"],
"project": ["src/**/*.ts"]
},
"docs-site": {
"entry": [
"app/**/*.{ts,tsx}",
"components/**/*.{ts,tsx}",
"lib/**/*.{ts,tsx}",
"middleware.ts",
"next.config.mjs",
"source.config.ts",
"tests/**/*.mjs"
],
"project": [
"app/**/*.{ts,tsx}",
"components/**/*.{ts,tsx}",
"lib/**/*.{ts,tsx}",
"*.ts",
"*.mjs",
"tests/**/*.mjs"
],
"ignoreDependencies": ["tailwindcss"]
}
},
"ignore": [
"**/dist/**",
"**/coverage/**",
"**/.next/**",
"**/node_modules/**",
"**/*.gen.ts",
"**/*.generated.ts"
],
"ignoreIssues": {
"packages/cli/src/clack.ts": ["exports"],
"packages/cli/src/commands/connection-metabase-setup.ts": ["exports", "types"],
"packages/cli/src/ingest.test-utils.ts": ["exports"],
"packages/cli/src/io/symbols.ts": ["exports"],
"packages/cli/src/managed-python-command.ts": ["types"],
"packages/cli/src/managed-python-daemon.ts": ["types"],
"packages/cli/src/managed-python-http.ts": ["exports", "types"],
"packages/cli/src/managed-python-runtime.ts": ["types"],
"packages/cli/src/memory-flow-tui.tsx": ["types"],
"packages/cli/src/next-steps.ts": ["exports"],
"packages/cli/src/print-command-tree.ts": ["exports"],
"packages/cli/src/setup-agents.ts": ["exports", "types"],
"packages/cli/src/setup-context.ts": ["types"],
"packages/cli/src/setup-demo-tour.ts": ["exports"],
"packages/cli/src/setup-models.ts": ["exports"],
"packages/cli/src/setup-project.ts": ["types"],
"packages/cli/src/setup-ready-menu.ts": ["types"],
"packages/cli/src/setup-sources.ts": ["types"],
"packages/context/src/ingest/adapters/historic-sql/pattern-inputs.ts": ["exports", "types"],
"packages/context/src/ingest/adapters/lookml/pull-config.ts": ["exports"],
"packages/context/src/ingest/adapters/metabase/serialize-card.ts": ["types"],
"packages/context/src/ingest/adapters/metabase/types.ts": ["exports"],
"packages/context/src/ingest/adapters/metricflow/parse.ts": ["types"],
"packages/context/src/ingest/ports.ts": ["types"],
"packages/context/src/ingest/stages/stage-3-work-units.ts": ["types"],
"packages/context/src/ingest/stages/stage-index.types.ts": ["types"],
"packages/context/src/project/config.ts": ["types"],
"packages/context/src/scan/relationship-candidates.ts": ["types"],
"packages/context/src/scan/relationship-diagnostics.ts": ["types"],
"packages/context/src/tools/context-evidence-tool-store.ts": ["types"]
}
}

View file

@ -18,6 +18,10 @@
"artifacts:verify-manifest": "node scripts/package-artifacts.mjs verify-manifest", "artifacts:verify-manifest": "node scripts/package-artifacts.mjs verify-manifest",
"build": "pnpm --filter './packages/*' run build", "build": "pnpm --filter './packages/*' run build",
"check": "node scripts/check-boundaries.mjs && node --test scripts/*.test.mjs && pnpm --filter './packages/*' run build && pnpm --filter './packages/*' run test", "check": "node scripts/check-boundaries.mjs && node --test scripts/*.test.mjs && pnpm --filter './packages/*' run build && pnpm --filter './packages/*' run test",
"dead-code": "pnpm run dead-code:biome && pnpm run dead-code:knip",
"dead-code:biome": "biome ci . --formatter-enabled=false --assist-enabled=false",
"dead-code:fix": "biome check . --formatter-enabled=false --assist-enabled=false --write && knip --fix --format",
"dead-code:knip": "knip --reporter compact",
"ktx": "node scripts/run-ktx.mjs", "ktx": "node scripts/run-ktx.mjs",
"link:dev": "node scripts/link-dev-cli.mjs", "link:dev": "node scripts/link-dev-cli.mjs",
"native:rebuild": "pnpm -r rebuild better-sqlite3", "native:rebuild": "pnpm -r rebuild better-sqlite3",
@ -36,9 +40,12 @@
"type-check": "pnpm --filter './packages/*' run type-check" "type-check": "pnpm --filter './packages/*' run type-check"
}, },
"devDependencies": { "devDependencies": {
"@biomejs/biome": "^2.4.15",
"@types/node": "^25.7.0", "@types/node": "^25.7.0",
"better-sqlite3": "^12.10.0",
"knip": "^6.12.2",
"typescript": "^6.0.3", "typescript": "^6.0.3",
"vitest": "^4.1.6" "yaml": "^2.9.0"
}, },
"pnpm": { "pnpm": {
"onlyBuiltDependencies": [ "onlyBuiltDependencies": [

View file

@ -188,7 +188,7 @@ export function registerConnectionCommands(program: Command, context: KtxCliComm
registerConnectionNotionCommands(connection, context); registerConnectionNotionCommands(connection, context);
} }
export function registerConnectionMappingCommands(connection: Command, context: KtxCliCommandContext): void { function registerConnectionMappingCommands(connection: Command, context: KtxCliCommandContext): void {
const mapping = connection const mapping = connection
.command('mapping') .command('mapping')
.description('Manage Metabase warehouse mappings') .description('Manage Metabase warehouse mappings')

View file

@ -369,14 +369,6 @@ function setExpanded(state: PickerState, nodeId: string, value: boolean | 'toggl
return cloneState(state, { expanded }); return cloneState(state, { expanded });
} }
function expandPath(state: PickerState, nodeId: string): PickerState {
const expanded = new Set(state.expanded);
for (const ancestorId of ancestorsOf(nodeId, state.byId)) {
expanded.add(ancestorId);
}
return cloneState(state, { expanded });
}
export function moveCursor(state: PickerState, dir: 'up' | 'down' | 'left' | 'right'): PickerState { export function moveCursor(state: PickerState, dir: 'up' | 'down' | 'left' | 'right'): PickerState {
const node = state.byId.get(state.cursorId); const node = state.byId.get(state.cursorId);
if (!node) { if (!node) {

View file

@ -1,6 +1,6 @@
/* @jsxImportSource react */ /* @jsxImportSource react */
import { render as renderInkTest } from 'ink-testing-library'; import { render as renderInkTest } from 'ink-testing-library';
import React, { act, type ReactNode } from 'react'; import { act, type ReactNode } from 'react';
import { afterEach, describe, expect, it, vi } from 'vitest'; import { afterEach, describe, expect, it, vi } from 'vitest';
import { buildInitialState, buildPickerTree, type NotionPickerPageInput } from './connection-notion-tree.js'; import { buildInitialState, buildPickerTree, type NotionPickerPageInput } from './connection-notion-tree.js';
import { import {

View file

@ -1,6 +1,6 @@
/* @jsxImportSource react */ /* @jsxImportSource react */
import { Box, Text, render as renderInkRuntime, useApp, useInput } from 'ink'; import { Box, Text, render as renderInkRuntime, useApp, useInput } from 'ink';
import React, { type ReactNode, useEffect, useMemo, useRef, useState } from 'react'; import { type ReactNode, useEffect, useMemo, useRef, useState } from 'react';
import { import {
filterTree, filterTree,
flattenSelection, flattenSelection,

View file

@ -1,4 +1,4 @@
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; import { mkdtemp, rm } from 'node:fs/promises';
import { createRequire } from 'node:module'; import { createRequire } from 'node:module';
import { tmpdir } from 'node:os'; import { tmpdir } from 'node:os';
import { join } from 'node:path'; import { join } from 'node:path';

View file

@ -1,10 +1,8 @@
import { EventEmitter } from 'node:events'; import { EventEmitter } from 'node:events';
import { access, mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; import { mkdir, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path'; import { join } from 'node:path';
import { AgentRunnerService, type RunLoopParams } from '@ktx/context/agent'; import { AgentRunnerService, type RunLoopParams } from '@ktx/context/agent';
import { import {
LocalLookerRuntimeStore,
LocalMetabaseSourceStateReader, LocalMetabaseSourceStateReader,
MetabaseSourceAdapter, MetabaseSourceAdapter,
getLocalIngestStatus, getLocalIngestStatus,
@ -12,12 +10,10 @@ import {
type FetchContext, type FetchContext,
type IngestReportSnapshot, type IngestReportSnapshot,
type LocalIngestResult, type LocalIngestResult,
type LocalMetabaseFanoutProgress,
type LookerMappingClient, type LookerMappingClient,
type LookerRuntimeClient, type LookerRuntimeClient,
type LookerTableIdentifierParser, type LookerTableIdentifierParser,
type MemoryFlowEventSink, type MemoryFlowEventSink,
type MemoryFlowReplayInput,
type MetabaseCard, type MetabaseCard,
type MetabaseCardSummary, type MetabaseCardSummary,
type MetabaseClientFactory, type MetabaseClientFactory,
@ -28,7 +24,7 @@ import {
} from '@ktx/context/ingest'; } from '@ktx/context/ingest';
import { ktxLocalStateDbPath, loadKtxProject } from '@ktx/context/project'; import { ktxLocalStateDbPath, loadKtxProject } from '@ktx/context/project';
import { expect, vi } from 'vitest'; import { expect, vi } from 'vitest';
import { type KtxIngestArgs, runKtxIngest } from './ingest.js'; import { runKtxIngest } from './ingest.js';
export function makeIo( export function makeIo(
options: { options: {

View file

@ -4,10 +4,8 @@ import { join } from 'node:path';
import { import {
LocalLookerRuntimeStore, LocalLookerRuntimeStore,
LocalMetabaseSourceStateReader, LocalMetabaseSourceStateReader,
getLocalIngestStatus,
type LocalIngestResult, type LocalIngestResult,
type LocalMetabaseFanoutProgress, type LocalMetabaseFanoutProgress,
type MemoryFlowReplayInput,
type RunLocalIngestOptions, type RunLocalIngestOptions,
type SourceAdapter, type SourceAdapter,
} from '@ktx/context/ingest'; } from '@ktx/context/ingest';
@ -20,7 +18,6 @@ import {
CliMetabaseAgentRunner, CliMetabaseAgentRunner,
CliMetabaseSourceAdapter, CliMetabaseSourceAdapter,
completedLocalBundleRun, completedLocalBundleRun,
emitLiveLocalMemoryFlow,
failedLocalBundleRun, failedLocalBundleRun,
localFakeBundleReport, localFakeBundleReport,
makeCliLookerParser, makeCliLookerParser,
@ -28,7 +25,6 @@ import {
makeIo, makeIo,
persistLocalBundleReport, persistLocalBundleReport,
runPublicMetabaseSyncModeCase, runPublicMetabaseSyncModeCase,
writeBundleReportFile,
writeMetabaseConfig, writeMetabaseConfig,
writeWarehouseConfig, writeWarehouseConfig,
} from './ingest.test-utils.js'; } from './ingest.test-utils.js';

View file

@ -1,7 +1,7 @@
/* @jsxImportSource react */ /* @jsxImportSource react */
import type { MemoryFlowEvent, MemoryFlowReplayInput } from '@ktx/context/ingest/memory-flow'; import type { MemoryFlowEvent, MemoryFlowReplayInput } from '@ktx/context/ingest/memory-flow';
import { Box, Text } from 'ink'; import { Box, Text } from 'ink';
import React, { type ReactNode } from 'react'; import { type ReactNode } from 'react';
import { buildDemoMetrics, formatCost, formatDuration } from './demo-metrics.js'; import { buildDemoMetrics, formatCost, formatDuration } from './demo-metrics.js';
import { formatNextStepLines } from './next-steps.js'; import { formatNextStepLines } from './next-steps.js';
import { profileMark } from './startup-profile.js'; import { profileMark } from './startup-profile.js';
@ -38,45 +38,6 @@ function isPrepopulatedDemoReplay(input: MemoryFlowReplayInput): boolean {
return input.metadata?.origin === 'packaged' || input.metadata?.timing === 'prebuilt'; return input.metadata?.origin === 'packaged' || input.metadata?.timing === 'prebuilt';
} }
function flowLine(width: number, frame: number, active: boolean): string {
if (!active) return '━'.repeat(width);
const pulse = ['░', '▒', '▓', '█', '█', '█', '▓', '▒', '░'];
const pw = pulse.length;
const chars: string[] = [];
const offset = (frame * 2) % (width + pw);
for (let i = 0; i < width; i += 1) {
const p = i - offset + pw;
chars.push(p >= 0 && p < pw ? (pulse[p] ?? '━') : '━');
}
return chars.join('');
}
function brailleFlow(width: number, frame: number): string {
// Braille unicode: U+2800 + dot bitmask
// Dots: 1=0x01 2=0x02 3=0x04 4=0x08 5=0x10 6=0x20 7=0x40 8=0x80
// Layout: col0=[1,2,3,7] col1=[4,5,6,8]
const chars: string[] = [];
for (let i = 0; i < width; i += 1) {
const density = (i + 1) / width;
const phase = (i * 3 + frame * 2) % 12;
let dots = 0;
// Sparse diagonal streams on the left, dense on the right
// Each "stream" is a diagonal line of dots moving rightward
if ((phase + 0) % 4 < density * 4) dots |= 0x01; // dot 1
if ((phase + 1) % 5 < density * 4) dots |= 0x08; // dot 4
if ((phase + 2) % 4 < density * 3) dots |= 0x02; // dot 2
if ((phase + 3) % 5 < density * 3) dots |= 0x10; // dot 5
if ((phase + 4) % 4 < density * 2.5) dots |= 0x04; // dot 3
if ((phase + 5) % 5 < density * 2.5) dots |= 0x20; // dot 6
if ((phase + 1) % 6 < density * 2) dots |= 0x40; // dot 7
if ((phase + 3) % 6 < density * 2) dots |= 0x80; // dot 8
chars.push(String.fromCharCode(0x2800 + dots));
}
return chars.join('');
}
function progressBarOverall( function progressBarOverall(
finishedCount: number, finishedCount: number,
activeCount: number, activeCount: number,
@ -104,43 +65,6 @@ function progressBarOverall(
return finished + activeChars.join('') + '░'.repeat(queuedWidth); return finished + activeChars.join('') + '░'.repeat(queuedWidth);
} }
function sparkleWipe(width: number, frame: number, row: number): string {
const chars: string[] = [];
const sweepPos = (frame * 2 + row * 6) % (width + 8);
const sparkles = ['✨', '✦', '✧', '·'];
for (let i = 0; i < width; i += 1) {
const dist = i - sweepPos;
if (dist < -6) {
const t = (i * 11 + row * 5 + frame * 3) % 10;
chars.push(t === 0 ? sparkles[0]! : t === 3 ? sparkles[1]! : t === 7 ? sparkles[2]! : ' ');
} else if (dist < -3) {
const t = (i + frame) % 3;
chars.push(t === 0 ? sparkles[1]! : t === 1 ? sparkles[2]! : sparkles[3]!);
} else if (dist <= 0) {
const gradient = ['░', '▒', '▓', '█'];
chars.push(gradient[Math.min(3, dist + 3)] ?? '█');
} else if (dist <= 2) {
chars.push(dist === 1 ? '▓' : '▒');
} else {
const noise = (i * 31 + row * 17 + frame * 3) % 5;
const messy = ['░', '▒', '▓', '▒', '░'];
chars.push(messy[noise] ?? '▒');
}
}
return chars.join('');
}
function activityWave(width: number, frame: number, offset: number): string {
const heights = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
const chars: string[] = [];
for (let i = 0; i < width; i += 1) {
const wave = Math.sin(((i * 2 + frame + offset * 5) * Math.PI) / 6);
const idx = Math.round(((wave + 1) / 2) * (heights.length - 1));
chars.push(heights[idx] ?? '▁');
}
return chars.join('');
}
function topicName(key: string): string { function topicName(key: string): string {
return (key.split('/').pop()?.replace(/\.md$/, '') ?? key).replace(/[_-]/g, ' '); return (key.split('/').pop()?.replace(/\.md$/, '') ?? key).replace(/[_-]/g, ' ');
} }
@ -155,18 +79,9 @@ function humanizeInsight(key: string, target: 'sl' | 'wiki', summary: string | u
return target === 'sl' ? `Query definition: ${name}` : `Knowledge page: ${name}`; return target === 'sl' ? `Query definition: ${name}` : `Knowledge page: ${name}`;
} }
const ADAPTER_PREFIXES = ['live_database_', 'metabase_', 'looker_', 'lookml_', 'metricflow_', 'notion_', 'historic_sql_', 'dbt_descriptions_'];
const INTERNAL_DEMO_CONNECTION_ID = 'orbit_demo'; const INTERNAL_DEMO_CONNECTION_ID = 'orbit_demo';
const PUBLIC_DEMO_SOURCE_LABEL = 'Orbit Demo'; const PUBLIC_DEMO_SOURCE_LABEL = 'Orbit Demo';
function humanizeUnitKey(unitKey: string): string {
let key = unitKey.replace(/-/g, '_');
for (const prefix of ADAPTER_PREFIXES) {
if (key.startsWith(prefix)) { key = key.slice(prefix.length); break; }
}
return key.replace(/_/g, ' ');
}
interface SourceInfo { interface SourceInfo {
type: string; type: string;
name: string; name: string;
@ -224,13 +139,6 @@ function sourceDescription(input: MemoryFlowReplayInput): SourceInfo {
return { type: info.type, name: conn, sourceCount: count, itemNounPlural: info.plural, readingVerb: info.verb, ingestDescription: info.description }; return { type: info.type, name: conn, sourceCount: count, itemNounPlural: info.plural, readingVerb: info.verb, ingestDescription: info.description };
} }
function activeWorkUnit(
input: MemoryFlowReplayInput,
): { unitKey: string; stepIndex: number; stepBudget: number } | null {
const units = activeWorkUnits(input);
return units.at(-1) ?? null;
}
function activeWorkUnits( function activeWorkUnits(
input: MemoryFlowReplayInput, input: MemoryFlowReplayInput,
): Array<{ unitKey: string; stepIndex: number; stepBudget: number }> { ): Array<{ unitKey: string; stepIndex: number; stepBudget: number }> {
@ -299,22 +207,6 @@ function finishedUnits(input: MemoryFlowReplayInput): Array<{ unitKey: string; a
return units; return units;
} }
function artifactCounts(input: MemoryFlowReplayInput): { sl: number; wiki: number } {
let sl = 0;
let wiki = 0;
for (const e of input.events) {
if (e.type === 'candidate_action') {
if (e.target === 'sl') sl++;
else wiki++;
}
}
return { sl, wiki };
}
function pad(str: string, width: number): string {
return str.length >= width ? str : str + ' '.repeat(width - str.length);
}
const KTX_LOGO_SMALL = [ const KTX_LOGO_SMALL = [
'██╗ ██╗████████╗██╗ ██╗', '██╗ ██╗████████╗██╗ ██╗',
'██║ ██╔╝╚══██╔══╝╚██╗██╔╝', '██║ ██╔╝╚══██╔══╝╚██╗██╔╝',
@ -344,12 +236,7 @@ export function Hud(props: {
width: number; width: number;
now?: () => number; now?: () => number;
}): ReactNode { }): ReactNode {
const isRunning = props.input.status === 'running';
const isDone = props.input.status === 'done';
const isFlowing = isRunning && hasWorkStarted(props.input);
const src = sourceDescription(props.input); const src = sourceDescription(props.input);
const counts = artifactCounts(props.input);
const metrics = buildDemoMetrics(props.input, props.now ? { now: props.now } : {}); const metrics = buildDemoMetrics(props.input, props.now ? { now: props.now } : {});
const workStarted = hasWorkStarted(props.input); const workStarted = hasWorkStarted(props.input);
@ -358,11 +245,6 @@ export function Hud(props: {
const innerWidth = Math.max(60, props.width - 6); const innerWidth = Math.max(60, props.width - 6);
const actives = activeWorkUnits(props.input);
const reconEvent = props.input.events.find((e) => e.type === 'reconciliation_finished');
const allAnalyzed = isFlowing && actives.length === 0;
const isReconciling = allAnalyzed && !reconEvent && !isDone;
const hLine = '─'.repeat(innerWidth); const hLine = '─'.repeat(innerWidth);
const elapsed = formatDuration(metrics.elapsedMs); const elapsed = formatDuration(metrics.elapsedMs);
@ -429,7 +311,6 @@ export function ActivityFeed(props: {
const workStarted = hasWorkStarted(props.input); const workStarted = hasWorkStarted(props.input);
const totalChunks = planEvent?.chunkCount ?? 0; const totalChunks = planEvent?.chunkCount ?? 0;
const finishedWithArtifacts = finished.filter((u) => u.artifactCount > 0);
const finishedAreas = totalChunks > 0 ? Math.min(finished.length, totalChunks) : finished.length; const finishedAreas = totalChunks > 0 ? Math.min(finished.length, totalChunks) : finished.length;
const allWorkDone = workStarted && actives.length === 0 && queued.length === 0; const allWorkDone = workStarted && actives.length === 0 && queued.length === 0;
const isReconciling = allWorkDone && !reconEvent && !isDone && !isError; const isReconciling = allWorkDone && !reconEvent && !isDone && !isError;

View file

@ -11,7 +11,6 @@ import {
startLiveMemoryFlowTui, startLiveMemoryFlowTui,
type KtxMemoryFlowTuiIo, type KtxMemoryFlowTuiIo,
type MemoryFlowInkInstance, type MemoryFlowInkInstance,
type MemoryFlowInkRenderOptions,
} from './memory-flow-tui.js'; } from './memory-flow-tui.js';
function replayInput(): MemoryFlowReplayInput { function replayInput(): MemoryFlowReplayInput {

View file

@ -1,7 +1,6 @@
/* @jsxImportSource react */ /* @jsxImportSource react */
import { import {
buildMemoryFlowViewModel, buildMemoryFlowViewModel,
buildMemoryFlowVisualModel,
createInitialMemoryFlowInteractionState, createInitialMemoryFlowInteractionState,
findMemoryFlowSearchMatches, findMemoryFlowSearchMatches,
type MemoryFlowColumnId, type MemoryFlowColumnId,
@ -14,8 +13,7 @@ import {
selectedMemoryFlowDetails, selectedMemoryFlowDetails,
} from '@ktx/context/ingest'; } from '@ktx/context/ingest';
import { Box, Text, render as renderInkRuntime, useApp, useInput } from 'ink'; import { Box, Text, render as renderInkRuntime, useApp, useInput } from 'ink';
import React, { type ReactNode, useEffect, useMemo, useRef, useState } from 'react'; import { type ReactNode, useEffect, useMemo, useRef, useState } from 'react';
import { buildDemoMetrics } from './demo-metrics.js';
import { import {
ActivityFeed, ActivityFeed,
Hud, Hud,
@ -201,14 +199,6 @@ function stageLabel(columnId: MemoryFlowColumnId): string {
return STAGE_LABELS[columnId]; return STAGE_LABELS[columnId];
} }
function statusLabel(status: string): 'OK' | 'RUN' | 'WARN' | 'FAIL' | 'WAIT' {
if (status === 'complete') return 'OK';
if (status === 'active') return 'RUN';
if (status === 'warning') return 'WARN';
if (status === 'failed') return 'FAIL';
return 'WAIT';
}
function filterLabel(filter: MemoryFlowInteractionState['filter']): string { function filterLabel(filter: MemoryFlowInteractionState['filter']): string {
return filter === 'failed_or_flagged' ? 'issues' : 'all'; return filter === 'failed_or_flagged' ? 'issues' : 'all';
} }
@ -325,7 +315,6 @@ export function MemoryFlowTuiApp(props: MemoryFlowTuiAppProps): ReactNode {
const view = useMemo(() => buildMemoryFlowViewModel(pacedInput), [pacedInput]); const view = useMemo(() => buildMemoryFlowViewModel(pacedInput), [pacedInput]);
const [state, setState] = useState<MemoryFlowInteractionState>(() => createInitialMemoryFlowInteractionState(view)); const [state, setState] = useState<MemoryFlowInteractionState>(() => createInitialMemoryFlowInteractionState(view));
const [frame, setFrame] = useState(0); const [frame, setFrame] = useState(0);
const [thoughtFrame, setThoughtFrame] = useState(0);
const [completionFrame, setCompletionFrame] = useState(0); const [completionFrame, setCompletionFrame] = useState(0);
const [holdComplete, setHoldComplete] = useState(false); const [holdComplete, setHoldComplete] = useState(false);
const [userHasNavigated, setUserHasNavigated] = useState(false); const [userHasNavigated, setUserHasNavigated] = useState(false);
@ -346,7 +335,6 @@ export function MemoryFlowTuiApp(props: MemoryFlowTuiAppProps): ReactNode {
useEffect(() => { useEffect(() => {
const timer = setInterval(() => { const timer = setInterval(() => {
setFrame((current) => current + 1); setFrame((current) => current + 1);
setThoughtFrame((current) => current + 1);
}, props.frameMs ?? DEFAULT_TUI_TIMING.frameMs); }, props.frameMs ?? DEFAULT_TUI_TIMING.frameMs);
return () => clearInterval(timer); return () => clearInterval(timer);
}, [props.frameMs]); }, [props.frameMs]);
@ -354,7 +342,6 @@ export function MemoryFlowTuiApp(props: MemoryFlowTuiAppProps): ReactNode {
useEffect(() => { useEffect(() => {
if (lastEventCountRef.current !== pacedInput.events.length) { if (lastEventCountRef.current !== pacedInput.events.length) {
lastEventCountRef.current = pacedInput.events.length; lastEventCountRef.current = pacedInput.events.length;
setThoughtFrame(0);
} }
}, [pacedInput.events.length]); }, [pacedInput.events.length]);
@ -409,10 +396,6 @@ export function MemoryFlowTuiApp(props: MemoryFlowTuiAppProps): ReactNode {
}); });
const isComplete = pacedInput.status === 'done' || pacedInput.status === 'error'; const isComplete = pacedInput.status === 'done' || pacedInput.status === 'error';
const completionMetrics = useMemo(
() => buildDemoMetrics(pacedInput, pacedNow ? { now: pacedNow } : {}),
[pacedInput, pacedNow],
);
const termWidth = props.terminalWidth ?? 80; const termWidth = props.terminalWidth ?? 80;

View file

@ -1,5 +0,0 @@
import { resolve } from 'node:path';
export function resolveProjectDir(projectDir?: string, fallback = '.'): string {
return resolve(projectDir ?? fallback);
}

View file

@ -6,9 +6,9 @@ import { profileMark } from './startup-profile.js';
profileMark('module:public-ingest'); profileMark('module:public-ingest');
export type KtxPublicIngestStepName = 'scan' | 'source-ingest' | 'enrich' | 'memory-update'; type KtxPublicIngestStepName = 'scan' | 'source-ingest' | 'enrich' | 'memory-update';
export type KtxPublicIngestStepStatus = 'done' | 'skipped' | 'failed' | 'not-run'; type KtxPublicIngestStepStatus = 'done' | 'skipped' | 'failed' | 'not-run';
export type KtxPublicIngestInputMode = 'auto' | 'disabled'; type KtxPublicIngestInputMode = 'auto' | 'disabled';
export type KtxPublicIngestArgs = export type KtxPublicIngestArgs =
| { | {

View file

@ -474,16 +474,6 @@ async function markContextComplete(projectDir: string): Promise<void> {
await markKtxSetupStateStepComplete(projectDir, 'context'); await markKtxSetupStateStepComplete(projectDir, 'context');
} }
function writeBuildHeader(projectDir: string, runId: string, io: KtxCliIo): void {
const commands = contextBuildCommands(projectDir, runId);
io.stdout.write('\nKTX context build\n');
io.stdout.write(`Run: ${runId}\n`);
io.stdout.write(`Project: ${resolve(projectDir)}\n\n`);
io.stdout.write('Detach: press d to leave this running.\n');
io.stdout.write(`Resume: ${commands.watch}\n`);
io.stdout.write(`Status: ${commands.status}\n\n`);
}
function writeMissingCapabilities(missing: string[], io: KtxCliIo): void { function writeMissingCapabilities(missing: string[], io: KtxCliIo): void {
io.stderr.write('KTX cannot build agent-ready context yet.\n\n'); io.stderr.write('KTX cannot build agent-ready context yet.\n\n');
io.stderr.write('Missing:\n'); io.stderr.write('Missing:\n');

View file

@ -126,10 +126,6 @@ async function writeSqliteScanConfig(projectDir: string, dbPath: string, enrich
); );
} }
function parseJsonOutput<T>(stdout: string): T {
return JSON.parse(stdout) as T;
}
function expectProjectStderr(result: CliResult, projectDir: string): void { function expectProjectStderr(result: CliResult, projectDir: string): void {
expect(result).toMatchObject({ code: 0, stderr: `Project: ${projectDir}\n` }); expect(result).toMatchObject({ code: 0, stderr: `Project: ${projectDir}\n` });
} }

View file

@ -53,7 +53,6 @@ function fixSuggestions(input: MemoryFlowReplayInput): string[] {
export function formatMemoryFlowFinalSummary(input: MemoryFlowReplayInput): string { export function formatMemoryFlowFinalSummary(input: MemoryFlowReplayInput): string {
const sources = eventsOf(input.events, 'source_acquired'); const sources = eventsOf(input.events, 'source_acquired');
const source = sources.at(-1);
const totalFiles = sources.reduce((sum, s) => sum + s.fileCount, 0); const totalFiles = sources.reduce((sum, s) => sum + s.fileCount, 0);
const saved = latest(input.events, 'saved'); const saved = latest(input.events, 'saved');
const provenance = latest(input.events, 'provenance_recorded'); const provenance = latest(input.events, 'provenance_recorded');

View file

@ -68,15 +68,6 @@ export interface KtxDescriptionUpdate {
columnDescriptions?: Record<string, string | null>; columnDescriptions?: Record<string, string | null>;
} }
const PREFERRED_METADATA_FIELD_NAMES = [
'tags',
'constraints',
'enum_values',
'freshness',
'tests',
'lineage',
] as const;
export interface KtxMetadataUpdate { export interface KtxMetadataUpdate {
connectionId: string; connectionId: string;
table: KtxTableRef; table: KtxTableRef;

611
pnpm-lock.yaml generated
View file

@ -12,15 +12,24 @@ importers:
.: .:
devDependencies: devDependencies:
'@biomejs/biome':
specifier: ^2.4.15
version: 2.4.15
'@types/node': '@types/node':
specifier: ^24.3.0 specifier: ^24.3.0
version: 24.12.2 version: 24.12.2
better-sqlite3:
specifier: ^12.10.0
version: 12.10.0
knip:
specifier: ^6.12.2
version: 6.12.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
typescript: typescript:
specifier: ^6.0.3 specifier: ^6.0.3
version: 6.0.3 version: 6.0.3
vitest: yaml:
specifier: ^4.1.6 specifier: ^2.9.0
version: 4.1.6(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)) version: 2.9.0
docs-site: docs-site:
dependencies: dependencies:
@ -741,6 +750,63 @@ packages:
resolution: {integrity: sha512-SriLPKezypIsiZ+TtlFfE46uuBIap2HeaQVS78e1P7rz5OSbq0rsd52WE1mC5f7vAeLiXqv7I7oRhL3WFZEw3Q==} resolution: {integrity: sha512-SriLPKezypIsiZ+TtlFfE46uuBIap2HeaQVS78e1P7rz5OSbq0rsd52WE1mC5f7vAeLiXqv7I7oRhL3WFZEw3Q==}
engines: {node: '>=18.0.0'} engines: {node: '>=18.0.0'}
'@biomejs/biome@2.4.15':
resolution: {integrity: sha512-j5VH3a/h/HXTKBM50MDMxRCzkeLv9S2XJcW2WgnZT1+xyisi+0bISrXR82gCX+8S9lvK0skEvHJRN+3Ktr2hlw==}
engines: {node: '>=14.21.3'}
hasBin: true
'@biomejs/cli-darwin-arm64@2.4.15':
resolution: {integrity: sha512-rF3PPqLq1yoST79zaQbDjVJwsuIeci/O+9bgNmC5QpgOqz6aqYuzA4abyAGx+mgyiDXn4A049xAN8gijbuR1Qg==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [darwin]
'@biomejs/cli-darwin-x64@2.4.15':
resolution: {integrity: sha512-/5KHXYMfSJs1fNXiX30xFtI8JcCFV6zaVVLxOa0M2sfqBKHkpQhRTv94yxQWxeTY2lzo2OuTlNvPC+hDQt2wcQ==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [darwin]
'@biomejs/cli-linux-arm64-musl@2.4.15':
resolution: {integrity: sha512-ZPcxznxm0pogHBLZhYntyR3sR+MrZjqJIKEr7ZqVen0Rl+P/4upVmfYXjftizi9RoqZntg33fv/1fbdhbYXpEQ==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@biomejs/cli-linux-arm64@2.4.15':
resolution: {integrity: sha512-owaAMZD/T4LrD0ELNCk0Km3qrRHuM0X6EAyVE1FSqGY0rbLoiDLrO4Us2tllm6cAeB2Ioa9C2C08NZPdr8+0Ug==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@biomejs/cli-linux-x64-musl@2.4.15':
resolution: {integrity: sha512-CNq/9W38SYSH023lfcQ4KKU8K0YX8T//FZUhcgtMMRABDojx5XsMV7jlweAvGSl389wJQB29Qo6Zb/a+jdvt+w==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
libc: [musl]
'@biomejs/cli-linux-x64@2.4.15':
resolution: {integrity: sha512-0jj7THz12GbUOLmMibktK6DZjqz2zV64KFxyBtcFTKPiiOIY0a7vns1elpO1dERvxpsZ5ik0oFfz0oGwFde1+g==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@biomejs/cli-win32-arm64@2.4.15':
resolution: {integrity: sha512-ouhkYdlhp/1GghEJPdWwD/Vi3gQ1nFxuSpMolWsbq3Lsq3QUR4jl6UdhhscdCugKU5vOEuMiJhvKj66O0OCq+w==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [win32]
'@biomejs/cli-win32-x64@2.4.15':
resolution: {integrity: sha512-zBrGq5mx5wwpnow4+2BxUvleDM+GNd4sLbPaMapsSLQLD0NGRCquqPBTgN+7XkUteHvj7M+BstuI8tmnV7+HgQ==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [win32]
'@clack/core@1.3.1': '@clack/core@1.3.1':
resolution: {integrity: sha512-fT1qHVGAag4IEkrupZ6lRRbNCs1vS9P01KB/sG8zKgvUztbYtFBtQpjSITNwooDZ83tpsPzP0mRNs1/KVszCRA==} resolution: {integrity: sha512-fT1qHVGAag4IEkrupZ6lRRbNCs1vS9P01KB/sG8zKgvUztbYtFBtQpjSITNwooDZ83tpsPzP0mRNs1/KVszCRA==}
engines: {node: '>= 20.12.0'} engines: {node: '>= 20.12.0'}
@ -1317,9 +1383,247 @@ packages:
resolution: {integrity: sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA==} resolution: {integrity: sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA==}
engines: {node: '>= 20.0.0'} engines: {node: '>= 20.0.0'}
'@oxc-parser/binding-android-arm-eabi@0.128.0':
resolution: {integrity: sha512-aca6ZvzmCBUGOANQRiRQRZuRKYI3ENhcit6GisnknOOmcezfQc7xJ4dxlPU7MV7mOvrC7RNR1u3LAD7xyaiCxA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [android]
'@oxc-parser/binding-android-arm64@0.128.0':
resolution: {integrity: sha512-BbeDmuohoJ7Rz/it5wnkj69i/OsCPS3Z51nLEzwO/Y6YshtC4JU+15oNwhY8v4LRKRYclRc7ggOikwrsJ/eOEQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [android]
'@oxc-parser/binding-darwin-arm64@0.128.0':
resolution: {integrity: sha512-tRUHPt80417QmvNpoSslJT1VY8NUbWdrWR+L14Zn+RbOTcaqB8E6PYE/ZGN8jjWBzqporiA/H4MfO50ew/NCNA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [darwin]
'@oxc-parser/binding-darwin-x64@0.128.0':
resolution: {integrity: sha512-rWI2Hb1Nt3U/vKsjyNvZzDC8i/l144U20DKjhzaTmwIhIiSRGeroPWWiImwypmKLqrw8GuIixbWJkpGWLbkzrQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [darwin]
'@oxc-parser/binding-freebsd-x64@0.128.0':
resolution: {integrity: sha512-hhpdVMaNCLgQxjgNPeeFzSeJMmZPc5lKfv0NGSI3egZq9EdnEGqeC8JsYsQjK7PoQgbvZ17xlj0SO5ziH5Obkg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [freebsd]
'@oxc-parser/binding-linux-arm-gnueabihf@0.128.0':
resolution: {integrity: sha512-093zNw0zZ/e/obML+rhlSdmnzR0mVZluPcAkxunEc5E3F0yBVsFn24Y1ILfsEte11Ud041qn/gp2OJ1jxNqUng==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxc-parser/binding-linux-arm-musleabihf@0.128.0':
resolution: {integrity: sha512-fq7DmKmfC+dvD97IXrgbph6Jzwe0EDu+PYMofmzZ6fv5X1k9vtaqLpDGMuICO9MmUnyKAQmVl+wIv2RNy4Dz8g==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm]
os: [linux]
'@oxc-parser/binding-linux-arm64-gnu@0.128.0':
resolution: {integrity: sha512-Xvm48jJah8TlIrURIjNOP/gNiGe6aKvCB+r06VliflFo8Kq7VOLE8PxtgShJzZIqubrgdMdYfvuPPozn7F6MbQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-arm64-musl@0.128.0':
resolution: {integrity: sha512-M7iwBGmYJTx+pKOYFjI0buop4gJvlmcVzFGaXPt21DKpQkbQZG1f63Yg7LloIYT/t9yLxCw0Lhfx/RFlAlMSjA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxc-parser/binding-linux-ppc64-gnu@0.128.0':
resolution: {integrity: sha512-21LGNIZb1Pcfk5/EGsqabrxv4yqQOWis1407JJrClS7XpFCrbvr74YAB1V+m54cYbwvO6UWwQqS4WecxiyfCRg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-riscv64-gnu@0.128.0':
resolution: {integrity: sha512-gyHjOTFpg9bTTYjxPmQirvufb89+VdZwVfcMtAUyPr6F5H8ZswvCQshK4qOW+Q+2Xyb33hduRgY/eFHJQjU/vQ==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-riscv64-musl@0.128.0':
resolution: {integrity: sha512-X6Q2oKUrP5GyDd2xniuEBLk6aFQCZ97W2+aVXGgJXdjx5t4/oFuA9ri0wLOUrBIX+qdSuK581snMBio4z910eA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxc-parser/binding-linux-s390x-gnu@0.128.0':
resolution: {integrity: sha512-BdzTmqxfxoYkpgokoLaSnOX6T+R3/goL42klre2tnG+kHbG2TXS0VN+P5BPofH1axdKOHy5ei4ENZrjmCOt2lA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-x64-gnu@0.128.0':
resolution: {integrity: sha512-OO1nW2Q7sSYYvJZpDHdvyFSdRaVcQqRijZSSmWVMqFxPYy8cEF45zJ9fcdIYuzIT3jYq6YRhEFm/VMWNWhE22Q==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxc-parser/binding-linux-x64-musl@0.128.0':
resolution: {integrity: sha512-4NehAe404MRdoZVS9DW8C5XbJwbXIc/KfVlYdpi5vE4081zc9Y0YzKVqyOYj/Puye7/Do+ohaONBFWlEHYl9hw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxc-parser/binding-openharmony-arm64@0.128.0':
resolution: {integrity: sha512-kVbqgW9xLL8bh8oc7aYOJilRKXE5G33+tE0jan+duo/9OriaFRpijcCwT2waWs2oqYROYq0GlE7/p3ywoshVeg==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [openharmony]
'@oxc-parser/binding-wasm32-wasi@0.128.0':
resolution: {integrity: sha512-L38ojghJYHmgiz6fJd7jwLB/ESDBpB02NdFxh+smqVM6P2anCEvHn0jhaSrt5eVNR1Ak8+moOeftUlofeyvniA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [wasm32]
'@oxc-parser/binding-win32-arm64-msvc@0.128.0':
resolution: {integrity: sha512-xgvO35GyHBtjlQ5AEpaYr7Rll1rvY7zqIhT6ty8E3ezBW2J1SFLjIDEvI/tcgDg6oaseDAqVcM+jU1HuCekgZw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [arm64]
os: [win32]
'@oxc-parser/binding-win32-ia32-msvc@0.128.0':
resolution: {integrity: sha512-OY+3eM2SN72prHKRB22mPz8o5A/7dJ+f5DFLBVvggyZhEaNDAH9IB+ElMjmOkOIwf5MDCUAowCK7pAncNxzpBA==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [ia32]
os: [win32]
'@oxc-parser/binding-win32-x64-msvc@0.128.0':
resolution: {integrity: sha512-NE9ny+cPUCCObXa0IKLfj0tCdPd7pe/dz9ZpkxpUOymB3miNeMPybdlYYTBSGJUalMWeBM85/4JcCErCNTqOXw==}
engines: {node: ^20.19.0 || >=22.12.0}
cpu: [x64]
os: [win32]
'@oxc-project/types@0.127.0': '@oxc-project/types@0.127.0':
resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==}
'@oxc-project/types@0.128.0':
resolution: {integrity: sha512-huv1Y/LzBJkBVHt3OlC7u0zHBW9qXf1FdD7sGmc1rXc2P1mTwHssYv7jyGx5KAACSCH+9B3Bhn6Z9luHRvf7pQ==}
'@oxc-resolver/binding-android-arm-eabi@11.19.1':
resolution: {integrity: sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==}
cpu: [arm]
os: [android]
'@oxc-resolver/binding-android-arm64@11.19.1':
resolution: {integrity: sha512-oolbkRX+m7Pq2LNjr/kKgYeC7bRDMVTWPgxBGMjSpZi/+UskVo4jsMU3MLheZV55jL6c3rNelPl4oD60ggYmqA==}
cpu: [arm64]
os: [android]
'@oxc-resolver/binding-darwin-arm64@11.19.1':
resolution: {integrity: sha512-nUC6d2i3R5B12sUW4O646qD5cnMXf2oBGPLIIeaRfU9doJRORAbE2SGv4eW6rMqhD+G7nf2Y8TTJTLiiO3Q/dQ==}
cpu: [arm64]
os: [darwin]
'@oxc-resolver/binding-darwin-x64@11.19.1':
resolution: {integrity: sha512-cV50vE5+uAgNcFa3QY1JOeKDSkM/9ReIcc/9wn4TavhW/itkDGrXhw9jaKnkQnGbjJ198Yh5nbX/Gr2mr4Z5jQ==}
cpu: [x64]
os: [darwin]
'@oxc-resolver/binding-freebsd-x64@11.19.1':
resolution: {integrity: sha512-xZOQiYGFxtk48PBKff+Zwoym7ScPAIVp4c14lfLxizO2LTTTJe5sx9vQNGrBymrf/vatSPNMD4FgsaaRigPkqw==}
cpu: [x64]
os: [freebsd]
'@oxc-resolver/binding-linux-arm-gnueabihf@11.19.1':
resolution: {integrity: sha512-lXZYWAC6kaGe/ky2su94e9jN9t6M0/6c+GrSlCqL//XO1cxi5lpAhnJYdyrKfm0ZEr/c7RNyAx3P7FSBcBd5+A==}
cpu: [arm]
os: [linux]
'@oxc-resolver/binding-linux-arm-musleabihf@11.19.1':
resolution: {integrity: sha512-veG1kKsuK5+t2IsO9q0DErYVSw2azvCVvWHnfTOS73WE0STdLLB7Q1bB9WR+yHPQM76ASkFyRbogWo1GR1+WbQ==}
cpu: [arm]
os: [linux]
'@oxc-resolver/binding-linux-arm64-gnu@11.19.1':
resolution: {integrity: sha512-heV2+jmXyYnUrpUXSPugqWDRpnsQcDm2AX4wzTuvgdlZfoNYO0O3W2AVpJYaDn9AG4JdM6Kxom8+foE7/BcSig==}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-arm64-musl@11.19.1':
resolution: {integrity: sha512-jvo2Pjs1c9KPxMuMPIeQsgu0mOJF9rEb3y3TdpsrqwxRM+AN6/nDDwv45n5ZrUnQMsdBy5gIabioMKnQfWo9ew==}
cpu: [arm64]
os: [linux]
libc: [musl]
'@oxc-resolver/binding-linux-ppc64-gnu@11.19.1':
resolution: {integrity: sha512-vLmdNxWCdN7Uo5suays6A/+ywBby2PWBBPXctWPg5V0+eVuzsJxgAn6MMB4mPlshskYbppjpN2Zg83ArHze9gQ==}
cpu: [ppc64]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-riscv64-gnu@11.19.1':
resolution: {integrity: sha512-/b+WgR+VTSBxzgOhDO7TlMXC1ufPIMR6Vj1zN+/x+MnyXGW7prTLzU9eW85Aj7Th7CCEG9ArCbTeqxCzFWdg2w==}
cpu: [riscv64]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-riscv64-musl@11.19.1':
resolution: {integrity: sha512-YlRdeWb9j42p29ROh+h4eg/OQ3dTJlpHSa+84pUM9+p6i3djtPz1q55yLJhgW9XfDch7FN1pQ/Vd6YP+xfRIuw==}
cpu: [riscv64]
os: [linux]
libc: [musl]
'@oxc-resolver/binding-linux-s390x-gnu@11.19.1':
resolution: {integrity: sha512-EDpafVOQWF8/MJynsjOGFThcqhRHy417sRyLfQmeiamJ8qVhSKAn2Dn2VVKUGCjVB9C46VGjhNo7nOPUi1x6uA==}
cpu: [s390x]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-x64-gnu@11.19.1':
resolution: {integrity: sha512-NxjZe+rqWhr+RT8/Ik+5ptA3oz7tUw361Wa5RWQXKnfqwSSHdHyrw6IdcTfYuml9dM856AlKWZIUXDmA9kkiBQ==}
cpu: [x64]
os: [linux]
libc: [glibc]
'@oxc-resolver/binding-linux-x64-musl@11.19.1':
resolution: {integrity: sha512-cM/hQwsO3ReJg5kR+SpI69DMfvNCp+A/eVR4b4YClE5bVZwz8rh2Nh05InhwI5HR/9cArbEkzMjcKgTHS6UaNw==}
cpu: [x64]
os: [linux]
libc: [musl]
'@oxc-resolver/binding-openharmony-arm64@11.19.1':
resolution: {integrity: sha512-QF080IowFB0+9Rh6RcD19bdgh49BpQHUW5TajG1qvWHvmrQznTZZjYlgE2ltLXyKY+qs4F/v5xuX1XS7Is+3qA==}
cpu: [arm64]
os: [openharmony]
'@oxc-resolver/binding-wasm32-wasi@11.19.1':
resolution: {integrity: sha512-w8UCKhX826cP/ZLokXDS6+milN8y4X7zidsAttEdWlVoamTNf6lhBJldaWr3ukTDiye7s4HRcuPEPOXNC432Vg==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
'@oxc-resolver/binding-win32-arm64-msvc@11.19.1':
resolution: {integrity: sha512-nJ4AsUVZrVKwnU/QRdzPCCrO0TrabBqgJ8pJhXITdZGYOV28TIYystV1VFLbQ7DtAcaBHpocT5/ZJnF78YJPtQ==}
cpu: [arm64]
os: [win32]
'@oxc-resolver/binding-win32-ia32-msvc@11.19.1':
resolution: {integrity: sha512-EW+ND5q2Tl+a3pH81l1QbfgbF3HmqgwLfDfVithRFheac8OTcnbXt/JxqD2GbDkb7xYEqy1zNaVFRr3oeG8npA==}
cpu: [ia32]
os: [win32]
'@oxc-resolver/binding-win32-x64-msvc@11.19.1':
resolution: {integrity: sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw==}
cpu: [x64]
os: [win32]
'@radix-ui/number@1.1.1': '@radix-ui/number@1.1.1':
resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==}
@ -2799,6 +3103,9 @@ packages:
resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
engines: {node: '>= 4.9.1'} engines: {node: '>= 4.9.1'}
fd-package-json@2.0.0:
resolution: {integrity: sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ==}
fdir@6.5.0: fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
@ -2838,6 +3145,11 @@ packages:
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
engines: {node: '>= 6'} engines: {node: '>= 6'}
formatly@0.3.0:
resolution: {integrity: sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w==}
engines: {node: '>=18.3.0'}
hasBin: true
formdata-polyfill@4.0.10: formdata-polyfill@4.0.10:
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
engines: {node: '>=12.20.0'} engines: {node: '>=12.20.0'}
@ -3019,6 +3331,9 @@ packages:
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
engines: {node: '>= 0.4'} engines: {node: '>= 0.4'}
get-tsconfig@4.14.0:
resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==}
github-from-package@0.0.0: github-from-package@0.0.0:
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
@ -3269,6 +3584,11 @@ packages:
jws@4.0.1: jws@4.0.1:
resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==}
knip@6.12.2:
resolution: {integrity: sha512-RcZpT1sVziKZgDk1F0hAcp+bq71VJAF8vg1Y9ZLXc1+UXQaMm1rjiUqpJQTIj+lqwmiBQT19/u7ikgazs23cvA==}
engines: {node: ^20.19.0 || >=22.12.0}
hasBin: true
kuler@2.0.0: kuler@2.0.0:
resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==}
@ -3766,6 +4086,13 @@ packages:
zod: zod:
optional: true optional: true
oxc-parser@0.128.0:
resolution: {integrity: sha512-XkOw3eiIxAgQ19WRew/Bq9wc5Ga/guaWIzDBzq80z1PyuDNGvWBpPby9k6YGwV8A8uMw+Nlq3xqlzuDYmUFYUw==}
engines: {node: ^20.19.0 || >=22.12.0}
oxc-resolver@11.19.1:
resolution: {integrity: sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg==}
p-limit@7.3.0: p-limit@7.3.0:
resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==}
engines: {node: '>=20'} engines: {node: '>=20'}
@ -4028,6 +4355,9 @@ packages:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
restore-cursor@4.0.0: restore-cursor@4.0.0:
resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@ -4138,6 +4468,10 @@ packages:
resolution: {integrity: sha512-SO/3iYL5S3W57LLEniscOGPZgOqZUPCx6d3dB+52B80yJ0XstzsC/eV8gnA4tM3MHDrKz+OCFSLNjswdSC+/bA==} resolution: {integrity: sha512-SO/3iYL5S3W57LLEniscOGPZgOqZUPCx6d3dB+52B80yJ0XstzsC/eV8gnA4tM3MHDrKz+OCFSLNjswdSC+/bA==}
engines: {node: '>=22'} engines: {node: '>=22'}
smol-toml@1.6.1:
resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==}
engines: {node: '>= 18'}
snowflake-sdk@2.4.1: snowflake-sdk@2.4.1:
resolution: {integrity: sha512-JIdqz9ed2FzkU8oEstf06hTJRoX9+PRRG9LJT1vfGTXN3A52kGxhGoWzmK0GtFTUnxTMxMoMYgD5QdoQbckyag==} resolution: {integrity: sha512-JIdqz9ed2FzkU8oEstf06hTJRoX9+PRRG9LJT1vfGTXN3A52kGxhGoWzmK0GtFTUnxTMxMoMYgD5QdoQbckyag==}
engines: {node: '>=18'} engines: {node: '>=18'}
@ -4211,6 +4545,10 @@ packages:
resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
strip-json-comments@5.0.3:
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
engines: {node: '>=14.16'}
strnum@2.2.3: strnum@2.2.3:
resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==} resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==}
@ -4336,6 +4674,10 @@ packages:
engines: {node: '>=0.8.0'} engines: {node: '>=0.8.0'}
hasBin: true hasBin: true
unbash@3.0.0:
resolution: {integrity: sha512-FeFPZ/WFT0mbRCuydiZzpPFlrYN8ZUpphQKoq4EeElVIYjYyGzPMxQR/simUwCOJIyVhpFk4RbtyO7RuMpMnHA==}
engines: {node: '>=14'}
undici-types@7.16.0: undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
@ -4487,6 +4829,10 @@ packages:
jsdom: jsdom:
optional: true optional: true
walk-up-path@4.0.0:
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
engines: {node: 20 || >=22}
web-namespaces@2.0.1: web-namespaces@2.0.1:
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
@ -5546,6 +5892,41 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@biomejs/biome@2.4.15':
optionalDependencies:
'@biomejs/cli-darwin-arm64': 2.4.15
'@biomejs/cli-darwin-x64': 2.4.15
'@biomejs/cli-linux-arm64': 2.4.15
'@biomejs/cli-linux-arm64-musl': 2.4.15
'@biomejs/cli-linux-x64': 2.4.15
'@biomejs/cli-linux-x64-musl': 2.4.15
'@biomejs/cli-win32-arm64': 2.4.15
'@biomejs/cli-win32-x64': 2.4.15
'@biomejs/cli-darwin-arm64@2.4.15':
optional: true
'@biomejs/cli-darwin-x64@2.4.15':
optional: true
'@biomejs/cli-linux-arm64-musl@2.4.15':
optional: true
'@biomejs/cli-linux-arm64@2.4.15':
optional: true
'@biomejs/cli-linux-x64-musl@2.4.15':
optional: true
'@biomejs/cli-linux-x64@2.4.15':
optional: true
'@biomejs/cli-win32-arm64@2.4.15':
optional: true
'@biomejs/cli-win32-x64@2.4.15':
optional: true
'@clack/core@1.3.1': '@clack/core@1.3.1':
dependencies: dependencies:
fast-wrap-ansi: 0.2.0 fast-wrap-ansi: 0.2.0
@ -6130,8 +6511,139 @@ snapshots:
'@orama/orama@3.1.18': {} '@orama/orama@3.1.18': {}
'@oxc-parser/binding-android-arm-eabi@0.128.0':
optional: true
'@oxc-parser/binding-android-arm64@0.128.0':
optional: true
'@oxc-parser/binding-darwin-arm64@0.128.0':
optional: true
'@oxc-parser/binding-darwin-x64@0.128.0':
optional: true
'@oxc-parser/binding-freebsd-x64@0.128.0':
optional: true
'@oxc-parser/binding-linux-arm-gnueabihf@0.128.0':
optional: true
'@oxc-parser/binding-linux-arm-musleabihf@0.128.0':
optional: true
'@oxc-parser/binding-linux-arm64-gnu@0.128.0':
optional: true
'@oxc-parser/binding-linux-arm64-musl@0.128.0':
optional: true
'@oxc-parser/binding-linux-ppc64-gnu@0.128.0':
optional: true
'@oxc-parser/binding-linux-riscv64-gnu@0.128.0':
optional: true
'@oxc-parser/binding-linux-riscv64-musl@0.128.0':
optional: true
'@oxc-parser/binding-linux-s390x-gnu@0.128.0':
optional: true
'@oxc-parser/binding-linux-x64-gnu@0.128.0':
optional: true
'@oxc-parser/binding-linux-x64-musl@0.128.0':
optional: true
'@oxc-parser/binding-openharmony-arm64@0.128.0':
optional: true
'@oxc-parser/binding-wasm32-wasi@0.128.0':
dependencies:
'@emnapi/core': 1.10.0
'@emnapi/runtime': 1.10.0
'@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
optional: true
'@oxc-parser/binding-win32-arm64-msvc@0.128.0':
optional: true
'@oxc-parser/binding-win32-ia32-msvc@0.128.0':
optional: true
'@oxc-parser/binding-win32-x64-msvc@0.128.0':
optional: true
'@oxc-project/types@0.127.0': {} '@oxc-project/types@0.127.0': {}
'@oxc-project/types@0.128.0': {}
'@oxc-resolver/binding-android-arm-eabi@11.19.1':
optional: true
'@oxc-resolver/binding-android-arm64@11.19.1':
optional: true
'@oxc-resolver/binding-darwin-arm64@11.19.1':
optional: true
'@oxc-resolver/binding-darwin-x64@11.19.1':
optional: true
'@oxc-resolver/binding-freebsd-x64@11.19.1':
optional: true
'@oxc-resolver/binding-linux-arm-gnueabihf@11.19.1':
optional: true
'@oxc-resolver/binding-linux-arm-musleabihf@11.19.1':
optional: true
'@oxc-resolver/binding-linux-arm64-gnu@11.19.1':
optional: true
'@oxc-resolver/binding-linux-arm64-musl@11.19.1':
optional: true
'@oxc-resolver/binding-linux-ppc64-gnu@11.19.1':
optional: true
'@oxc-resolver/binding-linux-riscv64-gnu@11.19.1':
optional: true
'@oxc-resolver/binding-linux-riscv64-musl@11.19.1':
optional: true
'@oxc-resolver/binding-linux-s390x-gnu@11.19.1':
optional: true
'@oxc-resolver/binding-linux-x64-gnu@11.19.1':
optional: true
'@oxc-resolver/binding-linux-x64-musl@11.19.1':
optional: true
'@oxc-resolver/binding-openharmony-arm64@11.19.1':
optional: true
'@oxc-resolver/binding-wasm32-wasi@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)':
dependencies:
'@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
optional: true
'@oxc-resolver/binding-win32-arm64-msvc@11.19.1':
optional: true
'@oxc-resolver/binding-win32-ia32-msvc@11.19.1':
optional: true
'@oxc-resolver/binding-win32-x64-msvc@11.19.1':
optional: true
'@radix-ui/number@1.1.1': {} '@radix-ui/number@1.1.1': {}
'@radix-ui/primitive@1.1.3': {} '@radix-ui/primitive@1.1.3': {}
@ -7691,6 +8203,10 @@ snapshots:
fastest-levenshtein@1.0.16: {} fastest-levenshtein@1.0.16: {}
fd-package-json@2.0.0:
dependencies:
walk-up-path: 4.0.0
fdir@6.5.0(picomatch@4.0.4): fdir@6.5.0(picomatch@4.0.4):
optionalDependencies: optionalDependencies:
picomatch: 4.0.4 picomatch: 4.0.4
@ -7727,6 +8243,10 @@ snapshots:
hasown: 2.0.3 hasown: 2.0.3
mime-types: 2.1.35 mime-types: 2.1.35
formatly@0.3.0:
dependencies:
fd-package-json: 2.0.0
formdata-polyfill@4.0.10: formdata-polyfill@4.0.10:
dependencies: dependencies:
fetch-blob: 3.2.0 fetch-blob: 3.2.0
@ -7895,6 +8415,10 @@ snapshots:
dunder-proto: 1.0.1 dunder-proto: 1.0.1
es-object-atoms: 1.1.1 es-object-atoms: 1.1.1
get-tsconfig@4.14.0:
dependencies:
resolve-pkg-maps: 1.0.0
github-from-package@0.0.0: {} github-from-package@0.0.0: {}
github-slugger@2.0.0: {} github-slugger@2.0.0: {}
@ -8234,6 +8758,26 @@ snapshots:
jwa: 2.0.1 jwa: 2.0.1
safe-buffer: 5.2.1 safe-buffer: 5.2.1
knip@6.12.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0):
dependencies:
fdir: 6.5.0(picomatch@4.0.4)
formatly: 0.3.0
get-tsconfig: 4.14.0
jiti: 2.7.0
minimist: 1.2.8
oxc-parser: 0.128.0
oxc-resolver: 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
picomatch: 4.0.4
smol-toml: 1.6.1
strip-json-comments: 5.0.3
tinyglobby: 0.2.16
unbash: 3.0.0
yaml: 2.9.0
zod: 4.4.3
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
kuler@2.0.0: {} kuler@2.0.0: {}
lightningcss-android-arm64@1.32.0: lightningcss-android-arm64@1.32.0:
@ -8963,6 +9507,57 @@ snapshots:
optionalDependencies: optionalDependencies:
zod: 4.4.3 zod: 4.4.3
oxc-parser@0.128.0:
dependencies:
'@oxc-project/types': 0.128.0
optionalDependencies:
'@oxc-parser/binding-android-arm-eabi': 0.128.0
'@oxc-parser/binding-android-arm64': 0.128.0
'@oxc-parser/binding-darwin-arm64': 0.128.0
'@oxc-parser/binding-darwin-x64': 0.128.0
'@oxc-parser/binding-freebsd-x64': 0.128.0
'@oxc-parser/binding-linux-arm-gnueabihf': 0.128.0
'@oxc-parser/binding-linux-arm-musleabihf': 0.128.0
'@oxc-parser/binding-linux-arm64-gnu': 0.128.0
'@oxc-parser/binding-linux-arm64-musl': 0.128.0
'@oxc-parser/binding-linux-ppc64-gnu': 0.128.0
'@oxc-parser/binding-linux-riscv64-gnu': 0.128.0
'@oxc-parser/binding-linux-riscv64-musl': 0.128.0
'@oxc-parser/binding-linux-s390x-gnu': 0.128.0
'@oxc-parser/binding-linux-x64-gnu': 0.128.0
'@oxc-parser/binding-linux-x64-musl': 0.128.0
'@oxc-parser/binding-openharmony-arm64': 0.128.0
'@oxc-parser/binding-wasm32-wasi': 0.128.0
'@oxc-parser/binding-win32-arm64-msvc': 0.128.0
'@oxc-parser/binding-win32-ia32-msvc': 0.128.0
'@oxc-parser/binding-win32-x64-msvc': 0.128.0
oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0):
optionalDependencies:
'@oxc-resolver/binding-android-arm-eabi': 11.19.1
'@oxc-resolver/binding-android-arm64': 11.19.1
'@oxc-resolver/binding-darwin-arm64': 11.19.1
'@oxc-resolver/binding-darwin-x64': 11.19.1
'@oxc-resolver/binding-freebsd-x64': 11.19.1
'@oxc-resolver/binding-linux-arm-gnueabihf': 11.19.1
'@oxc-resolver/binding-linux-arm-musleabihf': 11.19.1
'@oxc-resolver/binding-linux-arm64-gnu': 11.19.1
'@oxc-resolver/binding-linux-arm64-musl': 11.19.1
'@oxc-resolver/binding-linux-ppc64-gnu': 11.19.1
'@oxc-resolver/binding-linux-riscv64-gnu': 11.19.1
'@oxc-resolver/binding-linux-riscv64-musl': 11.19.1
'@oxc-resolver/binding-linux-s390x-gnu': 11.19.1
'@oxc-resolver/binding-linux-x64-gnu': 11.19.1
'@oxc-resolver/binding-linux-x64-musl': 11.19.1
'@oxc-resolver/binding-openharmony-arm64': 11.19.1
'@oxc-resolver/binding-wasm32-wasi': 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)
'@oxc-resolver/binding-win32-arm64-msvc': 11.19.1
'@oxc-resolver/binding-win32-ia32-msvc': 11.19.1
'@oxc-resolver/binding-win32-x64-msvc': 11.19.1
transitivePeerDependencies:
- '@emnapi/core'
- '@emnapi/runtime'
p-limit@7.3.0: p-limit@7.3.0:
dependencies: dependencies:
yocto-queue: 1.2.2 yocto-queue: 1.2.2
@ -9273,6 +9868,8 @@ snapshots:
require-from-string@2.0.2: {} require-from-string@2.0.2: {}
resolve-pkg-maps@1.0.0: {}
restore-cursor@4.0.0: restore-cursor@4.0.0:
dependencies: dependencies:
onetime: 5.1.2 onetime: 5.1.2
@ -9467,6 +10064,8 @@ snapshots:
ansi-styles: 6.2.3 ansi-styles: 6.2.3
is-fullwidth-code-point: 5.1.0 is-fullwidth-code-point: 5.1.0
smol-toml@1.6.1: {}
snowflake-sdk@2.4.1(asn1.js@5.4.1): snowflake-sdk@2.4.1(asn1.js@5.4.1):
dependencies: dependencies:
'@aws-crypto/sha256-js': 5.2.0 '@aws-crypto/sha256-js': 5.2.0
@ -9558,6 +10157,8 @@ snapshots:
strip-json-comments@2.0.1: {} strip-json-comments@2.0.1: {}
strip-json-comments@5.0.3: {}
strnum@2.2.3: {} strnum@2.2.3: {}
stubs@3.0.0: {} stubs@3.0.0: {}
@ -9689,6 +10290,8 @@ snapshots:
uglify-js@3.19.3: uglify-js@3.19.3:
optional: true optional: true
unbash@3.0.0: {}
undici-types@7.16.0: {} undici-types@7.16.0: {}
unified@11.0.5: unified@11.0.5:
@ -9811,6 +10414,8 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- msw - msw
walk-up-path@4.0.0: {}
web-namespaces@2.0.1: {} web-namespaces@2.0.1: {}
web-streams-polyfill@3.3.3: {} web-streams-polyfill@3.3.3: {}

View file

@ -151,10 +151,6 @@ export function publicNpmPackageJson(cliPackageJson, dependencies, version = PUB
} }
function bundledWorkspacePackageJson(packageJson) { function bundledWorkspacePackageJson(packageJson) {
const dependencies = Object.fromEntries(
Object.entries(packageJson.dependencies ?? {}).filter(([name]) => !isWorkspacePackageName(name)),
);
return { return {
name: packageJson.name, name: packageJson.name,
version: packageJson.version ?? PUBLIC_NPM_PACKAGE_VERSION, version: packageJson.version ?? PUBLIC_NPM_PACKAGE_VERSION,
@ -164,7 +160,6 @@ function bundledWorkspacePackageJson(packageJson) {
types: packageJson.types, types: packageJson.types,
exports: packageJson.exports, exports: packageJson.exports,
files: packageJson.files, files: packageJson.files,
dependencies: sortedObject(Object.entries(dependencies)),
license: packageJson.license ?? 'Apache-2.0', license: packageJson.license ?? 'Apache-2.0',
}; };
} }

View file

@ -250,7 +250,7 @@ describe('createPublicNpmPackageTree', () => {
await readFile(join(layout.packRoot, 'node_modules', '@ktx', 'context', 'package.json'), 'utf8'), await readFile(join(layout.packRoot, 'node_modules', '@ktx', 'context', 'package.json'), 'utf8'),
); );
assert.equal(bundledContextJson.private, true); assert.equal(bundledContextJson.private, true);
assert.deepEqual(bundledContextJson.dependencies, { yaml: '^2.8.2' }); assert.equal(bundledContextJson.dependencies, undefined);
} finally { } finally {
await rm(root, { recursive: true, force: true }); await rm(root, { recursive: true, force: true });
} }

View file

@ -22,10 +22,6 @@ function publicPackagePattern(text) {
return new RegExp(text.replaceAll('{package}', escapeRegExp(publicNpmPackageName()))); return new RegExp(text.replaceAll('{package}', escapeRegExp(publicNpmPackageName())));
} }
function runtimeWheelPackagePattern(text) {
return new RegExp(text.replaceAll('{package}', escapeRegExp(runtimeWheelPackageName())));
}
describe('standalone example docs', () => { describe('standalone example docs', () => {
it('documents the local warehouse example from the examples index', async () => { it('documents the local warehouse example from the examples index', async () => {
const examples = await readText('examples/README.md'); const examples = await readText('examples/README.md');

View file

@ -459,9 +459,6 @@ export function npmSmokePackageJson(layout) {
dependencies: { dependencies: {
'@kaelio/ktx': `file:${layout.cliTarball}`, '@kaelio/ktx': `file:${layout.cliTarball}`,
}, },
devDependencies: {
'better-sqlite3': '^12.6.2',
},
}; };
} }
@ -485,11 +482,11 @@ if (typeof cli.runKtxCli !== 'function') {
export function npmRuntimeSmokeSource() { export function npmRuntimeSmokeSource() {
return ` return `
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import Database from 'better-sqlite3';
import { execFile } from 'node:child_process'; import { execFile } from 'node:child_process';
import { access, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; import { access, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
import { tmpdir } from 'node:os'; import { tmpdir } from 'node:os';
import { join } from 'node:path'; import { join } from 'node:path';
import { DatabaseSync } from 'node:sqlite';
import { promisify } from 'node:util'; import { promisify } from 'node:util';
const execFileAsync = promisify(execFile); const execFileAsync = promisify(execFile);
@ -569,7 +566,7 @@ function getRunId(stdout) {
} }
async function writeSqliteWarehouse(projectDir) { async function writeSqliteWarehouse(projectDir) {
const database = new Database(join(projectDir, 'warehouse.db')); const database = new DatabaseSync(join(projectDir, 'warehouse.db'));
try { try {
database.exec(\` database.exec(\`
DROP TABLE IF EXISTS orders; DROP TABLE IF EXISTS orders;

View file

@ -27,8 +27,6 @@ import {
writeArtifactManifest, writeArtifactManifest,
} from './package-artifacts.mjs'; } from './package-artifacts.mjs';
const STALE_METABASE_UNSUPPORTED = ['Standalone Metabase scheduled fetch', 'is intentionally unsupported'].join(' ');
async function writeJson(path, value) { async function writeJson(path, value) {
await writeFile(path, `${JSON.stringify(value, null, 2)}\n`); await writeFile(path, `${JSON.stringify(value, null, 2)}\n`);
} }
@ -420,9 +418,7 @@ describe('verification snippets', () => {
assert.deepEqual(packageJson.dependencies, { assert.deepEqual(packageJson.dependencies, {
'@kaelio/ktx': `file:${layout.cliTarball}`, '@kaelio/ktx': `file:${layout.cliTarball}`,
}); });
assert.deepEqual(packageJson.devDependencies, { assert.equal(packageJson.devDependencies, undefined);
'better-sqlite3': '^12.6.2',
});
assert.equal( assert.equal(
npmSmokePnpmWorkspaceYaml(), npmSmokePnpmWorkspaceYaml(),
['packages:', ' - "."', 'allowBuilds:', ' better-sqlite3: true', ''].join('\n'), ['packages:', ' - "."', 'allowBuilds:', ' better-sqlite3: true', ''].join('\n'),
@ -465,7 +461,7 @@ describe('verification snippets', () => {
assert.match(source, /semantic-layer', 'warehouse', 'orders\.yaml'/); assert.match(source, /semantic-layer', 'warehouse', 'orders\.yaml'/);
assert.match(source, /run\('pnpm', \[\s*'exec',\s*'ktx',\s*'sl',\s*'list'/); assert.match(source, /run\('pnpm', \[\s*'exec',\s*'ktx',\s*'sl',\s*'list'/);
assert.match(source, /orders\.order_count/); assert.match(source, /orders\.order_count/);
assert.match(source, /sqlite3/); assert.match(source, /node:sqlite/);
assert.match(source, /driver: sqlite/); assert.match(source, /driver: sqlite/);
assert.match(source, /path: warehouse\.db/); assert.match(source, /path: warehouse\.db/);
assert.match(source, /live-database/); assert.match(source, /live-database/);
@ -473,7 +469,7 @@ describe('verification snippets', () => {
assert.match(source, /"mode": "compile_only"/); assert.match(source, /"mode": "compile_only"/);
assert.match(source, /"mode": "executed"/); assert.match(source, /"mode": "executed"/);
assert.match(source, /ktx sl query sqlite execute/); assert.match(source, /ktx sl query sqlite execute/);
assert.match(source, /import Database from 'better-sqlite3'/); assert.match(source, /import \{ DatabaseSync \} from 'node:sqlite'/);
assert.doesNotMatch(source, /run\('python'/); assert.doesNotMatch(source, /run\('python'/);
assert.match(source, /KTX_RUNTIME_ROOT/); assert.match(source, /KTX_RUNTIME_ROOT/);
assert.match(source, /managed-runtime/); assert.match(source, /managed-runtime/);

View file

@ -9,7 +9,6 @@ import { runWorkspaceKtx } from './run-ktx.mjs';
const scriptDir = dirname(fileURLToPath(import.meta.url)); const scriptDir = dirname(fileURLToPath(import.meta.url));
const ktxRootDir = resolve(scriptDir, '..'); const ktxRootDir = resolve(scriptDir, '..');
const repoRootDir = resolve(ktxRootDir, '..');
const defaultProjectDir = resolve(ktxRootDir, 'examples/orbit-relationship-verification'); const defaultProjectDir = resolve(ktxRootDir, 'examples/orbit-relationship-verification');
const defaultReportPath = resolve( const defaultReportPath = resolve(
ktxRootDir, ktxRootDir,