mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-10 08:05:14 +02:00
fix(cli): align setup database labels
This commit is contained in:
parent
869669e87f
commit
38e921d3e2
12 changed files with 105 additions and 63 deletions
|
|
@ -65,7 +65,7 @@ KTX project: /home/user/analytics
|
|||
Project ready: yes
|
||||
LLM ready: yes (claude-sonnet-4-6)
|
||||
Embeddings ready: yes (text-embedding-3-small)
|
||||
Primary sources configured: yes (postgres-warehouse)
|
||||
Databases configured: yes (postgres-warehouse)
|
||||
Context sources configured: yes (dbt-main)
|
||||
KTX context built: yes
|
||||
Agent integration ready: yes (claude-code:project)
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ KTX project: /home/user/analytics
|
|||
Project ready: yes
|
||||
LLM ready: yes (claude-sonnet-4-6)
|
||||
Embeddings ready: yes (text-embedding-3-small)
|
||||
Primary sources configured: yes (postgres-warehouse)
|
||||
Databases configured: yes (postgres-warehouse)
|
||||
Context sources configured: yes (dbt-main)
|
||||
KTX context built: yes
|
||||
Agent integration ready: yes (codex:project)
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ Building schema context for postgres-warehouse
|
|||
Schema context complete for postgres-warehouse
|
||||
Changes: 42 new tables
|
||||
|
||||
Primary source ready
|
||||
Database ready
|
||||
postgres-warehouse - PostgreSQL - schema context complete
|
||||
```
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ When the build completes, KTX verifies that agent-ready context was produced:
|
|||
```
|
||||
KTX context is ready for agents.
|
||||
|
||||
Primary sources:
|
||||
Databases:
|
||||
postgres-warehouse: deep context complete
|
||||
|
||||
Context sources:
|
||||
|
|
@ -228,7 +228,7 @@ KTX project: /home/user/analytics
|
|||
Project ready: yes
|
||||
LLM ready: yes (claude-sonnet-4-6)
|
||||
Embeddings ready: yes (text-embedding-3-small)
|
||||
Primary sources configured: yes (postgres-warehouse)
|
||||
Databases configured: yes (postgres-warehouse)
|
||||
Context sources configured: yes (dbt-main)
|
||||
KTX context built: yes
|
||||
Agent integration ready: yes (claude-code:project)
|
||||
|
|
|
|||
|
|
@ -293,6 +293,8 @@ describe('setup context build state', () => {
|
|||
artifactPaths: ['raw-sources/warehouse/live-database/sync-1/scan-report.json'],
|
||||
});
|
||||
expect(io.stdout()).toContain('KTX context is ready for agents.');
|
||||
expect(io.stdout()).toContain('Databases:');
|
||||
expect(io.stdout()).not.toContain(['Primary sources', ':'].join(''));
|
||||
});
|
||||
|
||||
it('records only failed sources as retryable when the context build fails', async () => {
|
||||
|
|
@ -375,6 +377,7 @@ describe('setup context build state', () => {
|
|||
contextSourceConnectionIds: ['docs'],
|
||||
});
|
||||
expect(io.stdout()).toContain('KTX context is ready for agents.');
|
||||
expect(io.stdout()).not.toContain(['Primary sources', ':'].join(''));
|
||||
});
|
||||
|
||||
it('does not mark context ready until primary scans have completed description enrichment', async () => {
|
||||
|
|
|
|||
|
|
@ -570,7 +570,7 @@ function writeSuccess(
|
|||
io: KtxCliIo,
|
||||
): void {
|
||||
io.stdout.write('\nKTX context is ready for agents.\n\n');
|
||||
io.stdout.write('Primary sources:\n');
|
||||
io.stdout.write('Databases:\n');
|
||||
if (targets.primarySourceConnectionIds.length === 0) {
|
||||
io.stdout.write(' none\n');
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ describe('setup databases step', () => {
|
|||
await rm(tempDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it('shows every supported primary source in the interactive checklist', async () => {
|
||||
it('shows every supported database in the interactive checklist', async () => {
|
||||
const prompts = makePromptAdapter({ multiselectValues: [['back']] });
|
||||
|
||||
const result = await runKtxSetupDatabasesStep(
|
||||
|
|
@ -88,7 +88,7 @@ describe('setup databases step', () => {
|
|||
expect(result.status).toBe('back');
|
||||
expect(prompts.multiselect).toHaveBeenCalledWith({
|
||||
message:
|
||||
'Which primary sources should KTX connect to?\n' +
|
||||
'Which databases should KTX connect to?\n' +
|
||||
'Use Up/Down to move, Space to select or unselect, Enter to confirm, Escape to go back, or Ctrl+C to exit.',
|
||||
options: [
|
||||
{ value: 'sqlite', label: 'SQLite' },
|
||||
|
|
@ -103,7 +103,7 @@ describe('setup databases step', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('requires choosing a primary source after an empty interactive selection', async () => {
|
||||
it('requires choosing a database after an empty interactive selection', async () => {
|
||||
const io = makeIo();
|
||||
const prompts = makePromptAdapter({
|
||||
multiselectValues: [[], ['back']],
|
||||
|
|
@ -119,12 +119,12 @@ describe('setup databases step', () => {
|
|||
expect(result.status).toBe('back');
|
||||
expect(prompts.select).not.toHaveBeenCalled();
|
||||
expect(io.stdout()).toContain(
|
||||
'KTX cannot work without at least one primary source. Select a source or press Escape to go back.',
|
||||
'KTX cannot work without at least one database. Select a database or press Escape to go back.',
|
||||
);
|
||||
expect(prompts.multiselect).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('lets Back from connection method selection return to primary source selection when adding a new driver', async () => {
|
||||
it('lets Back from connection method selection return to database selection when adding a new driver', async () => {
|
||||
const prompts = makePromptAdapter({
|
||||
multiselectValues: [['postgres'], ['back']],
|
||||
selectValues: ['back'],
|
||||
|
|
@ -147,12 +147,12 @@ describe('setup databases step', () => {
|
|||
});
|
||||
expect(prompts.multiselect).toHaveBeenCalledTimes(2);
|
||||
expect(vi.mocked(prompts.multiselect).mock.calls[1]?.[0].message).toBe(
|
||||
'Which primary sources should KTX connect to?\n' +
|
||||
'Which databases should KTX connect to?\n' +
|
||||
'Use Up/Down to move, Space to select or unselect, Enter to confirm, Escape to go back, or Ctrl+C to exit.',
|
||||
);
|
||||
});
|
||||
|
||||
it('offers connection URL paste first for URL-capable primary sources', async () => {
|
||||
it('offers connection URL paste first for URL-capable databases', async () => {
|
||||
const cases: Array<{ driver: KtxSetupDatabaseDriver; label: string }> = [
|
||||
{ driver: 'postgres', label: 'PostgreSQL' },
|
||||
{ driver: 'mysql', label: 'MySQL' },
|
||||
|
|
@ -505,7 +505,7 @@ describe('setup databases step', () => {
|
|||
}
|
||||
});
|
||||
|
||||
it('lets Back from connection method selection return to primary source selection', async () => {
|
||||
it('lets Back from connection method selection return to database selection', async () => {
|
||||
const prompts = makePromptAdapter({
|
||||
multiselectValues: [['postgres'], ['back']],
|
||||
selectValues: ['back'],
|
||||
|
|
@ -542,7 +542,7 @@ describe('setup databases step', () => {
|
|||
expect(scanConnection).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('shows a configured primary source menu instead of the type checklist when a primary source exists', async () => {
|
||||
it('shows a configured database menu instead of the type checklist when a database exists', async () => {
|
||||
await writeFile(
|
||||
join(tempDir, 'ktx.yaml'),
|
||||
[
|
||||
|
|
@ -565,7 +565,13 @@ describe('setup databases step', () => {
|
|||
const scanConnection = vi.fn(async () => 0);
|
||||
|
||||
const result = await runKtxSetupDatabasesStep(
|
||||
{ projectDir: tempDir, inputMode: 'auto', skipDatabases: false, databaseSchemas: [] },
|
||||
{
|
||||
projectDir: tempDir,
|
||||
inputMode: 'auto',
|
||||
skipDatabases: false,
|
||||
databaseSchemas: [],
|
||||
disableQueryHistory: true,
|
||||
},
|
||||
makeIo().io,
|
||||
{ prompts, testConnection, scanConnection },
|
||||
);
|
||||
|
|
@ -573,17 +579,17 @@ describe('setup databases step', () => {
|
|||
expect(result).toEqual({ status: 'ready', projectDir: tempDir, connectionIds: ['warehouse'] });
|
||||
expect(prompts.multiselect).not.toHaveBeenCalled();
|
||||
expect(prompts.select).toHaveBeenCalledWith({
|
||||
message: 'Primary sources already configured: warehouse\nWhat would you like to do?',
|
||||
message: 'Databases already configured: warehouse\nWhat would you like to do?',
|
||||
options: [
|
||||
{ value: 'continue', label: 'Continue to knowledge sources' },
|
||||
{ value: 'add', label: 'Add another primary source' },
|
||||
{ value: 'continue', label: 'Continue to context sources' },
|
||||
{ value: 'add', label: 'Add another database' },
|
||||
],
|
||||
});
|
||||
expect(testConnection).not.toHaveBeenCalled();
|
||||
expect(scanConnection).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('preserves existing primary source ids when adding another source from the configured menu', async () => {
|
||||
it('preserves existing database ids when adding another database from the configured menu', async () => {
|
||||
await writeFile(
|
||||
join(tempDir, 'ktx.yaml'),
|
||||
[
|
||||
|
|
@ -610,7 +616,13 @@ describe('setup databases step', () => {
|
|||
const scanConnection = vi.fn(async () => 0);
|
||||
|
||||
const result = await runKtxSetupDatabasesStep(
|
||||
{ projectDir: tempDir, inputMode: 'auto', skipDatabases: false, databaseSchemas: [] },
|
||||
{
|
||||
projectDir: tempDir,
|
||||
inputMode: 'auto',
|
||||
skipDatabases: false,
|
||||
databaseSchemas: [],
|
||||
disableQueryHistory: true,
|
||||
},
|
||||
makeIo().io,
|
||||
{ prompts, testConnection, scanConnection },
|
||||
);
|
||||
|
|
@ -622,10 +634,10 @@ describe('setup databases step', () => {
|
|||
});
|
||||
expect(prompts.multiselect).toHaveBeenCalledTimes(1);
|
||||
expect(prompts.select).toHaveBeenCalledWith({
|
||||
message: 'Primary sources already configured: warehouse\nWhat would you like to do?',
|
||||
message: 'Databases already configured: warehouse\nWhat would you like to do?',
|
||||
options: [
|
||||
{ value: 'continue', label: 'Continue to knowledge sources' },
|
||||
{ value: 'add', label: 'Add another primary source' },
|
||||
{ value: 'continue', label: 'Continue to context sources' },
|
||||
{ value: 'add', label: 'Add another database' },
|
||||
],
|
||||
});
|
||||
expect(testConnection).toHaveBeenCalledTimes(1);
|
||||
|
|
@ -635,7 +647,7 @@ describe('setup databases step', () => {
|
|||
expect(config.setup?.database_connection_ids).toEqual(['warehouse', 'mysql-warehouse']);
|
||||
});
|
||||
|
||||
it('lets users add another primary source after completing the first one', async () => {
|
||||
it('lets users add another database after completing the first one', async () => {
|
||||
const prompts = makePromptAdapter({
|
||||
multiselectValues: [['postgres'], ['mysql']],
|
||||
selectValues: ['url', 'add', 'url', 'continue'],
|
||||
|
|
@ -645,7 +657,13 @@ describe('setup databases step', () => {
|
|||
const scanConnection = vi.fn(async () => 0);
|
||||
|
||||
const result = await runKtxSetupDatabasesStep(
|
||||
{ projectDir: tempDir, inputMode: 'auto', skipDatabases: false, databaseSchemas: [] },
|
||||
{
|
||||
projectDir: tempDir,
|
||||
inputMode: 'auto',
|
||||
skipDatabases: false,
|
||||
databaseSchemas: [],
|
||||
disableQueryHistory: true,
|
||||
},
|
||||
makeIo().io,
|
||||
{ prompts, testConnection, scanConnection },
|
||||
);
|
||||
|
|
@ -657,10 +675,10 @@ describe('setup databases step', () => {
|
|||
});
|
||||
expect(prompts.multiselect).toHaveBeenCalledTimes(2);
|
||||
expect(prompts.select).toHaveBeenCalledWith({
|
||||
message: 'Primary sources already configured: postgres-warehouse\nWhat would you like to do?',
|
||||
message: 'Databases already configured: postgres-warehouse\nWhat would you like to do?',
|
||||
options: [
|
||||
{ value: 'continue', label: 'Continue to knowledge sources' },
|
||||
{ value: 'add', label: 'Add another primary source' },
|
||||
{ value: 'continue', label: 'Continue to context sources' },
|
||||
{ value: 'add', label: 'Add another database' },
|
||||
],
|
||||
});
|
||||
const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8'));
|
||||
|
|
@ -678,7 +696,13 @@ describe('setup databases step', () => {
|
|||
const scanConnection = vi.fn(async () => 0);
|
||||
|
||||
const result = await runKtxSetupDatabasesStep(
|
||||
{ projectDir: tempDir, inputMode: 'auto', skipDatabases: false, databaseSchemas: [] },
|
||||
{
|
||||
projectDir: tempDir,
|
||||
inputMode: 'auto',
|
||||
skipDatabases: false,
|
||||
databaseSchemas: [],
|
||||
disableQueryHistory: true,
|
||||
},
|
||||
io.io,
|
||||
{ prompts, testConnection, scanConnection },
|
||||
);
|
||||
|
|
@ -689,12 +713,12 @@ describe('setup databases step', () => {
|
|||
connectionIds: ['postgres-warehouse'],
|
||||
});
|
||||
expect(prompts.multiselect).toHaveBeenCalledTimes(2);
|
||||
expect(io.stdout()).not.toContain('KTX cannot work without at least one primary source');
|
||||
expect(io.stdout()).not.toContain('KTX cannot work without at least one database');
|
||||
expect(prompts.select).toHaveBeenNthCalledWith(2, {
|
||||
message: 'Primary sources already configured: postgres-warehouse\nWhat would you like to do?',
|
||||
message: 'Databases already configured: postgres-warehouse\nWhat would you like to do?',
|
||||
options: [
|
||||
{ value: 'continue', label: 'Continue to knowledge sources' },
|
||||
{ value: 'add', label: 'Add another primary source' },
|
||||
{ value: 'continue', label: 'Continue to context sources' },
|
||||
{ value: 'add', label: 'Add another database' },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
|
@ -730,12 +754,12 @@ describe('setup databases step', () => {
|
|||
);
|
||||
|
||||
expect(result).toEqual({ status: 'ready', projectDir: tempDir, connectionIds: ['warehouse'] });
|
||||
expect(io.stdout()).not.toContain('KTX cannot work without at least one primary source');
|
||||
expect(io.stdout()).not.toContain('KTX cannot work without at least one database');
|
||||
expect(prompts.select).toHaveBeenNthCalledWith(2, {
|
||||
message: 'Primary sources already configured: warehouse\nWhat would you like to do?',
|
||||
message: 'Databases already configured: warehouse\nWhat would you like to do?',
|
||||
options: [
|
||||
{ value: 'continue', label: 'Continue to knowledge sources' },
|
||||
{ value: 'add', label: 'Add another primary source' },
|
||||
{ value: 'continue', label: 'Continue to context sources' },
|
||||
{ value: 'add', label: 'Add another database' },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
|
@ -755,6 +779,7 @@ describe('setup databases step', () => {
|
|||
databaseDrivers: ['postgres'],
|
||||
databaseSchemas: [],
|
||||
skipDatabases: false,
|
||||
disableQueryHistory: true,
|
||||
},
|
||||
makeIo().io,
|
||||
{ prompts, testConnection, scanConnection },
|
||||
|
|
@ -788,15 +813,15 @@ describe('setup databases step', () => {
|
|||
expect(prompts.select).toHaveBeenNthCalledWith(2, {
|
||||
message:
|
||||
'Some PostgreSQL connection details are missing.\n' +
|
||||
'Continue entering details, or go back to primary source selection.',
|
||||
'Continue entering details, or go back to database selection.',
|
||||
options: [
|
||||
{ value: 'retry', label: 'Continue entering PostgreSQL details' },
|
||||
{ value: 'back', label: 'Back to primary source selection' },
|
||||
{ value: 'back', label: 'Back to database selection' },
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('lets Escape from connection name return to primary source selection', async () => {
|
||||
it('lets Escape from connection name return to database selection', async () => {
|
||||
const prompts = makePromptAdapter({
|
||||
multiselectValues: [['postgres'], ['back']],
|
||||
textValues: [undefined],
|
||||
|
|
@ -966,7 +991,8 @@ describe('setup databases step', () => {
|
|||
expect(io.stdout()).toContain('│ Running fast database ingest…');
|
||||
expect(io.stdout()).toContain('◇ Schema context complete for postgres-warehouse');
|
||||
expect(io.stdout()).toContain('│ Changes: 2 new tables');
|
||||
expect(io.stdout()).toContain('◇ Primary source ready');
|
||||
expect(io.stdout()).toContain('◇ Database ready');
|
||||
expect(io.stdout()).not.toContain(['Primary source', 'ready'].join(' '));
|
||||
expect(io.stdout()).toContain('│ postgres-warehouse · PostgreSQL · schema context complete');
|
||||
expect(io.stdout()).not.toContain('Scanning postgres-warehouse');
|
||||
expect(io.stdout()).not.toContain('Scan complete for postgres-warehouse');
|
||||
|
|
@ -1108,6 +1134,7 @@ describe('setup databases step', () => {
|
|||
databaseUrl: 'env:DATABASE_URL',
|
||||
databaseSchemas: ['public'],
|
||||
skipDatabases: false,
|
||||
disableQueryHistory: true,
|
||||
},
|
||||
io.io,
|
||||
{ testConnection, scanConnection, listSchemas },
|
||||
|
|
@ -1122,13 +1149,15 @@ describe('setup databases step', () => {
|
|||
driver: 'postgres',
|
||||
url: 'env:DATABASE_URL',
|
||||
schemas: ['public'],
|
||||
context: { queryHistory: { enabled: false } },
|
||||
readonly: true,
|
||||
});
|
||||
expect(config.setup).toEqual({
|
||||
database_connection_ids: ['warehouse'],
|
||||
});
|
||||
expect((await readKtxSetupState(tempDir)).completed_steps).toContain('databases');
|
||||
expect(io.stdout()).toContain('Primary source ready');
|
||||
expect(io.stdout()).toContain('Database ready');
|
||||
expect(io.stdout()).not.toContain(['Primary source', 'ready'].join(' '));
|
||||
expect(io.stdout()).not.toContain('DATABASE_URL=');
|
||||
});
|
||||
|
||||
|
|
@ -1813,7 +1842,7 @@ describe('setup databases step', () => {
|
|||
expect(io.stderr()).toContain('"replay" is reserved for ktx ingest replay; choose a different connection id.');
|
||||
});
|
||||
|
||||
it('leaves setup incomplete when primary sources are skipped', async () => {
|
||||
it('leaves setup incomplete when databases are skipped', async () => {
|
||||
const io = makeIo();
|
||||
|
||||
const result = await runKtxSetupDatabasesStep(
|
||||
|
|
@ -1822,7 +1851,7 @@ describe('setup databases step', () => {
|
|||
);
|
||||
|
||||
expect(result.status).toBe('skipped');
|
||||
expect(io.stdout()).toContain('KTX cannot work until you add a primary source.');
|
||||
expect(io.stdout()).toContain('KTX cannot work until you add a database.');
|
||||
expect(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')).not.toContain('completed_steps:');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -197,7 +197,7 @@ function missingConnectionDetailsPrompt(
|
|||
label: string,
|
||||
canReturnToDriverSelection: boolean,
|
||||
): { message: string; options: Array<{ value: string; label: string }> } {
|
||||
const backDestination = canReturnToDriverSelection ? 'primary source selection' : 'the previous setup step';
|
||||
const backDestination = canReturnToDriverSelection ? 'database selection' : 'the previous setup step';
|
||||
return {
|
||||
message:
|
||||
`Some ${label} connection details are missing.\n` +
|
||||
|
|
@ -509,10 +509,10 @@ function configuredPrimarySourcesPrompt(connectionIds: string[]): {
|
|||
options: Array<{ value: string; label: string }>;
|
||||
} {
|
||||
return {
|
||||
message: `Primary sources already configured: ${connectionIds.join(', ')}\nWhat would you like to do?`,
|
||||
message: `Databases already configured: ${connectionIds.join(', ')}\nWhat would you like to do?`,
|
||||
options: [
|
||||
{ value: 'continue', label: 'Continue to knowledge sources' },
|
||||
{ value: 'add', label: 'Add another primary source' },
|
||||
{ value: 'continue', label: 'Continue to context sources' },
|
||||
{ value: 'add', label: 'Add another database' },
|
||||
],
|
||||
};
|
||||
}
|
||||
|
|
@ -1609,7 +1609,7 @@ async function validateAndScanConnection(input: {
|
|||
`Schema context complete for ${input.connectionId}`,
|
||||
[`Changes: ${summarizeScanChanges(scanOutput)}`],
|
||||
);
|
||||
writeSetupSection(input.io, 'Primary source ready', [
|
||||
writeSetupSection(input.io, 'Database ready', [
|
||||
`${input.connectionId} · ${driverDisplay} · schema context complete`,
|
||||
]);
|
||||
return true;
|
||||
|
|
@ -1629,13 +1629,13 @@ async function chooseDrivers(
|
|||
}
|
||||
if (args.inputMode === 'disabled') {
|
||||
io.stderr.write(
|
||||
'KTX cannot work without a primary source. Pass --database or --database-connection-id, or pass --skip-databases to leave setup incomplete.\n',
|
||||
'KTX cannot work without a database. Pass --database or --database-connection-id, or pass --skip-databases to leave setup incomplete.\n',
|
||||
);
|
||||
return 'missing-input';
|
||||
}
|
||||
while (true) {
|
||||
const choices = await prompts.multiselect({
|
||||
message: withMultiselectNavigation('Which primary sources should KTX connect to?'),
|
||||
message: withMultiselectNavigation('Which databases should KTX connect to?'),
|
||||
options: [...DRIVER_OPTIONS],
|
||||
required: false,
|
||||
});
|
||||
|
|
@ -1650,7 +1650,7 @@ async function chooseDrivers(
|
|||
return 'back';
|
||||
}
|
||||
|
||||
io.stdout.write('│ KTX cannot work without at least one primary source. Select a source or press Escape to go back.\n');
|
||||
io.stdout.write('│ KTX cannot work without at least one database. Select a database or press Escape to go back.\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1718,7 +1718,7 @@ export async function runKtxSetupDatabasesStep(
|
|||
deps: KtxSetupDatabasesDeps = {},
|
||||
): Promise<KtxSetupDatabasesResult> {
|
||||
if (args.skipDatabases) {
|
||||
io.stdout.write('│ Primary source setup skipped. KTX cannot work until you add a primary source.\n');
|
||||
io.stdout.write('│ Database setup skipped. KTX cannot work until you add a database.\n');
|
||||
return { status: 'skipped', projectDir: args.projectDir };
|
||||
}
|
||||
|
||||
|
|
@ -1772,7 +1772,7 @@ export async function runKtxSetupDatabasesStep(
|
|||
if (drivers === 'missing-input') return { status: 'missing-input', projectDir: args.projectDir };
|
||||
if (drivers.length === 0) {
|
||||
await markDatabasesComplete(args.projectDir, []);
|
||||
io.stdout.write('│ KTX cannot work without a primary source.\n');
|
||||
io.stdout.write('│ KTX cannot work without a database.\n');
|
||||
return { status: 'skipped', projectDir: args.projectDir };
|
||||
}
|
||||
|
||||
|
|
@ -1883,11 +1883,11 @@ export async function runKtxSetupDatabasesStep(
|
|||
) {
|
||||
if (args.inputMode === 'disabled') return { status: 'failed', projectDir: args.projectDir };
|
||||
const action = await prompts.select({
|
||||
message: `Primary source setup failed for ${connectionChoice.connectionId}`,
|
||||
message: `Database setup failed for ${connectionChoice.connectionId}`,
|
||||
options: [
|
||||
{ value: 'retry', label: 'Retry connection test' },
|
||||
{ value: 're-enter', label: 'Re-enter connection details' },
|
||||
{ value: 'skip', label: 'Skip this primary source' },
|
||||
{ value: 'skip', label: 'Skip this database' },
|
||||
{ value: 'back', label: 'Back' },
|
||||
],
|
||||
});
|
||||
|
|
@ -1940,7 +1940,7 @@ export async function runKtxSetupDatabasesStep(
|
|||
}
|
||||
|
||||
if (selectedConnectionIds.length === 0) {
|
||||
io.stderr.write('No primary source connections completed setup.\n');
|
||||
io.stderr.write('No database connections completed setup.\n');
|
||||
return { status: 'failed', projectDir: args.projectDir };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ describe('setup ready menu', () => {
|
|||
options: [
|
||||
{ value: 'models', label: 'Models' },
|
||||
{ value: 'embeddings', label: 'Embeddings' },
|
||||
{ value: 'databases', label: 'Primary sources' },
|
||||
{ value: 'databases', label: 'Databases' },
|
||||
{ value: 'sources', label: 'Context sources' },
|
||||
{ value: 'context', label: 'Rebuild KTX context' },
|
||||
{ value: 'agents', label: 'Agent integration' },
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ export async function runKtxSetupReadyChangeMenu(
|
|||
options: [
|
||||
{ value: 'models', label: 'Models' },
|
||||
{ value: 'embeddings', label: 'Embeddings' },
|
||||
{ value: 'databases', label: 'Primary sources' },
|
||||
{ value: 'databases', label: 'Databases' },
|
||||
{ value: 'sources', label: 'Context sources' },
|
||||
{ value: 'context', label: 'Rebuild KTX context' },
|
||||
{ value: 'agents', label: 'Agent integration' },
|
||||
|
|
|
|||
|
|
@ -379,6 +379,8 @@ describe('setup status', () => {
|
|||
expect(rendered).toContain(`KTX project: ${tempDir}`);
|
||||
expect(rendered).toContain('Project ready: yes');
|
||||
expect(rendered).toContain('LLM ready: no');
|
||||
expect(rendered).toContain('Databases configured: no');
|
||||
expect(rendered).not.toContain(['Primary sources', 'configured'].join(' '));
|
||||
expect(rendered).toContain('KTX context built: no');
|
||||
expect(rendered).not.toContain('No KTX project found.');
|
||||
});
|
||||
|
|
@ -1143,11 +1145,11 @@ describe('setup status', () => {
|
|||
|
||||
expect(databasePrompts.select).not.toHaveBeenCalled();
|
||||
expect(testIo.stdout()).toContain(
|
||||
'KTX cannot work without at least one primary source. Select a source or press Escape to go back.',
|
||||
'KTX cannot work without at least one database. Select a database or press Escape to go back.',
|
||||
);
|
||||
expect(embeddings).toHaveBeenCalledTimes(2);
|
||||
expect(embeddings).toHaveBeenNthCalledWith(2, expect.objectContaining({ forcePrompt: true }), testIo.io);
|
||||
expect(testIo.stderr()).not.toContain('No primary sources selected.');
|
||||
expect(testIo.stderr()).not.toContain('No databases selected.');
|
||||
});
|
||||
|
||||
it('lets Back from the first setup step return to the entry menu instead of exiting', async () => {
|
||||
|
|
|
|||
|
|
@ -371,7 +371,7 @@ export function formatKtxSetupStatus(status: KtxSetupStatus): string {
|
|||
`Embeddings ready: ${formatReady(status.embeddings.ready)}${
|
||||
status.embeddings.model ? ` (${status.embeddings.model})` : ''
|
||||
}`,
|
||||
`Primary sources configured: ${formatConnectionList(status.databases.map((database) => database.connectionId))}`,
|
||||
`Databases configured: ${formatConnectionList(status.databases.map((database) => database.connectionId))}`,
|
||||
`Context sources configured: ${formatConnectionList(status.sources.map((source) => source.connectionId))}`,
|
||||
`KTX context built: ${formatContextBuilt(status.context)}`,
|
||||
`Agent integration ready: ${formatReady(status.agents.some((agent) => agent.ready))}${
|
||||
|
|
|
|||
|
|
@ -243,6 +243,7 @@ describe('standalone example docs', () => {
|
|||
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 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');
|
||||
const contextAsCode = await readText('docs-site/content/docs/concepts/context-as-code.mdx');
|
||||
|
|
@ -261,6 +262,13 @@ describe('standalone example docs', () => {
|
|||
assert.match(contextAsCode, /ktx ingest --all --no-input/);
|
||||
assert.match(quickstart, /schema context/);
|
||||
assert.match(primarySources, /context:\n queryHistory:/);
|
||||
assert.match(rootReadme, /Databases configured: yes \(postgres-warehouse\)/);
|
||||
assert.match(quickstart, /Databases:\n postgres-warehouse: deep context complete/);
|
||||
assert.match(quickstart, /Databases configured: yes \(postgres-warehouse\)/);
|
||||
assert.match(setupReference, /Databases configured: yes \(postgres-warehouse\)/);
|
||||
assert.doesNotMatch(rootReadme, new RegExp(['Primary sources', 'configured'].join(' ')));
|
||||
assert.doesNotMatch(quickstart, new RegExp(['Primary', 'sources'].join(' ')));
|
||||
assert.doesNotMatch(setupReference, new RegExp(['Primary sources', 'configured'].join(' ')));
|
||||
|
||||
assert.doesNotMatch(cliMeta, /ktx-scan/);
|
||||
assert.doesNotMatch(ingestReference, /ktx ingest run/);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue