feat(cli): enforce required database selection and improve tree-picker UX (#86)

* feat(cli): enforce required database selection and improve tree-picker UX

- Require at least one database driver via prompt `required: true` instead of
  looping on empty selection; remove the now-dead retry/back-on-empty branch.
- Surface the recommended option with a "(recommended)" hint in the depth and
  query-history prompts.
- Tree picker: add `◧` partial glyph for parents whose descendants are checked,
  and make `a` toggle select-all-visible / select-none.

* fix(cli): drop unused export from tree-picker toggleSelectAllVisible

Knip flagged the export as unused; the function is only consumed by the
internal reducer via the 'toggle-select-all-visible' command, so demote
it to a module-local helper to keep CI's dead-code check green.

* test(cli): drop empty-selection warning assertion from setup test

The empty-selection retry/warning loop in `chooseDrivers` was removed in
favor of `multiselect`'s `required: true`, so the legacy warning string
is unreachable. Update the test to assert the simpler back-from-selection
return-to-embeddings flow.
This commit is contained in:
Andrey Avtomonov 2026-05-14 14:35:58 +02:00 committed by GitHub
parent e28b10454a
commit 6c4623f2ff
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 146 additions and 60 deletions

View file

@ -149,31 +149,10 @@ describe('setup databases step', () => {
{ value: 'bigquery', label: 'BigQuery' },
{ value: 'snowflake', label: 'Snowflake' },
],
required: false,
required: true,
});
});
it('requires choosing a database after an empty interactive selection', async () => {
const io = makeIo();
const prompts = makePromptAdapter({
multiselectValues: [[], ['back']],
selectValues: ['choose'],
});
const result = await runKtxSetupDatabasesStep(
{ projectDir: tempDir, inputMode: 'auto', skipDatabases: false, databaseSchemas: [] },
io.io,
{ prompts },
);
expect(result.status).toBe('back');
expect(prompts.select).not.toHaveBeenCalled();
expect(io.stdout()).toContain(
'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 database selection when adding a new driver', async () => {
const prompts = makePromptAdapter({
multiselectValues: [['postgres'], ['back']],
@ -744,10 +723,10 @@ describe('setup databases step', () => {
expect(config.setup?.database_connection_ids).toEqual(['postgres-warehouse', 'mysql-warehouse']);
});
it('returns to configured primary menu when submitting empty driver selection after adding a source', async () => {
it('returns to configured primary menu when pressing back on driver selection after adding a source', async () => {
const io = makeIo();
const prompts = makePromptAdapter({
multiselectValues: [['postgres'], []],
multiselectValues: [['postgres'], ['back']],
selectValues: ['url', 'add', 'continue'],
textValues: ['', 'env:DATABASE_URL'],
});
@ -787,7 +766,7 @@ describe('setup databases step', () => {
});
});
it('returns to configured primary menu when submitting empty driver selection with pre-existing source', async () => {
it('returns to configured primary menu when pressing back on driver selection with pre-existing source', async () => {
await writeFile(
join(tempDir, 'ktx.yaml'),
[
@ -806,7 +785,7 @@ describe('setup databases step', () => {
await writeKtxSetupState(tempDir, { completed_steps: ['databases'] });
const io = makeIo();
const prompts = makePromptAdapter({
multiselectValues: [[]],
multiselectValues: [['back']],
selectValues: ['add', 'continue'],
});
@ -2007,7 +1986,7 @@ describe('setup databases step', () => {
expect(prompts.select).toHaveBeenCalledWith({
message: 'Enable query-history ingest for this PostgreSQL connection?',
options: [
{ value: 'yes', label: 'Enable query history' },
{ value: 'yes', label: 'Enable query history (recommended)' },
{ value: 'no', label: 'Do not enable query history' },
{ value: 'back', label: 'Back' },
],