mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-07 07:55:13 +02:00
refactor(cli): hide internal setup options and remove dead flags
Hide advanced/internal `ktx setup` options from --help output using .hideHelp() so the command surface is approachable for new users. Remove the --project, --agent-scope, and --skip-initial-source-ingest flags that are no longer needed. Update docs and tests to match. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
f219ba22a6
commit
a9bc0431ca
5 changed files with 185 additions and 198 deletions
|
|
@ -18,8 +18,6 @@ ktx setup [options]
|
|||
| Flag | Description | Default |
|
||||
|------|-------------|---------|
|
||||
| `--project-dir <path>` | KTX project directory | `KTX_PROJECT_DIR`, nearest `ktx.yaml`, or cwd |
|
||||
| `--new` | Create a new KTX project before setup | `false` |
|
||||
| `--existing` | Use an existing KTX project | `false` |
|
||||
| `--yes` | Accept safe defaults in non-interactive setup | `false` |
|
||||
| `--no-input` | Disable interactive terminal input | — |
|
||||
|
||||
|
|
@ -29,76 +27,11 @@ ktx setup [options]
|
|||
|------|-------------|---------|
|
||||
| `--agents` | Install agent integration only | `false` |
|
||||
| `--target <target>` | Agent target (`claude-code`, `codex`, `cursor`, `opencode`, `universal`) | — |
|
||||
| `--agent-scope <scope>` | Agent install scope (`project` or `global`) | `project` |
|
||||
| `--project` | Install agent integration into the project scope | `false` |
|
||||
| `--global` | Install agent integration into the global target scope (Claude Code and Codex only) | `false` |
|
||||
| `--skip-agents` | Leave agent integration incomplete for now | `false` |
|
||||
|
||||
### LLM Configuration
|
||||
|
||||
| Flag | Description | Default |
|
||||
|------|-------------|---------|
|
||||
| `--anthropic-api-key-env <name>` | Environment variable containing the Anthropic API key | — |
|
||||
| `--anthropic-api-key-file <path>` | File containing the Anthropic API key | — |
|
||||
| `--anthropic-model <model>` | Anthropic model ID to validate and save | — |
|
||||
| `--skip-llm` | Leave LLM setup incomplete for now | `false` |
|
||||
|
||||
### Embedding Configuration
|
||||
|
||||
| Flag | Description | Default |
|
||||
|------|-------------|---------|
|
||||
| `--embedding-backend <backend>` | Embedding backend (`openai` or `sentence-transformers`) | — |
|
||||
| `--embedding-api-key-env <name>` | Environment variable containing the embedding provider API key | — |
|
||||
| `--embedding-api-key-file <path>` | File containing the embedding provider API key | — |
|
||||
| `--skip-embeddings` | Leave embedding setup incomplete for now | `false` |
|
||||
|
||||
### Database Configuration
|
||||
|
||||
| Flag | Description | Default |
|
||||
|------|-------------|---------|
|
||||
| `--database <driver>` | Database driver to configure; repeatable (`sqlite`, `postgres`, `mysql`, `clickhouse`, `sqlserver`, `bigquery`, `snowflake`) | — |
|
||||
| `--database-connection-id <id>` | Existing or new connection id; repeatable | — |
|
||||
| `--new-database-connection-id <id>` | Connection id for one new database connection | — |
|
||||
| `--database-url <url>` | URL, `env:NAME`, or `file:/path` for one new URL-style database connection | — |
|
||||
| `--database-schema <schema>` | Database schema to include; repeatable | — |
|
||||
| `--skip-databases` | Leave database setup incomplete | `false` |
|
||||
|
||||
### Historic SQL
|
||||
|
||||
| Flag | Description | Default |
|
||||
|------|-------------|---------|
|
||||
| `--enable-historic-sql` | Enable Historic SQL when the selected database supports it | `false` |
|
||||
| `--disable-historic-sql` | Disable Historic SQL for the selected database | `false` |
|
||||
| `--historic-sql-window-days <number>` | Historic SQL query-history window in days | — |
|
||||
| `--historic-sql-min-executions <number>` | Minimum executions for a Historic SQL template | — |
|
||||
| `--historic-sql-min-calls <number>` | Alias for `--historic-sql-min-executions` for one release | — |
|
||||
| `--historic-sql-service-account-pattern <pattern>` | Historic SQL service-account regex; repeatable | — |
|
||||
| `--historic-sql-redaction-pattern <pattern>` | Historic SQL SQL-literal redaction regex; repeatable | — |
|
||||
|
||||
### Context Source Configuration
|
||||
|
||||
| Flag | Description | Default |
|
||||
|------|-------------|---------|
|
||||
| `--source <type>` | Source connector type (`dbt`, `metricflow`, `metabase`, `looker`, `lookml`, `notion`) | — |
|
||||
| `--source-connection-id <id>` | Connection id for source setup | — |
|
||||
| `--source-path <path>` | Local source path for dbt, MetricFlow, or LookML | — |
|
||||
| `--source-git-url <url>` | Git URL for dbt, MetricFlow, or LookML | — |
|
||||
| `--source-branch <branch>` | Git branch for source setup | — |
|
||||
| `--source-subpath <path>` | Repo subpath for source setup | — |
|
||||
| `--source-auth-token-ref <ref>` | `env:` or `file:` credential ref for source repo auth | — |
|
||||
| `--source-url <url>` | Source service URL for Metabase or Looker | — |
|
||||
| `--source-api-key-ref <ref>` | `env:` or `file:` API key ref for Metabase or Notion | — |
|
||||
| `--source-client-id <id>` | Looker client id | — |
|
||||
| `--source-client-secret-ref <ref>` | `env:` or `file:` Looker client secret ref | — |
|
||||
| `--source-warehouse-connection-id <id>` | Mapped warehouse connection id | — |
|
||||
| `--source-project-name <name>` | dbt project name override | — |
|
||||
| `--source-profiles-path <path>` | dbt profiles path | — |
|
||||
| `--source-target <target>` | dbt target or source-specific mapping target | — |
|
||||
| `--metabase-database-id <id>` | Metabase database id to map | — |
|
||||
| `--notion-crawl-mode <mode>` | Notion crawl mode (`all_accessible` or `selected_roots`) | — |
|
||||
| `--notion-root-page-id <id>` | Notion root page id; repeatable | — |
|
||||
| `--skip-initial-source-ingest` | Validate source setup without building source context during setup | `false` |
|
||||
| `--skip-sources` | Mark optional source setup complete with no sources | `false` |
|
||||
The setup wizard is the public configuration interface. It prompts for LLM
|
||||
credentials, embeddings, database connections, context sources, Historic SQL,
|
||||
and agent integration when those values are needed.
|
||||
|
||||
## Examples
|
||||
|
||||
|
|
@ -106,17 +39,8 @@ ktx setup [options]
|
|||
# Run the interactive setup wizard
|
||||
ktx setup
|
||||
|
||||
# Create a new project and run setup
|
||||
ktx setup --new
|
||||
|
||||
# Resume setup in an existing project
|
||||
ktx setup --existing
|
||||
|
||||
# Non-interactive setup with Anthropic key from environment
|
||||
ktx setup --yes --anthropic-api-key-env ANTHROPIC_API_KEY
|
||||
|
||||
# Set up a Postgres connection
|
||||
ktx setup --database postgres --database-url "env:DATABASE_URL"
|
||||
# Run setup for a specific project directory
|
||||
ktx setup --project-dir ./analytics
|
||||
|
||||
# Install agent integration for Claude Code only
|
||||
ktx setup --agents --target claude-code
|
||||
|
|
@ -124,12 +48,6 @@ ktx setup --agents --target claude-code
|
|||
# Install agent integration globally for Codex
|
||||
ktx setup --agents --target codex --global
|
||||
|
||||
# Add a dbt source from a local path
|
||||
ktx setup --source dbt --source-path ./my-dbt-project
|
||||
|
||||
# Skip optional steps for a minimal setup
|
||||
ktx setup --skip-sources --skip-agents
|
||||
|
||||
# Check setup readiness
|
||||
ktx status
|
||||
```
|
||||
|
|
@ -156,5 +74,5 @@ Agent integration ready: yes (codex:project)
|
|||
|-------|-------|----------|
|
||||
| Setup resumes an unexpected project | `KTX_PROJECT_DIR` or nearest `ktx.yaml` points to another directory | Pass `--project-dir <path>` explicitly |
|
||||
| Health check for model fails | Provider key or model id is invalid | Set the correct environment variable or secret file and rerun setup |
|
||||
| Setup cannot run in CI | Interactive prompts need a TTY | Use `--yes --no-input` with explicit flags for required values |
|
||||
| Setup cannot run in CI | Interactive prompts need a TTY | Run setup interactively before CI, or provide a fixture `ktx.yaml` for automated tests |
|
||||
| Agent integration missing | Setup skipped the agents step | Run `ktx setup --agents --target <target>` |
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ Agent integration ready: yes (claude-code:project)
|
|||
| Local embeddings hang or fail | The managed Python runtime cannot start or the local model runtime is unavailable | Install `uv`, run `ktx dev runtime status`, then run `ktx dev runtime install --feature local-embeddings --yes` and rerun setup |
|
||||
| Database connection test fails | Credentials, network access, warehouse, database, or schema value is wrong | Test the same URL with the database's native client, then rerun `ktx setup` and reconfigure the connection |
|
||||
| `KTX context built: no` in `ktx status` | Setup saved configuration but did not build context | Run `ktx setup` and choose to build context now |
|
||||
| Agent integration is incomplete | Setup skipped the agents step or the target was not installed | Run `ktx setup --agents --target codex --project` using the target you need |
|
||||
| Agent integration is incomplete | Setup skipped the agents step or the target was not installed | Run `ktx setup --agents --target codex` using the target you need |
|
||||
|
||||
## Next steps
|
||||
|
||||
|
|
|
|||
|
|
@ -64,13 +64,6 @@ function sourceType(value: string): KtxSetupSourceType {
|
|||
throw new InvalidArgumentError(`invalid choice '${value}'`);
|
||||
}
|
||||
|
||||
function agentScope(value: string): 'project' | 'global' {
|
||||
if (value === 'project' || value === 'global') {
|
||||
return value;
|
||||
}
|
||||
throw new InvalidArgumentError(`invalid choice '${value}'`);
|
||||
}
|
||||
|
||||
function positiveNumber(value: string): number {
|
||||
const parsed = Number.parseInt(value, 10);
|
||||
if (!Number.isInteger(parsed) || parsed <= 0) {
|
||||
|
|
@ -97,7 +90,6 @@ function shouldShowSetupEntryMenu(
|
|||
agents?: boolean;
|
||||
target?: string;
|
||||
global?: boolean;
|
||||
project?: boolean;
|
||||
skipAgents?: boolean;
|
||||
yes?: boolean;
|
||||
input?: boolean;
|
||||
|
|
@ -142,7 +134,6 @@ function shouldShowSetupEntryMenu(
|
|||
metabaseDatabaseId?: number;
|
||||
notionCrawlMode?: string;
|
||||
notionRootPageId?: string[];
|
||||
skipInitialSourceIngest?: boolean;
|
||||
skipSources?: boolean;
|
||||
},
|
||||
command: Command,
|
||||
|
|
@ -172,7 +163,6 @@ function shouldShowSetupEntryMenu(
|
|||
'agents',
|
||||
'target',
|
||||
'global',
|
||||
'project',
|
||||
'skipAgents',
|
||||
'yes',
|
||||
'input',
|
||||
|
|
@ -211,7 +201,6 @@ function shouldShowSetupEntryMenu(
|
|||
'sourceTarget',
|
||||
'metabaseDatabaseId',
|
||||
'notionCrawlMode',
|
||||
'skipInitialSourceIngest',
|
||||
'skipSources',
|
||||
].some((optionName) => optionWasSpecified(command, optionName));
|
||||
}
|
||||
|
|
@ -220,9 +209,9 @@ export function registerSetupCommands(program: Command, context: KtxCliCommandCo
|
|||
const setup = program
|
||||
.command('setup')
|
||||
.description('Set up or resume a local KTX project')
|
||||
.option('--project-dir <path>', 'KTX project directory')
|
||||
.option('--new', 'Create a new KTX project before setup', false)
|
||||
.option('--existing', 'Use an existing KTX project', false)
|
||||
.addOption(new Option('--project-dir <path>', 'KTX project directory').hideHelp())
|
||||
.addOption(new Option('--new', 'Create a new KTX project before setup').hideHelp().default(false))
|
||||
.addOption(new Option('--existing', 'Use an existing KTX project').hideHelp().default(false))
|
||||
.option('--agents', 'Install agent integration only', false)
|
||||
.addOption(
|
||||
new Option('--target <target>', 'Agent target').choices([
|
||||
|
|
@ -233,94 +222,124 @@ export function registerSetupCommands(program: Command, context: KtxCliCommandCo
|
|||
'universal',
|
||||
]),
|
||||
)
|
||||
.addOption(new Option('--agent-scope <scope>', 'Agent install scope').argParser(agentScope).default('project'))
|
||||
.option('--project', 'Install agent integration into the project scope', false)
|
||||
.option('--global', 'Install agent integration into the global target scope', false)
|
||||
.option('--skip-agents', 'Leave agent integration incomplete for now', false)
|
||||
.addOption(new Option('--skip-agents', 'Leave agent integration incomplete for now').hideHelp().default(false))
|
||||
.option('--yes', 'Accept safe defaults in non-interactive setup', false)
|
||||
.option('--no-input', 'Disable interactive terminal input')
|
||||
.addOption(new Option('--llm-backend <backend>', 'LLM backend').argParser(llmBackend))
|
||||
.option('--anthropic-api-key-env <name>', 'Environment variable containing the Anthropic API key')
|
||||
.option('--anthropic-api-key-file <path>', 'File containing the Anthropic API key')
|
||||
.option('--anthropic-model <model>', 'Anthropic model ID to validate and save')
|
||||
.option('--vertex-project <project>', 'Google Vertex AI project ID, env:NAME, or file:/path')
|
||||
.option('--vertex-location <location>', 'Google Vertex AI location, env:NAME, or file:/path')
|
||||
.addOption(new Option('--skip-llm', 'Leave LLM setup incomplete for now').hideHelp().default(false))
|
||||
.addOption(new Option('--embedding-backend <backend>', 'Embedding backend').argParser(embeddingBackend))
|
||||
.option('--embedding-api-key-env <name>', 'Environment variable containing the embedding provider API key')
|
||||
.option('--embedding-api-key-file <path>', 'File containing the embedding provider API key')
|
||||
.addOption(new Option('--skip-embeddings', 'Leave embedding setup incomplete for now').hideHelp().default(false))
|
||||
.option(
|
||||
'--database <driver>',
|
||||
'Database driver to configure; repeatable',
|
||||
(value, previous: KtxSetupDatabaseDriver[]) => {
|
||||
return [...previous, databaseDriver(value)];
|
||||
},
|
||||
[] as KtxSetupDatabaseDriver[],
|
||||
)
|
||||
.option(
|
||||
'--database-connection-id <id>',
|
||||
'Existing selected connection id or new connection id',
|
||||
(value, previous: string[]) => [...previous, value],
|
||||
[],
|
||||
)
|
||||
.option('--new-database-connection-id <id>', 'Connection id for one new database connection', (value) => {
|
||||
if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value)) {
|
||||
throw new InvalidArgumentError(`Unsafe connection id: ${value}`);
|
||||
}
|
||||
return value;
|
||||
})
|
||||
.option('--database-url <url>', 'URL, env:NAME, or file:/path for one new URL-style database connection')
|
||||
.option(
|
||||
'--database-schema <schema>',
|
||||
'Database schema to include; repeatable',
|
||||
(value, previous: string[]) => [...previous, value],
|
||||
[],
|
||||
)
|
||||
.option('--enable-historic-sql', 'Enable Historic SQL when the selected database supports it', false)
|
||||
.option('--disable-historic-sql', 'Disable Historic SQL for the selected database', false)
|
||||
.option('--historic-sql-window-days <number>', 'Historic SQL query-history window', positiveInteger)
|
||||
.option('--historic-sql-min-executions <number>', 'Minimum Historic SQL executions for a template', positiveInteger)
|
||||
.option(
|
||||
'--historic-sql-service-account-pattern <pattern>',
|
||||
'Historic SQL service-account regex; repeatable',
|
||||
(value, previous: string[]) => [...previous, value],
|
||||
[],
|
||||
)
|
||||
.option(
|
||||
'--historic-sql-redaction-pattern <pattern>',
|
||||
'Historic SQL SQL-literal redaction regex; repeatable',
|
||||
(value, previous: string[]) => [...previous, value],
|
||||
[],
|
||||
)
|
||||
.option('--skip-databases', 'Leave database setup incomplete; KTX cannot work until a primary source is added', false)
|
||||
.addOption(new Option('--source <type>', 'Source connector type').argParser(sourceType))
|
||||
.option('--source-connection-id <id>', 'Connection id for source setup')
|
||||
.option('--source-path <path>', 'Local source path for dbt, MetricFlow, or LookML')
|
||||
.option('--source-git-url <url>', 'Git URL for dbt, MetricFlow, or LookML')
|
||||
.option('--source-branch <branch>', 'Git branch for source setup')
|
||||
.option('--source-subpath <path>', 'Repo subpath for source setup')
|
||||
.option('--source-auth-token-ref <ref>', 'env: or file: credential ref for source repo auth')
|
||||
.option('--source-url <url>', 'Source service URL for Metabase or Looker')
|
||||
.option('--source-api-key-ref <ref>', 'env: or file: API key ref for Metabase or Notion')
|
||||
.option('--source-client-id <id>', 'Looker client id')
|
||||
.option('--source-client-secret-ref <ref>', 'env: or file: Looker client secret ref')
|
||||
.option('--source-warehouse-connection-id <id>', 'Mapped warehouse connection id')
|
||||
.option('--source-project-name <name>', 'dbt project name override')
|
||||
.option('--source-profiles-path <path>', 'dbt profiles path')
|
||||
.option('--source-target <target>', 'dbt target or source-specific mapping target')
|
||||
.option('--metabase-database-id <id>', 'Metabase database id to map', positiveNumber)
|
||||
.addOption(new Option('--llm-backend <backend>', 'LLM backend').argParser(llmBackend).hideHelp())
|
||||
.addOption(
|
||||
new Option('--notion-crawl-mode <mode>', 'Notion crawl mode').choices(['all_accessible', 'selected_roots']),
|
||||
new Option('--anthropic-api-key-env <name>', 'Environment variable containing the Anthropic API key').hideHelp(),
|
||||
)
|
||||
.option(
|
||||
'--notion-root-page-id <id>',
|
||||
'Notion root page id; repeatable',
|
||||
(value, previous: string[]) => [...previous, value],
|
||||
[],
|
||||
.addOption(
|
||||
new Option('--anthropic-api-key-file <path>', 'File containing the Anthropic API key').hideHelp(),
|
||||
)
|
||||
.option('--skip-initial-source-ingest', 'Validate source setup without building source context during setup', false)
|
||||
.option('--skip-sources', 'Mark optional source setup complete with no sources', false)
|
||||
.addOption(new Option('--anthropic-model <model>', 'Anthropic model ID to validate and save').hideHelp())
|
||||
.addOption(new Option('--vertex-project <project>', 'Google Vertex AI project ID, env:NAME, or file:/path').hideHelp())
|
||||
.addOption(new Option('--vertex-location <location>', 'Google Vertex AI location, env:NAME, or file:/path').hideHelp())
|
||||
.addOption(new Option('--skip-llm', 'Leave LLM setup incomplete for now').hideHelp().default(false))
|
||||
.addOption(new Option('--embedding-backend <backend>', 'Embedding backend').argParser(embeddingBackend).hideHelp())
|
||||
.addOption(
|
||||
new Option(
|
||||
'--embedding-api-key-env <name>',
|
||||
'Environment variable containing the embedding provider API key',
|
||||
).hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--embedding-api-key-file <path>', 'File containing the embedding provider API key').hideHelp(),
|
||||
)
|
||||
.addOption(new Option('--skip-embeddings', 'Leave embedding setup incomplete for now').hideHelp().default(false))
|
||||
.addOption(
|
||||
new Option('--database <driver>', 'Database driver to configure; repeatable')
|
||||
.argParser((value, previous: KtxSetupDatabaseDriver[]) => {
|
||||
return [...previous, databaseDriver(value)];
|
||||
})
|
||||
.default([] as KtxSetupDatabaseDriver[])
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--database-connection-id <id>', 'Existing selected connection id or new connection id')
|
||||
.argParser((value, previous: string[]) => [...previous, value])
|
||||
.default([] as string[])
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--new-database-connection-id <id>', 'Connection id for one new database connection')
|
||||
.argParser((value) => {
|
||||
if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(value)) {
|
||||
throw new InvalidArgumentError(`Unsafe connection id: ${value}`);
|
||||
}
|
||||
return value;
|
||||
})
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--database-url <url>', 'URL, env:NAME, or file:/path for one new URL-style database connection').hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--database-schema <schema>', 'Database schema to include; repeatable')
|
||||
.argParser((value, previous: string[]) => [...previous, value])
|
||||
.default([] as string[])
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--enable-historic-sql', 'Enable Historic SQL when the selected database supports it')
|
||||
.hideHelp()
|
||||
.default(false),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--disable-historic-sql', 'Disable Historic SQL for the selected database').hideHelp().default(false),
|
||||
)
|
||||
.addOption(new Option('--historic-sql-window-days <number>', 'Historic SQL query-history window').argParser(positiveInteger).hideHelp())
|
||||
.addOption(
|
||||
new Option('--historic-sql-min-executions <number>', 'Minimum Historic SQL executions for a template')
|
||||
.argParser(positiveInteger)
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--historic-sql-service-account-pattern <pattern>', 'Historic SQL service-account regex; repeatable')
|
||||
.argParser((value, previous: string[]) => [...previous, value])
|
||||
.default([] as string[])
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--historic-sql-redaction-pattern <pattern>', 'Historic SQL SQL-literal redaction regex; repeatable')
|
||||
.argParser((value, previous: string[]) => [...previous, value])
|
||||
.default([] as string[])
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--skip-databases', 'Leave database setup incomplete; KTX cannot work until a primary source is added')
|
||||
.hideHelp()
|
||||
.default(false),
|
||||
)
|
||||
.addOption(new Option('--source <type>', 'Source connector type').argParser(sourceType).hideHelp())
|
||||
.addOption(new Option('--source-connection-id <id>', 'Connection id for source setup').hideHelp())
|
||||
.addOption(new Option('--source-path <path>', 'Local source path for dbt, MetricFlow, or LookML').hideHelp())
|
||||
.addOption(new Option('--source-git-url <url>', 'Git URL for dbt, MetricFlow, or LookML').hideHelp())
|
||||
.addOption(new Option('--source-branch <branch>', 'Git branch for source setup').hideHelp())
|
||||
.addOption(new Option('--source-subpath <path>', 'Repo subpath for source setup').hideHelp())
|
||||
.addOption(new Option('--source-auth-token-ref <ref>', 'env: or file: credential ref for source repo auth').hideHelp())
|
||||
.addOption(new Option('--source-url <url>', 'Source service URL for Metabase or Looker').hideHelp())
|
||||
.addOption(new Option('--source-api-key-ref <ref>', 'env: or file: API key ref for Metabase or Notion').hideHelp())
|
||||
.addOption(new Option('--source-client-id <id>', 'Looker client id').hideHelp())
|
||||
.addOption(new Option('--source-client-secret-ref <ref>', 'env: or file: Looker client secret ref').hideHelp())
|
||||
.addOption(new Option('--source-warehouse-connection-id <id>', 'Mapped warehouse connection id').hideHelp())
|
||||
.addOption(new Option('--source-project-name <name>', 'dbt project name override').hideHelp())
|
||||
.addOption(new Option('--source-profiles-path <path>', 'dbt profiles path').hideHelp())
|
||||
.addOption(new Option('--source-target <target>', 'dbt target or source-specific mapping target').hideHelp())
|
||||
.addOption(new Option('--metabase-database-id <id>', 'Metabase database id to map').argParser(positiveNumber).hideHelp())
|
||||
.addOption(
|
||||
new Option('--notion-crawl-mode <mode>', 'Notion crawl mode')
|
||||
.choices(['all_accessible', 'selected_roots'])
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(
|
||||
new Option('--notion-root-page-id <id>', 'Notion root page id; repeatable')
|
||||
.argParser((value, previous: string[]) => [...previous, value])
|
||||
.default([] as string[])
|
||||
.hideHelp(),
|
||||
)
|
||||
.addOption(new Option('--skip-sources', 'Mark optional source setup complete with no sources').hideHelp().default(false))
|
||||
.showHelpAfterError();
|
||||
|
||||
setup.hook('preAction', (_thisCommand, actionCommand) => {
|
||||
|
|
@ -371,7 +390,7 @@ export function registerSetupCommands(program: Command, context: KtxCliCommandCo
|
|||
}
|
||||
|
||||
const mode = options.new ? 'new' : options.existing ? 'existing' : 'auto';
|
||||
const resolvedAgentScope = options.global ? 'global' : options.agentScope;
|
||||
const resolvedAgentScope = options.global ? 'global' : 'project';
|
||||
await runSetupArgs(context, {
|
||||
command: 'run',
|
||||
projectDir: resolveCommandProjectDir(command),
|
||||
|
|
|
|||
|
|
@ -444,20 +444,54 @@ describe('runKtxCli', () => {
|
|||
expect(io.stderr()).toContain('Choose only one runtime install mode: --yes or --no-input');
|
||||
});
|
||||
|
||||
it('documents setup as a bare command without subcommands', async () => {
|
||||
it('documents setup with only the common interactive options visible', async () => {
|
||||
const testIo = makeIo();
|
||||
|
||||
await expect(runKtxCli(['setup', '--help'], testIo.io)).resolves.toBe(0);
|
||||
|
||||
expect(testIo.stdout()).toContain('Usage: ktx setup [options]');
|
||||
expect(testIo.stdout()).not.toContain('Commands:');
|
||||
expect(testIo.stdout()).not.toContain('setup demo');
|
||||
expect(testIo.stdout()).not.toContain('setup context');
|
||||
expect(testIo.stdout()).not.toContain('--skip-llm');
|
||||
expect(testIo.stdout()).not.toContain('--skip-embeddings');
|
||||
expect(testIo.stdout()).not.toContain('--embedding-model');
|
||||
expect(testIo.stdout()).not.toContain('--embedding-dimensions');
|
||||
expect(testIo.stdout()).not.toContain('--embedding-base-url');
|
||||
const stdout = testIo.stdout();
|
||||
expect(stdout).toContain('Usage: ktx setup [options]');
|
||||
expect(stdout).toContain('--agents');
|
||||
expect(stdout).toContain('--target <target>');
|
||||
expect(stdout).toContain('--global');
|
||||
expect(stdout).toContain('--yes');
|
||||
expect(stdout).toContain('--no-input');
|
||||
expect(stdout).toContain('Global Options:');
|
||||
expect(stdout.match(/--project-dir <path>/g)).toHaveLength(1);
|
||||
expect(stdout).not.toContain('Commands:');
|
||||
expect(stdout).not.toContain('setup demo');
|
||||
expect(stdout).not.toContain('setup context');
|
||||
|
||||
for (const hiddenFlag of [
|
||||
'--new',
|
||||
'--existing',
|
||||
'--agent-scope',
|
||||
'--skip-agents',
|
||||
'--llm-backend',
|
||||
'--anthropic-api-key-env',
|
||||
'--vertex-project',
|
||||
'--embedding-backend',
|
||||
'--database ',
|
||||
'--database-connection-id',
|
||||
'--new-database-connection-id',
|
||||
'--enable-historic-sql',
|
||||
'--historic-sql-min-executions',
|
||||
'--skip-databases',
|
||||
'--source ',
|
||||
'--source-connection-id',
|
||||
'--metabase-database-id',
|
||||
'--notion-root-page-id',
|
||||
'--skip-initial-source-ingest',
|
||||
'--skip-sources',
|
||||
'--skip-llm',
|
||||
'--skip-embeddings',
|
||||
'--embedding-model',
|
||||
'--embedding-dimensions',
|
||||
'--embedding-base-url',
|
||||
]) {
|
||||
expect(stdout).not.toContain(hiddenFlag);
|
||||
}
|
||||
expect(stdout).not.toMatch(/^ --project\s/m);
|
||||
expect(testIo.stderr()).toBe('');
|
||||
});
|
||||
|
||||
|
|
@ -725,6 +759,23 @@ describe('runKtxCli', () => {
|
|||
expect(setup).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('rejects removed setup options', async () => {
|
||||
const setup = vi.fn(async () => 0);
|
||||
const cases = [
|
||||
['setup', '--project'],
|
||||
['setup', '--agent-scope', 'global'],
|
||||
['setup', '--skip-initial-source-ingest'],
|
||||
];
|
||||
|
||||
for (const args of cases) {
|
||||
const testIo = makeIo();
|
||||
await expect(runKtxCli(['--project-dir', tempDir, ...args], testIo.io, { setup })).resolves.toBe(1);
|
||||
expect(testIo.stderr()).toMatch(/unknown option|error:/i);
|
||||
}
|
||||
|
||||
expect(setup).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('prints ingest help without invoking ingest execution', async () => {
|
||||
const testIo = makeIo();
|
||||
const ingest = vi.fn();
|
||||
|
|
@ -1250,7 +1301,6 @@ describe('runKtxCli', () => {
|
|||
'--agents',
|
||||
'--target',
|
||||
'codex',
|
||||
'--project',
|
||||
'--no-input',
|
||||
'--yes',
|
||||
],
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ export function plannedKtxAgentFiles(input: {
|
|||
{ kind: 'file', path: join(codexHome, 'instructions/ktx.md'), role: 'rule' as const },
|
||||
];
|
||||
}
|
||||
throw new Error(`Global ${input.target} installation is not supported; use --project.`);
|
||||
throw new Error(`Global ${input.target} installation is not supported; omit --global.`);
|
||||
}
|
||||
|
||||
const root = resolve(input.projectDir);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue