mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-13 08:15:14 +02:00
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:
parent
005c5fc860
commit
00cdf2de90
237 changed files with 844 additions and 974 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {}'),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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/);
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
[
|
||||
|
|
|
|||
|
|
@ -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`);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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/);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -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\\+/);
|
||||
|
|
|
|||
|
|
@ -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\)/);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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/);
|
||||
|
|
|
|||
|
|
@ -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`);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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: '' },
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue