feat(cli): remove default agent and resolve from saved config or init - #271
Conversation
Instead of defaulting to Claude when no --agent flag is provided, the chat command now checks the saved atomic config for a previously selected agent. If none is found, it runs init to prompt the user, ensuring an explicit agent choice. Assistant-model: Claude Code
PR Review: feat(cli): remove default agent and resolve from saved config or initSummaryThis PR removes the hardcoded default agent (Claude) from the ✅ What Looks Good
🔧 Suggestions & Issues1. Outdated Comment in
|
There was a problem hiding this comment.
Pull request overview
This PR removes the implicit default agent selection for atomic chat and instead resolves the agent from persisted .atomic/settings.json (local override + global fallback) or triggers atomic init to prompt the user on first run.
Changes:
- Removed the
--agentdefault from the CLI and added resolution viareadAtomicConfig(...), with a fallback to runninginit. - Updated
chatCommandto requireagentTypeat runtime (no longer defaulting to"claude"). - Updated
bun.lockmetadata (configVersion).
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/commands/chat.ts | Removes default agent behavior and enforces presence of agentType before proceeding. |
| src/cli.ts | Resolves agent from CLI flag → saved config → init prompt; updates help text accordingly. |
| bun.lock | Lockfile metadata updated (configVersion). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| // If still no agent (first run), run init which prompts for selection | ||
| if (!agentType) { | ||
| await initCommand({ showBanner: true }); |
There was a problem hiding this comment.
The fallback-to-init path ignores global CLI flags. Here initCommand({ showBanner: true }) does not respect --no-banner, and it also drops --force/--yes, which can change behavior for users expecting non-interactive / overwrite semantics. Consider reading const globalOpts = program.opts() and passing showBanner: globalOpts.banner !== false, force: globalOpts.force, and yes: globalOpts.yes (matching the init command behavior).
| await initCommand({ showBanner: true }); | |
| const globalOpts = program.opts(); | |
| await initCommand({ | |
| showBanner: globalOpts.banner !== false, | |
| force: globalOpts.force, | |
| yes: globalOpts.yes, | |
| }); |
| // Validate agent choice | ||
| if (!validAgents.includes(agentType)) { | ||
| console.error(`${COLORS.red}Error: Unknown agent '${agentType}'${COLORS.reset}`); | ||
| console.error(`Valid agents: ${agentChoices}`); | ||
| process.exit(1); |
There was a problem hiding this comment.
Agent validation currently uses Object.keys(AGENT_CONFIG) + includes, which doesn’t type-narrow agentType and duplicates the agent list logic. Since config.ts already exposes isValidAgent(key: string): key is AgentKey, using that guard here would both validate and narrow the type in one step (and keep this code resilient if agents are added/removed).
| const exitCode = await chatCommand({ | ||
| agentType: localOpts.agent as "claude" | "opencode" | "copilot", | ||
| agentType: agentType as "claude" | "opencode" | "copilot", | ||
| workflow: localOpts.workflow, |
There was a problem hiding this comment.
After validation, agentType is cast to a hard-coded union ("claude" | "opencode" | "copilot"). This will become incorrect the next time AGENT_CONFIG gains an agent and also hides type errors if the validation logic changes. Prefer passing a properly narrowed AgentKey/AgentType (e.g., via isValidAgent narrowing) instead of a literal union cast.
| if (!agentType) { | ||
| throw new Error("agentType is required — resolve via saved config or init before calling chatCommand"); | ||
| } |
There was a problem hiding this comment.
chatCommand now throws if agentType is missing, but the type signature still allows callers to omit it (ChatCommandOptions.agentType? and chatCommand(options: ChatCommandOptions = {})). To prevent accidental runtime failures and make the contract explicit, make agentType required in ChatCommandOptions (or change the function signature to require it and drop the default {}), so TypeScript catches misuses at compile time.
…#271) Instead of defaulting to Claude when no --agent flag is provided, the chat command now checks the saved atomic config for a previously selected agent. If none is found, it runs init to prompt the user, ensuring an explicit agent choice. Assistant-model: Claude Code
Summary
Removes the hardcoded default agent (Claude) from the chat command. Instead, the CLI now resolves the agent from saved configuration or prompts the user via init, ensuring an explicit agent choice every time.
Key Changes
--agentflag insrc/cli.ts:98-99--agent <name>).atomic/settings.json- local or global)initto prompt user selectionchatCommandto require explicitagentTypeparameterBehavior Changes
Before
After
Impact
atomic chatcommand.atomic/settings.json--agentflags continue to work