mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-07 07:55:13 +02:00
feat(cli): add ktx admin reindex (#160)
* feat(cli): add admin reindex * fix: keep lexical-only reindex incremental
This commit is contained in:
parent
3db3e724cb
commit
6dbb0c8b3a
53 changed files with 1640 additions and 393 deletions
|
|
@ -193,12 +193,12 @@ describe('standalone example docs', () => {
|
|||
|
||||
assert.match(rootReadme, publicPackagePattern('npm install -g {package}'));
|
||||
assert.match(quickstart, publicPackagePattern('npm install -g {package}'));
|
||||
assert.match(quickstart, /ktx dev runtime install --feature local-embeddings --yes/);
|
||||
assert.match(quickstart, /ktx dev runtime start --feature local-embeddings/);
|
||||
assert.match(quickstart, /ktx admin runtime install --feature local-embeddings --yes/);
|
||||
assert.match(quickstart, /ktx admin runtime start --feature local-embeddings/);
|
||||
assert.match(packageArtifacts, /requires `uv` on `PATH`/);
|
||||
assert.match(packageArtifacts, /ktx dev runtime status/);
|
||||
assert.match(packageArtifacts, /ktx dev runtime status/);
|
||||
assert.doesNotMatch(packageArtifacts, /ktx dev runtime prune/);
|
||||
assert.match(packageArtifacts, /ktx admin runtime status/);
|
||||
assert.match(packageArtifacts, /ktx admin runtime status/);
|
||||
assert.doesNotMatch(packageArtifacts, /ktx admin runtime prune/);
|
||||
assert.match(
|
||||
packageArtifacts,
|
||||
new RegExp(
|
||||
|
|
@ -229,9 +229,9 @@ describe('standalone example docs', () => {
|
|||
assert.doesNotMatch(readme, /standalone Python distributions/);
|
||||
assert.doesNotMatch(readme, /installs the Python artifacts directly/);
|
||||
assert.match(readme, /requires `uv` on `PATH`/);
|
||||
assert.match(readme, /ktx dev runtime status/);
|
||||
assert.match(readme, /ktx dev runtime status/);
|
||||
assert.doesNotMatch(readme, /ktx dev runtime prune/);
|
||||
assert.match(readme, /ktx admin runtime status/);
|
||||
assert.match(readme, /ktx admin runtime status/);
|
||||
assert.doesNotMatch(readme, /ktx admin runtime prune/);
|
||||
assert.doesNotMatch(readme, /@ktx\/context/);
|
||||
assert.doesNotMatch(readme, /@ktx\/cli/);
|
||||
assert.doesNotMatch(readme, /python -m ktx_daemon semantic-validate/);
|
||||
|
|
@ -241,7 +241,7 @@ describe('standalone example docs', () => {
|
|||
const rootReadme = await readText('README.md');
|
||||
const cliMeta = await readText('docs-site/content/docs/cli-reference/meta.json');
|
||||
const ingestReference = await readText('docs-site/content/docs/cli-reference/ktx-ingest.mdx');
|
||||
const devReference = await readText('docs-site/content/docs/cli-reference/ktx-dev.mdx');
|
||||
const adminReference = await readText('docs-site/content/docs/cli-reference/ktx-admin.mdx');
|
||||
const setupReference = await readText('docs-site/content/docs/cli-reference/ktx-setup.mdx');
|
||||
const buildingContext = await readText('docs-site/content/docs/guides/building-context.mdx');
|
||||
const contextSources = await readText('docs-site/content/docs/integrations/context-sources.mdx');
|
||||
|
|
@ -275,7 +275,7 @@ describe('standalone example docs', () => {
|
|||
assert.doesNotMatch(ingestReference, /--adapter/);
|
||||
assert.doesNotMatch(ingestReference, /ktx ingest watch/);
|
||||
assert.doesNotMatch(ingestReference, /live-database/);
|
||||
assert.doesNotMatch(devReference, /ktx scan/);
|
||||
assert.doesNotMatch(adminReference, /ktx scan/);
|
||||
assert.doesNotMatch(buildingContext, /ktx ingest watch/);
|
||||
assert.doesNotMatch(buildingContext, /ktx ingest status/);
|
||||
assert.doesNotMatch(buildingContext, /ktx ingest replay/);
|
||||
|
|
|
|||
|
|
@ -237,17 +237,17 @@ function parseDaemonBaseUrl(stdout) {
|
|||
}
|
||||
|
||||
async function startDaemon(cleanInstallDir) {
|
||||
const result = await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'start'], {
|
||||
const result = await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'start'], {
|
||||
cwd: cleanInstallDir,
|
||||
env: managedRuntimeEnv(cleanInstallDir),
|
||||
timeout: 120_000,
|
||||
});
|
||||
requireSuccess('ktx dev runtime start', result);
|
||||
requireSuccess('ktx admin runtime start', result);
|
||||
return parseDaemonBaseUrl(result.stdout);
|
||||
}
|
||||
|
||||
async function stopDaemon(cleanInstallDir) {
|
||||
await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'stop'], {
|
||||
await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'stop'], {
|
||||
cwd: cleanInstallDir,
|
||||
env: managedRuntimeEnv(cleanInstallDir),
|
||||
timeout: 30_000,
|
||||
|
|
@ -271,7 +271,7 @@ async function prepareCleanInstall(layout, cleanInstallDir) {
|
|||
await run('pnpm', ['install'], { cwd: cleanInstallDir, timeout: 120_000 }).then((result) =>
|
||||
requireSuccess('pnpm install clean artifact project', result),
|
||||
);
|
||||
await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'install', '--yes'], {
|
||||
await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'install', '--yes'], {
|
||||
cwd: cleanInstallDir,
|
||||
env: managedRuntimeEnv(cleanInstallDir),
|
||||
timeout: 120_000,
|
||||
|
|
|
|||
|
|
@ -74,27 +74,27 @@ export function localEmbeddingsSmokeCommands(input) {
|
|||
timeoutMs: 60_000,
|
||||
},
|
||||
{
|
||||
label: 'ktx dev runtime status missing',
|
||||
label: 'ktx admin runtime status missing',
|
||||
command: 'pnpm',
|
||||
args: ['exec', 'ktx', 'dev', 'runtime', 'status', '--json'],
|
||||
args: ['exec', 'ktx', 'admin', 'runtime', 'status', '--json'],
|
||||
timeoutMs: 60_000,
|
||||
},
|
||||
{
|
||||
label: 'ktx dev runtime install local embeddings',
|
||||
label: 'ktx admin runtime install local embeddings',
|
||||
command: 'pnpm',
|
||||
args: ['exec', 'ktx', 'dev', 'runtime', 'install', '--feature', 'local-embeddings', '--yes'],
|
||||
args: ['exec', 'ktx', 'admin', 'runtime', 'install', '--feature', 'local-embeddings', '--yes'],
|
||||
timeoutMs: 1_200_000,
|
||||
},
|
||||
{
|
||||
label: 'ktx dev runtime status local embeddings ready',
|
||||
label: 'ktx admin runtime status local embeddings ready',
|
||||
command: 'pnpm',
|
||||
args: ['exec', 'ktx', 'dev', 'runtime', 'status', '--json'],
|
||||
args: ['exec', 'ktx', 'admin', 'runtime', 'status', '--json'],
|
||||
timeoutMs: 60_000,
|
||||
},
|
||||
{
|
||||
label: 'ktx dev runtime start local embeddings',
|
||||
label: 'ktx admin runtime start local embeddings',
|
||||
command: 'pnpm',
|
||||
args: ['exec', 'ktx', 'dev', 'runtime', 'start', '--feature', 'local-embeddings'],
|
||||
args: ['exec', 'ktx', 'admin', 'runtime', 'start', '--feature', 'local-embeddings'],
|
||||
timeoutMs: 300_000,
|
||||
},
|
||||
{
|
||||
|
|
@ -118,9 +118,9 @@ export function localEmbeddingsSmokeCommands(input) {
|
|||
timeoutMs: 900_000,
|
||||
},
|
||||
{
|
||||
label: 'ktx dev runtime stop local embeddings',
|
||||
label: 'ktx admin runtime stop local embeddings',
|
||||
command: 'pnpm',
|
||||
args: ['exec', 'ktx', 'dev', 'runtime', 'stop'],
|
||||
args: ['exec', 'ktx', 'admin', 'runtime', 'stop'],
|
||||
timeoutMs: 60_000,
|
||||
},
|
||||
];
|
||||
|
|
@ -374,7 +374,7 @@ export async function runLocalEmbeddingsRuntimeSmoke(options = {}) {
|
|||
process.stdout.write('KTX local embeddings runtime smoke verified\n');
|
||||
} finally {
|
||||
if (daemonStarted) {
|
||||
await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'stop'], {
|
||||
await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'stop'], {
|
||||
cwd: installDir,
|
||||
env: smokeEnv,
|
||||
timeoutMs: 60_000,
|
||||
|
|
|
|||
|
|
@ -89,23 +89,23 @@ describe('localEmbeddingsSmokeCommands', () => {
|
|||
|
||||
assert.deepEqual(commands.map((command) => command.label), [
|
||||
'ktx public package version',
|
||||
'ktx dev runtime status missing',
|
||||
'ktx dev runtime install local embeddings',
|
||||
'ktx dev runtime status local embeddings ready',
|
||||
'ktx dev runtime start local embeddings',
|
||||
'ktx admin runtime status missing',
|
||||
'ktx admin runtime install local embeddings',
|
||||
'ktx admin runtime status local embeddings ready',
|
||||
'ktx admin runtime start local embeddings',
|
||||
'ktx setup local embeddings',
|
||||
'ktx dev runtime stop local embeddings',
|
||||
'ktx admin runtime stop local embeddings',
|
||||
]);
|
||||
assert.deepEqual(commands[2], {
|
||||
label: 'ktx dev runtime install local embeddings',
|
||||
label: 'ktx admin runtime install local embeddings',
|
||||
command: 'pnpm',
|
||||
args: ['exec', 'ktx', 'dev', 'runtime', 'install', '--feature', 'local-embeddings', '--yes'],
|
||||
args: ['exec', 'ktx', 'admin', 'runtime', 'install', '--feature', 'local-embeddings', '--yes'],
|
||||
timeoutMs: 1_200_000,
|
||||
});
|
||||
assert.deepEqual(commands[4], {
|
||||
label: 'ktx dev runtime start local embeddings',
|
||||
label: 'ktx admin runtime start local embeddings',
|
||||
command: 'pnpm',
|
||||
args: ['exec', 'ktx', 'dev', 'runtime', 'start', '--feature', 'local-embeddings'],
|
||||
args: ['exec', 'ktx', 'admin', 'runtime', 'start', '--feature', 'local-embeddings'],
|
||||
timeoutMs: 300_000,
|
||||
});
|
||||
assert.deepEqual(commands[5].args, [
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ export async function findPythonArtifacts(pythonDir) {
|
|||
files,
|
||||
RUNTIME_WHEEL_DISTRIBUTION_NAME,
|
||||
'.whl',
|
||||
'kaelio-ktx dev runtime wheel',
|
||||
'kaelio-ktx runtime wheel',
|
||||
pythonDir,
|
||||
RUNTIME_WHEEL_PACKAGE_VERSION,
|
||||
),
|
||||
|
|
@ -606,8 +606,8 @@ try {
|
|||
requireOutput('ktx public package version', version, await installedPackageVersionPattern());
|
||||
|
||||
const runtimeStatusBefore = parseJsonResultWithExitCode(
|
||||
'ktx dev runtime status missing',
|
||||
await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'status', '--json']),
|
||||
'ktx admin runtime status missing',
|
||||
await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'status', '--json']),
|
||||
1,
|
||||
);
|
||||
assert.equal(runtimeStatusBefore.kind, 'missing');
|
||||
|
|
@ -768,8 +768,8 @@ try {
|
|||
requireOutput('ktx sl query first managed runtime install', slQuery, /orders/);
|
||||
|
||||
const runtimeStatusAfter = parseJsonResult(
|
||||
'ktx dev runtime status ready',
|
||||
await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'status', '--json']),
|
||||
'ktx admin runtime status ready',
|
||||
await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'status', '--json']),
|
||||
);
|
||||
assert.equal(runtimeStatusAfter.kind, 'ready');
|
||||
assert.deepEqual(runtimeStatusAfter.manifest.features, ['core']);
|
||||
|
|
@ -797,29 +797,29 @@ try {
|
|||
requireOutput('ktx sl query sqlite execute', sqliteSlQuery, /"rows": \\[\\s*\\[\\s*3\\s*\\]\\s*\\]/);
|
||||
process.stdout.write('ktx sl query sqlite execute verified\\n');
|
||||
|
||||
const runtimeDoctor = await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'status']);
|
||||
requireSuccess('ktx dev runtime status', runtimeDoctor);
|
||||
requireOutput('ktx dev runtime status', runtimeDoctor, /KTX Python runtime/);
|
||||
requireOutput('ktx dev runtime status', runtimeDoctor, /status: ready/);
|
||||
process.stdout.write('ktx dev runtime status verified\\n');
|
||||
const runtimeDoctor = await run('pnpm', ['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, /status: ready/);
|
||||
process.stdout.write('ktx admin runtime status verified\\n');
|
||||
|
||||
const runtimeStart = await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'start']);
|
||||
requireSuccess('ktx dev runtime start', runtimeStart);
|
||||
const runtimeStart = await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'start']);
|
||||
requireSuccess('ktx admin runtime start', runtimeStart);
|
||||
daemonStarted = true;
|
||||
requireOutput('ktx dev runtime start', runtimeStart, /Started KTX Python daemon/);
|
||||
requireOutput('ktx dev runtime start', runtimeStart, /url: http:\\/\\/127\\.0\\.0\\.1:\\d+/);
|
||||
requireOutput('ktx dev runtime start', runtimeStart, /features: core/);
|
||||
requireOutput('ktx admin runtime start', runtimeStart, /Started KTX Python 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('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'start']);
|
||||
requireSuccess('ktx dev runtime start reuse', runtimeStartReuse);
|
||||
requireOutput('ktx dev runtime start reuse', runtimeStartReuse, /Using existing KTX Python daemon/);
|
||||
requireOutput('ktx dev runtime start reuse', runtimeStartReuse, /features: core/);
|
||||
const runtimeStartReuse = await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'start']);
|
||||
requireSuccess('ktx admin runtime start reuse', runtimeStartReuse);
|
||||
requireOutput('ktx admin runtime start reuse', runtimeStartReuse, /Using existing KTX Python daemon/);
|
||||
requireOutput('ktx admin runtime start reuse', runtimeStartReuse, /features: core/);
|
||||
|
||||
const runtimeStop = await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'stop']);
|
||||
requireSuccess('ktx dev runtime stop', runtimeStop);
|
||||
const runtimeStop = await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'stop']);
|
||||
requireSuccess('ktx admin runtime stop', runtimeStop);
|
||||
daemonStarted = false;
|
||||
requireOutput('ktx dev runtime stop', runtimeStop, /Stopped KTX Python daemon/);
|
||||
process.stdout.write('ktx dev runtime daemon lifecycle verified\\n');
|
||||
requireOutput('ktx admin runtime stop', runtimeStop, /Stopped KTX Python daemon/);
|
||||
process.stdout.write('ktx admin runtime daemon lifecycle verified\\n');
|
||||
|
||||
const structuralScan = await run('pnpm', ['exec', 'ktx', 'ingest', 'warehouse',
|
||||
'--project-dir',
|
||||
|
|
@ -849,7 +849,7 @@ try {
|
|||
process.stdout.write('ktx ingest state verified\\n');
|
||||
} finally {
|
||||
if (daemonStarted) {
|
||||
await run('pnpm', ['exec', 'ktx', 'dev', 'runtime', 'stop']);
|
||||
await run('pnpm', ['exec', 'ktx', 'admin', 'runtime', 'stop']);
|
||||
}
|
||||
if (previousRuntimeRoot === undefined) {
|
||||
delete process.env.KTX_RUNTIME_ROOT;
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ describe('findPythonArtifacts', () => {
|
|||
it('throws when a required Python artifact is missing', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'ktx-artifacts-test-'));
|
||||
try {
|
||||
await assert.rejects(() => findPythonArtifacts(root), /Missing Python artifact: kaelio-ktx dev runtime wheel/);
|
||||
await assert.rejects(() => findPythonArtifacts(root), /Missing Python artifact: kaelio-ktx runtime wheel/);
|
||||
} finally {
|
||||
await rm(root, { recursive: true, force: true });
|
||||
}
|
||||
|
|
@ -491,20 +491,20 @@ describe('verification snippets', () => {
|
|||
assert.doesNotMatch(source, /run\('python'/);
|
||||
assert.match(source, /KTX_RUNTIME_ROOT/);
|
||||
assert.match(source, /managed-runtime/);
|
||||
assert.match(source, /ktx dev runtime status missing/);
|
||||
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.match(source, /ktx dev runtime status ready/);
|
||||
assert.match(source, /ktx admin runtime status ready/);
|
||||
assert.match(source, /runtimeStatusAfter\.kind, 'ready'/);
|
||||
assert.match(source, /runtimeStatusAfter\.manifest\.features/);
|
||||
assert.match(source, /ktx dev runtime status/);
|
||||
assert.match(source, /ktx admin runtime status/);
|
||||
assert.match(source, /status: ready/);
|
||||
assert.match(source, /ktx dev runtime start/);
|
||||
assert.match(source, /ktx dev runtime start reuse/);
|
||||
assert.match(source, /ktx admin runtime start/);
|
||||
assert.match(source, /ktx admin runtime start reuse/);
|
||||
assert.match(source, /Using existing KTX Python daemon/);
|
||||
assert.match(source, /ktx dev runtime stop/);
|
||||
assert.doesNotMatch(source, /ktx dev runtime prune/);
|
||||
assert.match(source, /ktx admin runtime stop/);
|
||||
assert.doesNotMatch(source, /ktx admin runtime prune/);
|
||||
assert.doesNotMatch(source, /staleRuntimeDir/);
|
||||
assert.match(source, /run\('pnpm', \[\s*'exec',\s*'ktx',\s*'ingest',\s*'warehouse'/);
|
||||
assert.match(source, /'--deep'/);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue