refactor: enforce ktx naming and AGENTS.md compliance sweep (#289)

Align the tree with AGENTS.md/CLAUDE.md conventions:

- Rewrite user-facing strings, docs, and tests to lowercase `ktx`
  (no bare uppercase `KTX` tokens remain outside literal identifiers).
- Drop the legacy `historicSql` migration path and its now-unused
  helpers, per the no-backward-compat rule.
- Remove `as unknown as` / `any` casts: narrow `BaseTool` generics to
  `z.ZodObject`, add a typed `createLookerClient`, and delete the dead
  `getParametersSchema`/`toAnthropicFormat` pre-AI-SDK helpers.
- Use `InvalidArgumentError` for Commander parse failures.
- Finish the adapter→connector prose conversion in the `ktx.yaml` docs
  while keeping the literal `adapters` config key.
This commit is contained in:
Andrey Avtomonov 2026-06-11 13:49:45 +02:00 committed by GitHub
parent 005c5fc860
commit 00cdf2de90
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
237 changed files with 844 additions and 974 deletions

View file

@ -32,7 +32,7 @@ export function runtimeWheelPyproject() {
return `[project]
name = "${RUNTIME_WHEEL_DISTRIBUTION_NAME}"
version = "${RUNTIME_WHEEL_PACKAGE_VERSION}"
description = "Bundled Python runtime payload for the KTX npm package"
description = "Bundled Python runtime payload for the ktx npm package"
readme = "README.md"
requires-python = ">=3.13"
license = "Apache-2.0"
@ -76,7 +76,7 @@ packages = ["semantic_layer", "ktx_daemon"]
export function runtimeWheelReadme() {
return `# kaelio-ktx Python runtime
Bundled Python runtime wheel for KTX.
Bundled Python runtime wheel for ktx.
This wheel is built from the repository's \`semantic_layer\` and
\`ktx_daemon\` source trees for inclusion in the npm package. It is not a

View file

@ -70,7 +70,7 @@ describe('runtimeWheelPyproject', () => {
});
describe('createRuntimeWheelBuildTree', () => {
it('copies KTX-owned Python packages into the build tree', async () => {
it('copies ktx-owned Python packages into the build tree', async () => {
const root = await mkdtemp(join(tmpdir(), 'ktx-runtime-wheel-test-'));
try {
await writeRuntimeSourceFixture(root);
@ -90,7 +90,7 @@ describe('createRuntimeWheelBuildTree', () => {
assert.match(pyproject, /name = "kaelio-ktx"/);
assert.match(pyproject, /local-embeddings = \[/);
const readme = await readFile(join(layout.buildRoot, 'README.md'), 'utf8');
assert.match(readme, /Bundled Python runtime wheel for KTX/);
assert.match(readme, /Bundled Python runtime wheel for ktx/);
} finally {
await rm(root, { recursive: true, force: true });
}

View file

@ -25,7 +25,7 @@ describe('scanFileContent', () => {
[],
);
assert.deepEqual(
scanFileContent('packages/cli/src/prompts/memory_agent_bundle_ingest_work_unit.md', 'Write output for KTX.'),
scanFileContent('packages/cli/src/prompts/memory_agent_bundle_ingest_work_unit.md', 'Write output for ktx.'),
[],
);
});
@ -83,7 +83,7 @@ describe('scanFileContent', () => {
);
});
it('rejects old KTX LLM port declarations in context', () => {
it('rejects old ktx LLM port declarations in context', () => {
const violations = [
...scanFileContent('packages/cli/src/context/agent/agent-runner.service.ts', 'export interface LlmProviderPort {}'),
...scanFileContent('packages/cli/src/context/scan/types.ts', 'export interface KtxScanLlmPort {}'),

View file

@ -20,8 +20,8 @@ async function readCiWorkflowOrSkip(testContext) {
return readFile(ciWorkflowPath, 'utf-8');
}
describe('KTX CI artifact upload contract', () => {
it('uploads verified KTX package artifacts from the standalone check job', async (testContext) => {
describe('ktx CI artifact upload contract', () => {
it('uploads verified ktx package artifacts from the standalone check job', async (testContext) => {
const workflow = await readCiWorkflowOrSkip(testContext);
if (workflow === null) {
return;

View file

@ -1,5 +1,5 @@
#!/bin/bash
# conductor-run.sh - Starts the long-lived local KTX daemon for Conductor.
# conductor-run.sh - Starts the long-lived local ktx daemon for Conductor.
#
# Uses a fixed port because Conductor runs this workspace in nonconcurrent mode.
@ -82,9 +82,9 @@ resolve_uv_for_project() {
printf '%s\n' "$workspace_uv"
}
echo "=== Starting KTX for Conductor ==="
echo "=== Starting ktx for Conductor ==="
echo "Building KTX packages..."
echo "Building ktx packages..."
pnpm run build
KTX_UV_BIN="$(resolve_uv_for_project "pyproject.toml")"
@ -94,5 +94,5 @@ if [ -f ".venv/bin/activate" ]; then
source .venv/bin/activate
fi
echo "KTX daemon: http://127.0.0.1:8765"
echo "ktx daemon: http://127.0.0.1:8765"
exec uv run ktx-daemon serve-http --host 127.0.0.1 --port 8765

View file

@ -42,7 +42,7 @@ describe('Conductor workspace scripts', () => {
assert.doesNotMatch(workspaceScript, /link_agent_skills_for_claude/);
});
it('runs the KTX daemon on the documented fixed local port', async () => {
it('runs the ktx daemon on the documented fixed local port', async () => {
const runScript = await readText('scripts/conductor-run.sh');
assert.match(runScript, /pnpm run build/);

View file

@ -1,5 +1,5 @@
#!/bin/bash
# conductor-setup.sh - Runs once when Conductor creates a KTX workspace.
# conductor-setup.sh - Runs once when Conductor creates a ktx workspace.
#
# Prepares the standalone pnpm + uv workspace and builds the local CLI.
@ -114,7 +114,7 @@ link_agent_overlays() {
fi
}
echo "=== Conductor KTX workspace setup ==="
echo "=== Conductor ktx workspace setup ==="
link_agent_overlays
@ -126,21 +126,21 @@ fi
KTX_UV_BIN="$(resolve_uv_for_project "pyproject.toml")"
export PATH="$(dirname "$KTX_UV_BIN"):$PATH"
echo "Installing KTX Python dependencies..."
echo "Installing ktx Python dependencies..."
uv sync --all-packages --all-groups
echo "Installing KTX JS dependencies..."
echo "Installing ktx JS dependencies..."
pnpm install --frozen-lockfile --prefer-offline
echo "Rebuilding native JS dependencies..."
pnpm run native:rebuild
echo "Building KTX runtime artifacts..."
echo "Building ktx runtime artifacts..."
# Builds every internal package (llm/context/connectors/cli) before producing
# the wheel + npm tarball, so a separate `pnpm run build` would be redundant.
pnpm run artifacts:build
echo "Running KTX setup doctor..."
echo "Running ktx setup doctor..."
# Run from a temp dir so `ktx status` doesn't walk up into a parent ktx.yaml
# (e.g. ~/ktx.yaml) and report on an unrelated project.
KTX_CLI_BIN="$PWD/packages/cli/dist/bin.js"

View file

@ -49,7 +49,7 @@ describe('installed live-database artifact smoke helpers', () => {
);
});
it('writes a public database ingest KTX project config with SQLite local state', () => {
it('writes a public database ingest ktx project config with SQLite local state', () => {
assert.equal(
buildKtxYaml('postgresql://ktx:postgres@127.0.0.1:15432/warehouse'), // pragma: allowlist secret
[

View file

@ -73,7 +73,7 @@ async function writePinnedPosixLauncher(globalBin, binPath, binaryName, writeFil
const launcherPath = join(globalBin, binaryName);
const script = [
'#!/bin/sh',
'# Generated by `pnpm run link:dev` in the KTX workspace.',
'# Generated by `pnpm run link:dev` in the ktx workspace.',
'# Keep this launcher pinned to the Node binary that built native dependencies.',
`exec ${shellDoubleQuote(process.execPath)} ${shellDoubleQuote(binPath)} "$@"`,
'',
@ -88,7 +88,7 @@ async function writePinnedWindowsLauncher(globalBin, binPath, binaryName, writeF
const launcherPath = join(globalBin, `${binaryName}.cmd`);
const script = [
'@echo off',
'REM Generated by `pnpm run link:dev` in the KTX workspace.',
'REM Generated by `pnpm run link:dev` in the ktx workspace.',
`"${process.execPath}" "${binPath}" %*`,
'',
].join('\r\n');
@ -179,7 +179,7 @@ if (import.meta.url === pathToFileURL(process.argv[1]).href) {
checkOnly: hasFlag('--check-only'),
binaryName: optionValue('--name', 'ktx-dev'),
});
process.stdout.write(`KTX CLI bin: ${result.binPath}\n`);
process.stdout.write(`ktx CLI bin: ${result.binPath}\n`);
if (result.linked) {
process.stdout.write(`Linked binary: ${result.binaryName}\n`);
process.stdout.write(`Verified: ${result.verification.output}\n`);

View file

@ -312,7 +312,7 @@ export async function runLocalEmbeddingsRuntimeSmoke(options = {}) {
timeoutMs: commands[2].timeoutMs,
});
requireSuccess(commands[2].label, install);
requireOutput(commands[2].label, install, /Installed KTX Python runtime/);
requireOutput(commands[2].label, install, /Installed ktx Python runtime/);
requireOutput(commands[2].label, install, /features: core, local-embeddings/);
const readyStatus = parseJsonStdout(
@ -342,11 +342,11 @@ export async function runLocalEmbeddingsRuntimeSmoke(options = {}) {
const embeddingResponse = await postJson(
baseUrl,
'/embeddings/compute',
{ text: 'KTX local embeddings release smoke' },
{ text: 'ktx local embeddings release smoke' },
900_000,
);
validateEmbeddingResponse(embeddingResponse, 384);
process.stdout.write('KTX daemon computed a 384-dimensional embedding\n');
process.stdout.write('ktx daemon computed a 384-dimensional embedding\n');
const setup = await run(commands[5].command, commands[5].args, {
cwd: installDir,
@ -363,7 +363,7 @@ export async function runLocalEmbeddingsRuntimeSmoke(options = {}) {
if (/base_url:/.test(config)) {
throw new Error(`ktx.yaml should omit base_url for managed local embeddings:\n${config}`);
}
process.stdout.write('KTX setup persisted managed local embeddings (no base_url)\n');
process.stdout.write('ktx setup persisted managed local embeddings (no base_url)\n');
const stop = await run(commands[6].command, commands[6].args, {
cwd: installDir,
@ -372,9 +372,9 @@ export async function runLocalEmbeddingsRuntimeSmoke(options = {}) {
});
requireSuccess(commands[6].label, stop);
daemonStarted = false;
requireOutput(commands[6].label, stop, /Stopped KTX daemon/);
requireOutput(commands[6].label, stop, /Stopped ktx daemon/);
process.stdout.write('KTX local embeddings runtime smoke verified\n');
process.stdout.write('ktx local embeddings runtime smoke verified\n');
} finally {
if (daemonStarted) {
await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'stop'], {
@ -395,7 +395,7 @@ async function main() {
const args = process.argv.slice(2);
const optIn = localEmbeddingsSmokeOptIn(process.env, args);
if (!optIn.run) {
process.stdout.write(`Skipping KTX local embeddings runtime smoke. ${optIn.message}\n`);
process.stdout.write(`Skipping ktx local embeddings runtime smoke. ${optIn.message}\n`);
if (args.includes('--require-opt-in')) {
process.exitCode = 1;
}

View file

@ -129,13 +129,13 @@ describe('localEmbeddingsSmokeCommands', () => {
describe('parseDaemonBaseUrl', () => {
it('extracts the daemon URL from runtime start output', () => {
assert.equal(
parseDaemonBaseUrl('Started KTX daemon\nurl: http://127.0.0.1:61234\nfeatures: local-embeddings\n'),
parseDaemonBaseUrl('Started ktx daemon\nurl: http://127.0.0.1:61234\nfeatures: local-embeddings\n'),
'http://127.0.0.1:61234',
);
});
it('rejects output without a daemon URL', () => {
assert.throws(() => parseDaemonBaseUrl('Started KTX daemon\n'), /Daemon URL was not printed/);
assert.throws(() => parseDaemonBaseUrl('Started ktx daemon\n'), /Daemon URL was not printed/);
});
});

View file

@ -791,7 +791,7 @@ try {
requireSuccessWithStderr(
'ktx sl query first managed runtime install',
slQuery,
/Installing KTX Python runtime \\(core\\) with uv[\\s\\S]*KTX Python runtime ready:/,
/Installing ktx Python runtime \\(core\\) with uv[\\s\\S]*ktx Python runtime ready:/,
);
requireOutput('ktx sl query first managed runtime install', slQuery, /"mode": "compile_only"/);
requireOutput('ktx sl query first managed runtime install', slQuery, /orders/);
@ -836,26 +836,26 @@ try {
const runtimeDoctor = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'admin', 'runtime', 'status'])));
requireSuccess('ktx admin runtime status', runtimeDoctor);
requireOutput('ktx admin runtime status', runtimeDoctor, /KTX Python runtime/);
requireOutput('ktx admin runtime status', runtimeDoctor, /ktx Python runtime/);
requireOutput('ktx admin runtime status', runtimeDoctor, /status: ready/);
process.stdout.write('ktx admin runtime status verified\\n');
const runtimeStart = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'admin', 'runtime', 'start'])));
requireSuccess('ktx admin runtime start', runtimeStart);
daemonStarted = true;
requireOutput('ktx admin runtime start', runtimeStart, /Started KTX daemon/);
requireOutput('ktx admin runtime start', runtimeStart, /Started ktx daemon/);
requireOutput('ktx admin runtime start', runtimeStart, /url: http:\\/\\/127\\.0\\.0\\.1:\\d+/);
requireOutput('ktx admin runtime start', runtimeStart, /features: core/);
const runtimeStartReuse = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'admin', 'runtime', 'start'])));
requireSuccess('ktx admin runtime start reuse', runtimeStartReuse);
requireOutput('ktx admin runtime start reuse', runtimeStartReuse, /Using existing KTX daemon/);
requireOutput('ktx admin runtime start reuse', runtimeStartReuse, /Using existing ktx daemon/);
requireOutput('ktx admin runtime start reuse', runtimeStartReuse, /features: core/);
const runtimeStop = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'admin', 'runtime', 'stop'])));
requireSuccess('ktx admin runtime stop', runtimeStop);
daemonStarted = false;
requireOutput('ktx admin runtime stop', runtimeStop, /Stopped KTX daemon/);
requireOutput('ktx admin runtime stop', runtimeStop, /Stopped ktx daemon/);
process.stdout.write('ktx admin runtime daemon lifecycle verified\\n');
const databaseIngest = await run(
@ -952,7 +952,7 @@ try {
const doctor = await run(...Object.values(pnpmCommand(['exec', 'ktx', 'status', '--verbose', '--no-input'])));
assert.ok([0, 1].includes(doctor.code), 'ktx status setup exit code must be 0 or 1');
requireStdout('ktx status setup', doctor, /KTX status/);
requireStdout('ktx status setup', doctor, /ktx status/);
requireStdout('ktx status setup', doctor, /No project here yet\\./);
requireStdout('ktx status setup', doctor, /ktx setup/);
requireStdout('ktx status setup', doctor, /Node 22\\+/);

View file

@ -516,8 +516,8 @@ describe('verification snippets', () => {
assert.match(source, /managed-runtime/);
assert.match(source, /ktx admin runtime status missing/);
assert.match(source, /runtimeStatusBefore\.kind, 'missing'/);
assert.ok(source.includes(String.raw`Installing KTX Python runtime \(core\) with uv`));
assert.match(source, /KTX Python runtime ready:/);
assert.ok(source.includes(String.raw`Installing ktx Python runtime \(core\) with uv`));
assert.match(source, /ktx Python runtime ready:/);
assert.match(source, /ktx admin runtime status ready/);
assert.match(source, /runtimeStatusAfter\.kind, 'ready'/);
assert.match(source, /runtimeStatusAfter\.manifest\.features/);
@ -525,7 +525,7 @@ describe('verification snippets', () => {
assert.match(source, /status: ready/);
assert.match(source, /ktx admin runtime start/);
assert.match(source, /ktx admin runtime start reuse/);
assert.match(source, /Using existing KTX daemon/);
assert.match(source, /Using existing ktx daemon/);
assert.match(source, /ktx admin runtime stop/);
assert.doesNotMatch(source, /ktx admin runtime prune/);
assert.doesNotMatch(source, /staleRuntimeDir/);
@ -557,7 +557,7 @@ describe('verification snippets', () => {
assert.match(source, /Usage: ktx setup/);
assert.doesNotMatch(source, new RegExp(["'demo'", "'--mode'", "'deterministic'"].join(', ')));
assert.match(source, /'status', '--verbose', '--no-input'/);
assert.match(source, /KTX status/);
assert.match(source, /ktx status/);
assert.match(source, /No project here yet/);
assert.doesNotMatch(source, /function requireProjectStderr/);
assert.match(source, /Object\.keys\(packageJson\.dependencies\)/);

View file

@ -36,7 +36,7 @@ export async function ensureCliBinExecutable(rootDir = ktxRootDir()) {
if (import.meta.url === pathToFileURL(process.argv[1]).href) {
try {
const binPath = await ensureCliBinExecutable();
process.stdout.write(`Prepared KTX CLI bin: ${binPath}\n`);
process.stdout.write(`Prepared ktx CLI bin: ${binPath}\n`);
} catch (error) {
process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
process.exitCode = 1;

View file

@ -143,7 +143,7 @@ async function main() {
if (config.requireConfig) {
throw new Error(config.reason);
}
process.stdout.write(`Published KTX package smoke skipped: ${config.reason}\n`);
process.stdout.write(`Published ktx package smoke skipped: ${config.reason}\n`);
return;
}

View file

@ -197,7 +197,7 @@ function formatBlocked(result) {
export function formatOrbitVerificationMarkdown(result) {
const lines = [
'# KTX Relationship Discovery Orbit Verification',
'# ktx Relationship Discovery Orbit Verification',
'',
`Date: ${result.date}`,
'',
@ -323,7 +323,7 @@ export async function runOrbitVerification(options = {}) {
projectDir,
scanCommand,
scanExitCode: scan.exitCode,
blocker: 'KTX scan completed without printing a Run id',
blocker: 'ktx scan completed without printing a Run id',
scanStdout: scan.stdout,
scanStderr: scan.stderr,
};
@ -337,7 +337,7 @@ export async function runOrbitVerification(options = {}) {
projectDir,
scanCommand,
scanExitCode: scan.exitCode,
blocker: 'KTX scan completed without printing a report artifact path',
blocker: 'ktx scan completed without printing a report artifact path',
scanStdout: scan.stdout,
scanStderr: scan.stderr,
};

View file

@ -51,13 +51,13 @@ function successReportJson() {
function successfulRunKtxScan(calls = []) {
return async (args, io) => {
calls.push(args);
io.stdout.write('KTX scan completed\nRun: scan-orbit-1\nConnection: orbit\n Report: reports/scan-report.json\n');
io.stdout.write('ktx scan completed\nRun: scan-orbit-1\nConnection: orbit\n Report: reports/scan-report.json\n');
return 0;
};
}
describe('relationship Orbit verification helper', () => {
it('exposes the Orbit verification command from the KTX workspace package', async () => {
it('exposes the Orbit verification command from the ktx workspace package', async () => {
const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
assert.equal(
@ -145,8 +145,8 @@ describe('relationship Orbit verification helper', () => {
});
it('extracts the run id from human scan output', () => {
assert.equal(extractRunId(`KTX scan completed\nStatus: done\nRun: scan-orbit-1\nConnection: orbit\n`), 'scan-orbit-1');
assert.equal(extractRunId('KTX scan completed without a run line\n'), null);
assert.equal(extractRunId(`ktx scan completed\nStatus: done\nRun: scan-orbit-1\nConnection: orbit\n`), 'scan-orbit-1');
assert.equal(extractRunId('ktx scan completed without a run line\n'), null);
assert.equal(extractReportPath('Artifacts\n Report: reports/scan-report.json\n'), 'reports/scan-report.json');
});
@ -159,12 +159,12 @@ describe('relationship Orbit verification helper', () => {
scanCommand: 'internal runKtxScan connection=orbit mode=relationships projectDir=/tmp/orbit-project',
reportPath: '/tmp/orbit-project/reports/scan-report.json',
scanExitCode: 0,
scanStdout: 'KTX scan completed\nRun: scan-orbit-1\n',
scanStdout: 'ktx scan completed\nRun: scan-orbit-1\n',
scanStderr: '',
report: JSON.parse(successReportJson()),
});
assert.match(markdown, /# KTX Relationship Discovery Orbit Verification/);
assert.match(markdown, /# ktx Relationship Discovery Orbit Verification/);
assert.match(markdown, /Outcome/);
assert.match(markdown, /Exit code: 0/);
assert.match(markdown, /Accepted: 14/);

View file

@ -319,9 +319,9 @@ async function main() {
return;
}
process.stdout.write(`KTX release mode: ${report.releaseMode}\n`);
process.stdout.write(`KTX source revision: ${report.sourceRevision ?? 'local'}\n`);
process.stdout.write(`KTX packages: ${report.packageNames.join(', ')}\n`);
process.stdout.write(`ktx release mode: ${report.releaseMode}\n`);
process.stdout.write(`ktx source revision: ${report.sourceRevision ?? 'local'}\n`);
process.stdout.write(`ktx packages: ${report.packageNames.join(', ')}\n`);
process.stdout.write(`Published package smoke: ${report.publishedPackageSmokeGate.status}\n`);
process.stdout.write(`Published package smoke script: ${report.publishedPackageSmokeGate.script}\n`);
process.stdout.write(`Published package smoke reason: ${report.publishedPackageSmokeGate.reason}\n`);

View file

@ -102,7 +102,7 @@ async function writeReadyFixture(root, options = {}) {
}
describe('release readiness policy', () => {
it('reads the checked release policy path from the KTX root', async () => {
it('reads the checked release policy path from the ktx root', async () => {
const root = await mkdtemp(join(tmpdir(), 'ktx-release-policy-test-'));
try {
const policy = releasePolicy();

View file

@ -161,13 +161,13 @@ export async function runWorkspaceKtx(argv, options = {}) {
if (needsBuild) {
stderr.write(
binExists
? 'KTX CLI build output is stale. Rebuilding it now with `pnpm run build`...\n'
: 'KTX CLI build output is missing. Building it now with `pnpm run build`...\n',
? 'ktx CLI build output is stale. Rebuilding it now with `pnpm run build`...\n'
: 'ktx CLI build output is missing. Building it now with `pnpm run build`...\n',
);
const buildExitCode = await runCommand('pnpm', ['run', 'build'], { cwd: rootDir, env: commandEnv });
if (buildExitCode !== 0) {
stderr.write(
'\nKTX CLI build failed. Run `pnpm run setup:dev` from the KTX directory, then retry this command.\n',
'\nktx CLI build failed. Run `pnpm run setup:dev` from the ktx directory, then retry this command.\n',
);
return buildExitCode;
}

View file

@ -153,7 +153,7 @@ test('runWorkspaceKtx builds the workspace CLI before running it when dist is mi
],
);
assert.deepEqual(logs, [
['stderr', 'KTX CLI build output is missing. Building it now with `pnpm run build`...\n'],
['stderr', 'ktx CLI build output is missing. Building it now with `pnpm run build`...\n'],
['stdout', 'build ok\n'],
['stdout', 'Replay complete\n'],
]);
@ -216,7 +216,7 @@ test('runWorkspaceKtx rebuilds before running when workspace sources are newer t
],
);
assert.deepEqual(logs, [
['stderr', 'KTX CLI build output is stale. Rebuilding it now with `pnpm run build`...\n'],
['stderr', 'ktx CLI build output is stale. Rebuilding it now with `pnpm run build`...\n'],
['stdout', 'build ok\n'],
['stdout', '{"status":"ready"}\n'],
]);
@ -256,7 +256,7 @@ test('runWorkspaceKtx skips rebuild when only bin.js is older than sources but s
},
execFile: async (command, args, options) => {
calls.push({ command, args, cwd: options.cwd });
return { stdout: 'KTX status\n', stderr: '' };
return { stdout: 'ktx status\n', stderr: '' };
},
writeFile: async (path, contents) => {
writes.push({ path, contents });
@ -271,7 +271,7 @@ test('runWorkspaceKtx skips rebuild when only bin.js is older than sources but s
[[process.execPath, ['/workspace/ktx/packages/cli/dist/bin.js', 'status']]],
);
assert.deepEqual(writes, []);
assert.deepEqual(logs, [['stdout', 'KTX status\n']]);
assert.deepEqual(logs, [['stdout', 'ktx status\n']]);
});
test('runWorkspaceKtx rebuilds when stamp is missing even if bin.js exists', async () => {
@ -308,7 +308,7 @@ test('runWorkspaceKtx rebuilds when stamp is missing even if bin.js exists', asy
if (command === 'pnpm') {
return { stdout: 'build ok\n', stderr: '' };
}
return { stdout: 'KTX status\n', stderr: '' };
return { stdout: 'ktx status\n', stderr: '' };
},
writeFile: async (path, contents) => {
writes.push({ path, contents });
@ -327,7 +327,7 @@ test('runWorkspaceKtx rebuilds when stamp is missing even if bin.js exists', asy
);
assert.deepEqual(logs[0], [
'stderr',
'KTX CLI build output is stale. Rebuilding it now with `pnpm run build`...\n',
'ktx CLI build output is stale. Rebuilding it now with `pnpm run build`...\n',
]);
assert.deepEqual(writes, [
{ path: '/workspace/ktx/packages/cli/dist/.ktx-build-stamp', contents: '' },

View file

@ -12,7 +12,7 @@ function assertIncludesAll(text, values) {
}
}
describe('standalone KTX CI workflow', () => {
describe('standalone ktx CI workflow', () => {
it('runs package checks in parallel jobs from the repository root', async () => {
const workflow = await readText('.github/workflows/ci.yml');

View file

@ -27,7 +27,7 @@ async function readText(path) {
const DAEMON_PYPROJECT = `[project]
name = "ktx-daemon"
version = "0.4.0"
description = "Portable compute package for KTX semantic-layer operations"
description = "Portable compute package for ktx semantic-layer operations"
[build-system]
requires = ["hatchling"]