diff --git a/README.md b/README.md index cb9d25b0..8dadd3e1 100644 --- a/README.md +++ b/README.md @@ -162,7 +162,8 @@ ktx sl query --connection-id warehouse --measure orders.revenue --format sql During setup, choose **Ask data questions with ktx MCP** for agent clients. Choose **Ask data questions + manage ktx with CLI commands** when an operator -agent also needs pinned `ktx` admin commands. +agent also needs pinned `ktx` admin commands. Choose **Skip agent setup for +now** to leave agent integration incomplete and run `ktx setup --agents` later. After setup, **ktx** prints **Required before using agents** with the exact commands to run. If the output includes `ktx mcp start --project-dir ...`, run diff --git a/docs-site/content/docs/integrations/agent-clients.mdx b/docs-site/content/docs/integrations/agent-clients.mdx index 36aef1c3..46a1ec8b 100644 --- a/docs-site/content/docs/integrations/agent-clients.mdx +++ b/docs-site/content/docs/integrations/agent-clients.mdx @@ -9,7 +9,9 @@ admin surface for setup, ingest, status, daemon lifecycle, and debugging. Run `ktx setup` and select your agent client targets, or configure manually using the snippets below. Choose **Ask data questions with ktx MCP** for agent clients. Choose **Ask data questions + manage ktx with CLI commands** only when -a developer or operator agent also needs pinned `ktx` admin commands. +a developer or operator agent also needs pinned `ktx` admin commands. Choose +**Skip agent setup for now** to leave agent integration incomplete and run +`ktx setup --agents` later. ## Install with setup @@ -43,14 +45,19 @@ ktx setup --agents --target codex --global manifest lets status checks report agent readiness and lets future cleanup remove only files **ktx** installed. -The interactive command asks two questions: +The interactive command asks what agents can do first: ```txt ◆ What should agents be allowed to do with this ktx project? │ ○ Ask data questions with ktx MCP │ ○ Ask data questions + manage ktx with CLI commands +│ ○ Skip agent setup for now └ +``` +If you choose an install mode, it then asks which targets to install: + +```txt ◆ Which agent targets should ktx install? │ ◻ Claude Code │ ◻ Claude Desktop diff --git a/packages/cli/src/setup-agents.test.ts b/packages/cli/src/setup-agents.test.ts index a8090780..bd521787 100644 --- a/packages/cli/src/setup-agents.test.ts +++ b/packages/cli/src/setup-agents.test.ts @@ -418,6 +418,11 @@ describe('setup agents', () => { label: 'Ask data questions + manage KTX with CLI commands', hint: 'Adds an admin CLI skill so agents can run ktx status, sl, wiki, and setup commands.', }, + { + value: 'skip', + label: 'Skip agent setup for now', + hint: 'Leaves agent integration incomplete. You can run ktx setup --agents later.', + }, ], }); expect(prompts.multiselect).toHaveBeenCalledWith( @@ -427,6 +432,58 @@ describe('setup agents', () => { ); }); + it('lets interactive setup skip agent integration from the connection mode prompt', async () => { + const io = makeIo(); + const prompts = { + select: vi.fn(async () => 'skip'), + multiselect: vi.fn(async () => { + throw new Error('target selection should not run'); + }), + cancel: vi.fn(), + }; + + await expect( + runKtxSetupAgentsStep( + { + projectDir: tempDir, + inputMode: 'auto', + yes: false, + agents: true, + scope: 'project', + mode: 'mcp', + skipAgents: false, + }, + io.io, + { prompts }, + ), + ).resolves.toMatchObject({ status: 'skipped', projectDir: tempDir }); + + expect(prompts.select).toHaveBeenCalledWith({ + message: 'What should agents be allowed to do with this KTX project?', + options: [ + { + value: 'mcp', + label: 'Ask data questions with KTX MCP', + hint: 'Installs the MCP connection and analytics workflow skill. Best for normal use.', + }, + { + value: 'mcp-cli', + label: 'Ask data questions + manage KTX with CLI commands', + hint: 'Adds an admin CLI skill so agents can run ktx status, sl, wiki, and setup commands.', + }, + { + value: 'skip', + label: 'Skip agent setup for now', + hint: 'Leaves agent integration incomplete. You can run ktx setup --agents later.', + }, + ], + }); + expect(prompts.multiselect).not.toHaveBeenCalled(); + expect(io.stdout()).toContain('Agent integration skipped.'); + await expect(stat(join(tempDir, '.ktx/agents/install-manifest.json'))).rejects.toThrow(); + expect(await readKtxSetupState(tempDir)).toEqual({ completed_steps: [] }); + }); + it('prompts for global scope when every selected target supports it', async () => { const home = await mkdtemp(join(tmpdir(), 'ktx-setup-agents-home-')); const previousHome = process.env.HOME; diff --git a/packages/cli/src/setup-agents.ts b/packages/cli/src/setup-agents.ts index 113718cd..99d510c5 100644 --- a/packages/cli/src/setup-agents.ts +++ b/packages/cli/src/setup-agents.ts @@ -21,6 +21,7 @@ export type KtxAgentTarget = 'claude-code' | 'claude-desktop' | 'codex' | 'curso export type KtxAgentScope = 'project' | 'global' | 'local'; /** @internal */ export type KtxAgentInstallMode = 'mcp' | 'mcp-cli'; +type KtxAgentModePromptChoice = KtxAgentInstallMode | 'skip' | 'back'; export interface KtxSetupAgentsArgs { projectDir: string; @@ -1122,9 +1123,18 @@ export async function runKtxSetupAgentsStep( label: 'Ask data questions + manage KTX with CLI commands', hint: 'Adds an admin CLI skill so agents can run ktx status, sl, wiki, and setup commands.', }, + { + value: 'skip', + label: 'Skip agent setup for now', + hint: 'Leaves agent integration incomplete. You can run ktx setup --agents later.', + }, ], - })) as KtxAgentInstallMode | 'back'); + })) as KtxAgentModePromptChoice); if (mode === 'back') return { status: 'skipped', projectDir: args.projectDir }; + if (mode === 'skip') { + io.stdout.write('│ Agent integration skipped.\n'); + return { status: 'skipped', projectDir: args.projectDir }; + } const targets = args.target !== undefined