diff --git a/CLAUDE.md b/CLAUDE.md index ca9ec7930..f3804dee3 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -84,13 +84,13 @@ Relevant resources (use the deepwiki mcp `ask_question` tool for repos): ### Coding Agent Configuration Locations 1. OpenCode: - - global: `~/.opencode` + - global: `$XDG_CONFIG_HOME/.opencode` (default: `~/.config/.opencode`, Windows: `%APPDATA%\\.opencode`) - local: `.opencode` in the project directory 2. Claude Code: - global: `~/.claude` - local: `.claude` in the project directory 3. Copilot CLI: - - global: `~/.config/.copilot` + - global: `~/.config/.copilot` (Windows: `%APPDATA%\\.copilot`) - local: `.github` in the project directory ## Tips diff --git a/bun.lock b/bun.lock index b065a4d67..8b06b94dd 100644 --- a/bun.lock +++ b/bun.lock @@ -31,7 +31,7 @@ }, }, "packages": { - "@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.2.66", "", { "optionalDependencies": { "@img/sharp-darwin-arm64": "^0.34.2", "@img/sharp-darwin-x64": "^0.34.2", "@img/sharp-linux-arm": "^0.34.2", "@img/sharp-linux-arm64": "^0.34.2", "@img/sharp-linux-x64": "^0.34.2", "@img/sharp-linuxmusl-arm64": "^0.34.2", "@img/sharp-linuxmusl-x64": "^0.34.2", "@img/sharp-win32-arm64": "^0.34.2", "@img/sharp-win32-x64": "^0.34.2" }, "peerDependencies": { "zod": "^4.0.0" } }, "sha512-hJL+j35yIkhcryR0kkszLz00lsEWBMu3qx8hazIHh55QV2nnZ6cn3p6oi04/VT84J9YU90jfmDffTQ66RD7YZg=="], + "@anthropic-ai/claude-agent-sdk": ["@anthropic-ai/claude-agent-sdk@0.2.68", "", { "optionalDependencies": { "@img/sharp-darwin-arm64": "^0.34.2", "@img/sharp-darwin-x64": "^0.34.2", "@img/sharp-linux-arm": "^0.34.2", "@img/sharp-linux-arm64": "^0.34.2", "@img/sharp-linux-x64": "^0.34.2", "@img/sharp-linuxmusl-arm64": "^0.34.2", "@img/sharp-linuxmusl-x64": "^0.34.2", "@img/sharp-win32-arm64": "^0.34.2", "@img/sharp-win32-x64": "^0.34.2" }, "peerDependencies": { "zod": "^4.0.0" } }, "sha512-y4n6hTTgAqmiV/pqy1G4OgIdg6gDiAKPJaEgO1NOh7/rdsrXyc/HQoUmUy0ty4HkBq1hasm7hB92wtX3W1UMEw=="], "@azure/abort-controller": ["@azure/abort-controller@2.1.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA=="], diff --git a/package.json b/package.json index 6e8d0ff33..0b3e73db5 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "typescript": "^5.9.3" }, "dependencies": { - "@anthropic-ai/claude-agent-sdk": "^0.2.66", + "@anthropic-ai/claude-agent-sdk": "^0.2.68", "@azure/monitor-opentelemetry": "^1.16.0", "@clack/prompts": "^1.1.0", "@commander-js/extra-typings": "^14.0.0", diff --git a/research/docs/2026-03-04-claude-sdk-discovery-and-atomic-config-sync.md b/research/docs/2026-03-04-claude-sdk-discovery-and-atomic-config-sync.md new file mode 100644 index 000000000..1d22888d7 --- /dev/null +++ b/research/docs/2026-03-04-claude-sdk-discovery-and-atomic-config-sync.md @@ -0,0 +1,186 @@ +--- +date: 2026-03-04 07:53:42 UTC +researcher: OpenCode +git_commit: ec23c76b1c507ce7874eeebaabd7ca42cee01695 +branch: lavaman131/hotfix/claude-code-config +repository: claude-code-config +topic: "Why skills/sub-agents are not detected in Claude Agent SDK, and whether configs are copied/discovered across .opencode/.claude/.github and ~/.atomic mirrors" +tags: [research, codebase, claude-agent-sdk, opencode-sdk, copilot-sdk, config-sync, skills, sub-agents, commands] +status: complete +last_updated: 2026-03-04 +last_updated_by: OpenCode +last_updated_note: "Revised spec summary to explicitly mark SCM skills as the only intentional exception (local init copy), while non-SCM assets are globally mirrored to ~/.atomic" +--- + +# Research + +## Research Question +Figure out why skills and sub-agents are not being detected in Claude Agent SDK. Ensure understanding of whether all skills, commands, and agents are being copied from `.opencode`, `.claude`, and `.github` into `~/.atomic/.opencode`, `~/.atomic/.claude`, and `~/.atomic/.copilot`, and verify discovery behavior for custom agents/skills/commands across Claude, OpenCode, and Copilot SDK integrations. + +## Summary +The implementation separates global baseline sync, project-local SCM skill provisioning, and provider-native runtime discovery. The key behavior is: + +What exists today: +- Non-SCM template assets are globally mirrored to `~/.atomic`: `.claude -> ~/.atomic/.claude`, `.opencode -> ~/.atomic/.opencode`, `.github -> ~/.atomic/.copilot`. +- The only intentional exception is SCM skills (`gh-*`, `sl-*`): they are excluded from global sync and copied/reconciled into project-local `.claude` / `.opencode` / `.github` during `atomic init` (and chat auto-init when missing). +- Claude sub-agents are loaded programmatically into Claude SDK `options.agents` from project/user/atomic directories, and slash agent dispatch is passed as `options.agent`. +- Perceived Claude detection gaps come from split discovery channels: Atomic UI discovers from broader project/user/atomic paths, while Claude native runtime setting sources remain `.claude`/`~/.claude` and runtime does not set `CLAUDE_CONFIG_DIR`. +- Disk skills are often executed through Atomic's command path (`SKILL.md` content injection) in addition to provider-native skill systems. + +## Detailed Findings + +### 1) Atomic global copy/sync behavior +- Global sync is implemented in `syncAtomicGlobalAgentConfigs(...)`, with template-to-destination mapping and agent-specific exclusions. + - Mapping includes Copilot templates sourced from `.github` and copied to `~/.atomic/.copilot`. + - Source: [`src/utils/atomic-global-config.ts#L18`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L18), [`src/utils/atomic-global-config.ts#L22`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L22), [`src/utils/atomic-global-config.ts#L128`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L128), [`src/utils/atomic-global-config.ts#L139`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L139). +- SCM-managed skills are intentionally excluded from global sync and then pruned if stale. + - Source: [`src/utils/atomic-global-config.ts#L10`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L10), [`src/utils/atomic-global-config.ts#L125`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L125), [`src/utils/atomic-global-config.ts#L146`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L146). +- Sync execution points: + - Postinstall always attempts sync. + - Chat/init call `ensureAtomicGlobalAgentConfigs(...)` only when installation type is not `source`. + - Source: [`src/scripts/postinstall.ts#L32`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/scripts/postinstall.ts#L32), [`src/commands/chat.ts#L217`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L217), [`src/commands/init.ts#L392`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/init.ts#L392), [`src/utils/config-path.ts#L44`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/config-path.ts#L44). + +### 2) Claude sub-agent detection path (SDK-level) +- Claude client loads configured agents during `createSession()` via `loadConfiguredAgents(...)`, which delegates to `loadCopilotAgents(projectRoot)`. + - Source: [`src/sdk/clients/claude.ts#L368`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L368), [`src/sdk/clients/claude.ts#L1822`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L1822), [`src/sdk/clients/claude.ts#L1824`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L1824). +- Loaded agents are merged into `config.agents`, then forwarded into SDK `options.agents`. + - Source: [`src/sdk/clients/claude.ts#L1848`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L1848), [`src/sdk/clients/claude.ts#L600`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L600). +- Agent invocation from slash command path is passed structurally and reaches Claude query options as `options.agent`. + - Source: [`src/ui/commands/agent-commands.ts#L325`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/agent-commands.ts#L325), [`src/sdk/clients/claude.ts#L889`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L889), [`src/sdk/clients/claude.stream-agent-option.test.ts#L45`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.stream-agent-option.test.ts#L45). + +### 3) Claude skill/command detection path differs from Atomic UI discovery +- Claude options include filesystem setting sources `local/project/user` (Claude-native locations). + - Source: [`src/sdk/init.ts#L30`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/init.ts#L30). +- Chat explicitly does not set `CLAUDE_CONFIG_DIR`; instead it only runs a merge utility that writes merged content into `~/.atomic/.claude`. + - Source: [`src/commands/chat.ts#L236`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L236), [`src/commands/chat.ts#L239`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L239), [`src/utils/claude-config.ts#L27`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/claude-config.ts#L27), [`src/utils/claude-config.ts#L61`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/claude-config.ts#L61). +- `CLAUDE_CONFIG_DIR` is not set anywhere in runtime code (only mentioned in comments/docs in code). + - Source: [`src/commands/chat.ts#L236`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L236), [`src/utils/claude-config.ts#L15`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/claude-config.ts#L15). +- Therefore, copied `~/.atomic/.claude` skill/command content is not the direct Claude-native filesystem source unless mirrored through another path; Claude-native source-of-truth remains `.claude`/`~/.claude` for `settingSources`. + +### 4) Atomic UI discovery path for skills/agents is broader than Claude-native path +- Command initialization registers builtins/workflows, then discovers disk skills and disk agent commands. + - Source: [`src/ui/commands/index.ts#L87`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/index.ts#L87), [`src/ui/commands/index.ts#L99`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/index.ts#L99), [`src/ui/commands/index.ts#L103`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/index.ts#L103). +- Skill discovery scans project + user + atomic directories across `.claude`, `.opencode`, `.github`, `~/.copilot`, and `~/.atomic/...` locations. + - Source: [`src/ui/commands/skill-commands.ts#L56`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/skill-commands.ts#L56), [`src/ui/commands/skill-commands.ts#L63`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/skill-commands.ts#L63), [`src/ui/commands/skill-commands.ts#L69`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/skill-commands.ts#L69), [`src/ui/commands/skill-commands.ts#L220`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/skill-commands.ts#L220). +- Skill execution usually injects loaded `SKILL.md` content into conversation with a `` directive and explicitly tells the model not to call the Skill tool for that skill command path. + - Source: [`src/ui/commands/skill-commands.ts#L336`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/skill-commands.ts#L336), [`src/ui/commands/skill-commands.ts#L396`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/skill-commands.ts#L396), [`src/ui/commands/skill-commands.ts#L406`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/skill-commands.ts#L406). +- This creates a split where UI can show/execute skills even when native SDK skill enumeration differs. + +### 5) Custom discovery behavior by SDK integration +- **Claude integration:** custom sub-agents are programmatically injected via `options.agents`; skills are not similarly programmatically injected as directory lists. + - Source: [`src/sdk/types.ts#L162`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/types.ts#L162), [`src/sdk/clients/claude.ts#L600`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L600). +- **OpenCode integration:** runtime prepares merged config dir (`~/.atomic/.opencode` base + user/global + project overlays), and sets `OPENCODE_CONFIG_DIR`. + - Source: [`src/utils/opencode-config.ts#L19`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/opencode-config.ts#L19), [`src/commands/chat.ts#L224`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L224), [`src/commands/chat.ts#L226`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L226). +- **Copilot integration:** manually loads custom agents from local/global/atomic paths and passes `customAgents`; separately builds and passes `skillDirectories` across project/home/atomic. + - Source: [`src/config/copilot-manual.ts#L142`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/config/copilot-manual.ts#L142), [`src/sdk/clients/copilot.ts#L1093`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/copilot.ts#L1093), [`src/sdk/clients/copilot.ts#L1101`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/copilot.ts#L1101), [`src/sdk/clients/copilot.ts#L1163`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/copilot.ts#L1163). + +### 6) Observed filesystem state during this research session +- SCM skills exist in repo-local config trees: + - `.claude/skills/gh-commit/SKILL.md` + - `.opencode/skills/gh-commit/SKILL.md` + - `.github/skills/gh-commit/SKILL.md` +- Corresponding files are absent from `~/.atomic` mirrors: + - `~/.atomic/.claude/skills/gh-commit/SKILL.md` (not found) + - `~/.atomic/.opencode/skills/gh-commit/SKILL.md` (not found) + - `~/.atomic/.copilot/skills/gh-commit/SKILL.md` (not found) +- This matches the managed SCM exclusion/pruning logic in global sync. + +### 7) Config-location mismatch in project guidance vs runtime/docs +- Project guidance documents list Copilot global config as `~/.config/.copilot`. + - Source: [`AGENTS.md#L93`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/AGENTS.md#L93), [`CLAUDE.md#L93`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/CLAUDE.md#L93). +- Runtime code and bundled docs use `~/.copilot` (with XDG override references in docs for default path behavior). + - Source: [`src/config/copilot-manual.ts#L148`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/config/copilot-manual.ts#L148), [`src/utils/mcp-config.ts#L130`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/mcp-config.ts#L130), [`docs/copilot-cli/usage.md#L256`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/docs/copilot-cli/usage.md#L256), [`docs/copilot-cli/skills.md#L16`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/docs/copilot-cli/skills.md#L16). + +## Code References +- [`src/utils/atomic-global-config.ts#L128`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L128) - Main global sync function (`.claude/.opencode/.github` templates to `~/.atomic` destinations). +- [`src/utils/atomic-global-config.ts#L125`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L125) - SCM skills excluded from global sync by design. +- [`src/commands/chat.ts#L217`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L217) - Global sync ensure call is gated to non-source installs. +- [`src/commands/chat.ts#L236`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L236) - Explicitly avoids setting `CLAUDE_CONFIG_DIR`. +- [`src/utils/claude-config.ts#L23`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/claude-config.ts#L23) - Claude merge utility writes merged output into `~/.atomic/.claude` by default. +- [`src/sdk/init.ts#L30`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/init.ts#L30) - Claude `settingSources` are `local/project/user`. +- [`src/sdk/clients/claude.ts#L1824`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L1824) - Loads configured agents per session. +- [`src/sdk/clients/claude.ts#L600`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L600) - Forwards custom agents into Claude SDK options. +- [`src/sdk/clients/claude.ts#L889`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/claude.ts#L889) - Forwards selected sub-agent name as `options.agent`. +- [`src/ui/commands/index.ts#L99`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/index.ts#L99) - UI command registry discovers disk skills. +- [`src/ui/commands/skill-commands.ts#L56`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/skill-commands.ts#L56) - Skill discovery paths include `.claude/.opencode/.github` + user + atomic paths. +- [`src/ui/commands/skill-commands.ts#L336`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/skill-commands.ts#L336) - Skill-loaded directive path used during command execution. +- [`src/ui/commands/agent-commands.ts#L34`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/agent-commands.ts#L34) - Agent discovery paths include project directories. +- [`src/ui/commands/agent-commands.ts#L45`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/ui/commands/agent-commands.ts#L45) - Global/atomic agent discovery paths. +- [`src/config/copilot-manual.ts#L142`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/config/copilot-manual.ts#L142) - Custom agent loader path precedence across atomic/home/project. +- [`src/sdk/clients/copilot.ts#L1101`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/sdk/clients/copilot.ts#L1101) - Copilot skill directory candidates passed to SDK. +- [`src/utils/opencode-config.ts#L41`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/opencode-config.ts#L41) - OpenCode merged config layering from atomic/user/project. +- [`src/utils/mcp-config.ts#L130`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/mcp-config.ts#L130) - Copilot user config location in code is `~/.copilot`. +- [`AGENTS.md#L93`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/AGENTS.md#L93) - Project guidance lists `~/.config/.copilot`. + +## Architecture Documentation +The runtime currently composes configuration/discovery in four layers: + +1. **Template sync layer** + - Copies packaged templates to `~/.atomic` mirrors (with managed SCM skill exclusions). + +2. **Provider-specific runtime prep layer** + - OpenCode: merged config dir and `OPENCODE_CONFIG_DIR`. + - Claude: merge helper updates `~/.atomic/.claude` but runtime remains on `settingSources` (`.claude`/`~/.claude`). + - Copilot: explicit `customAgents` and `skillDirectories` injection. + +3. **UI command-discovery layer** + - Independently discovers and registers skills/agents from project, user, and atomic paths for slash-command UX and capabilities prompt. + +4. **Execution layer** + - Sub-agents: structural dispatch (`options.agent`) for Claude/OpenCode and Task-tool steering for Copilot. + - Skills: often loaded and injected by Atomic command system (``) instead of only relying on native SDK discovery. + +## External Documentation Confirmations +- Claude settings/skill/sub-agent path behavior: + - https://code.claude.com/docs/en/settings#settings-files + - https://code.claude.com/docs/en/skills#where-skills-live + - https://code.claude.com/docs/en/sub-agents#choose-the-subagent-scope +- OpenCode config precedence and config-dir behavior: + - https://opencode.ai/docs/config/#precedence-order + - https://opencode.ai/docs/config/#custom-directory + - https://opencode.ai/docs/skills/#place-files +- Copilot CLI locations: + - https://docs.github.com/en/copilot/how-tos/copilot-cli/set-up-copilot-cli/configure-copilot-cli + - https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/create-custom-agents-for-cli + - https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/create-skills + +## Historical Context (from research/) +- `research/docs/2026-02-25-global-config-sync-mechanism.md` - Documents the same `~/.atomic` sync flow and SCM-skill exclusion behavior. +- `research/docs/2026-02-25-install-postinstall-analysis.md` - Documents postinstall sync lifecycle and validation behavior. +- `research/docs/2026-02-17-legacy-code-removal-skills-migration.md` - Captures migration history from legacy command patterns to SKILL.md-centric behavior. +- `research/docs/2026-02-08-skill-loading-from-configs-and-ui.md` - Historical baseline for disk skill loading and UI-based skill dispatch model. + +## Related Research +- `research/docs/2026-03-02-copilot-sdk-ui-alignment.md` +- `research/docs/2026-02-23-sdk-subagent-api-research.md` +- `research/docs/2026-02-12-sub-agent-sdk-integration-analysis.md` +- `research/docs/2026-01-31-claude-agent-sdk-research.md` +- `research/docs/2026-01-31-opencode-sdk-research.md` +- `research/docs/2026-01-31-github-copilot-sdk-research.md` + +## Open Questions +- The repository guidance (`AGENTS.md`/`CLAUDE.md`) and runtime/docs differ on Copilot global path (`~/.config/.copilot` vs `~/.copilot`); this remains an explicit source-of-truth ambiguity. +- Claude runtime currently avoids `CLAUDE_CONFIG_DIR` while maintaining `~/.atomic/.claude` merges; this keeps a split between atomic mirror state and Claude-native filesystem setting sources. + +## Follow-up Research 2026-03-04 07:59:17 UTC + +### Follow-up Clarification +User clarified that SCM skills are the explicit exception: they are expected to be copied to local project config folders (`.opencode`, `.github`, `.claude`) during `atomic init`, rather than globally mirrored under `~/.atomic`. + +### Verification in Codebase +- Global sync excludes SCM-prefixed skills (`gh-*`, `sl-*`) by design. + - Source: [`src/utils/atomic-global-config.ts#L10`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L10), [`src/utils/atomic-global-config.ts#L125`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L125), [`src/utils/atomic-global-config.ts#L146`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/utils/atomic-global-config.ts#L146). +- `atomic init` copies selected SCM skill variants into project-local config directories and reconciles unselected variants. + - Source: [`src/commands/init.ts#L166`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/init.ts#L166), [`src/commands/init.ts#L181`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/init.ts#L181), [`src/commands/init.ts#L400`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/init.ts#L400), [`src/commands/init.ts#L413`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/init.ts#L413). +- Chat auto-init path also enforces project-local SCM skill setup when missing. + - Source: [`src/commands/chat.ts#L247`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L247), [`src/commands/chat.ts#L251`](https://github.com/flora131/atomic/blob/ec23c76b1c507ce7874eeebaabd7ca42cee01695/src/commands/chat.ts#L251). + +## Follow-up Research 2026-03-04 08:01:25 UTC + +### Follow-up Request +User requested revising the spec wording so the SCM-skill exception is explicit and treated as expected behavior. + +### Revision Applied +- Updated the top-level `## Summary` to state that non-SCM assets are globally mirrored to `~/.atomic`. +- Explicitly marked SCM skills (`gh-*`, `sl-*`) as the only intentional exception, copied to project-local config folders during `atomic init` / chat auto-init. +- Removed SCM exception wording from `## Open Questions` since this behavior is now documented as confirmed design. diff --git a/specs/claude-sdk-discovery-and-atomic-config-sync-alignment.md b/specs/claude-sdk-discovery-and-atomic-config-sync-alignment.md new file mode 100644 index 000000000..61cb2f991 --- /dev/null +++ b/specs/claude-sdk-discovery-and-atomic-config-sync-alignment.md @@ -0,0 +1,330 @@ +# Claude SDK Discovery and Atomic Config Sync Alignment Technical Design Document / RFC + +| Document Metadata | Details | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Author(s) | lavaman131 | +| Status | Draft (WIP) | +| Team / Owner | Atomic CLI | +| Created / Last Updated | Pending review | +| Research Inputs | `research/docs/2026-03-04-claude-sdk-discovery-and-atomic-config-sync.md`, `research/docs/2026-02-25-global-config-sync-mechanism.md`, `research/docs/2026-02-25-install-postinstall-analysis.md`, `research/docs/2026-02-17-legacy-code-removal-skills-migration.md`, `research/docs/2026-02-08-skill-loading-from-configs-and-ui.md`, `research/docs/2026-03-02-copilot-sdk-ui-alignment.md` | + +## 1. Executive Summary + +Atomic currently has a discovery split: global templates are synchronized to `~/.atomic`, UI command discovery scans project/user/atomic locations, and provider runtimes discover assets differently. This is most visible for Claude, where sub-agents are injected programmatically but skills/commands remain tied to Claude-native `settingSources` while runtime intentionally avoids `CLAUDE_CONFIG_DIR` ([R1], [R2]). The result is user-visible inconsistency where skills/agents may appear available in UI but are not aligned with provider-native discovery behavior. + +This RFC proposes a provider-aware discovery contract that explicitly defines what each SDK can discover, how Atomic prepares runtime configuration, and what the UI should surface as runtime-compatible. The design preserves intentional SCM behavior (`gh-*`, `sl-*` remain project-local via init/auto-init), keeps OpenCode and Copilot strengths, and enforces one deterministic path convention: always support `~/.atomic/*` baselines alongside user-global and project-local config roots without introducing user-facing discovery mode toggles ([R1], [R3]). + +Impact: clearer UX, fewer false "not detected" reports, improved cross-provider parity, safer config-path behavior, and better observability for discovery mismatches without changing the SKILL.md ecosystem or removing existing slash-command workflows. + +## 2. Context and Motivation + +### 2.1 Current State + +- **Global Sync Layer:** non-SCM templates are mirrored to `~/.atomic/.claude`, `~/.atomic/.opencode`, and `~/.atomic/.copilot`; SCM-prefixed skills (`gh-*`, `sl-*`) are intentionally excluded and pruned ([R1], [R2], [R3]). +- **SCM Provisioning Layer:** `atomic init` and chat auto-init copy/reconcile SCM variants into project-local config trees (`.claude`, `.opencode`, `.github`) ([R1]). +- **Provider Runtime Layer:** + - Claude loads custom agents into `options.agents` and routes slash-agent dispatch through `options.agent`, but runtime setting sources remain Claude-native (`local/project/user`) and `CLAUDE_CONFIG_DIR` is not set ([R1]). + - OpenCode builds merged runtime config and sets `OPENCODE_CONFIG_DIR` ([R1]). + - Copilot manually injects `customAgents` and `skillDirectories` from project/home/atomic candidates ([R1], [R6]). +- **UI Discovery Layer:** slash command discovery scans broad project + user + atomic paths for both skills and agents, then often executes skills by injecting `SKILL.md` body with `` ([R1], [R5]). + +### 2.2 The Problem + +- **User Impact:** users see skills/agents listed in Atomic UI that do not always map 1:1 to provider-native runtime discovery, especially for Claude sessions ([R1]). +- **Behavior Ambiguity:** equivalent "global config" means different things across SDKs, producing confusion and support/debug overhead. +- **Documentation Drift:** project guidance references Copilot global config as `~/.config/.copilot`, while runtime/docs commonly use `~/.copilot` ([R1]). +- **Environment Drift:** source-install behavior differs from npm/binary install sync lifecycle, which can hide state issues during local development ([R1], [R3]). + +## 3. Goals and Non-Goals + +### 3.1 Functional Goals + +- [ ] Define and implement a provider discovery contract that makes runtime discovery sources explicit for Claude, OpenCode, and Copilot. +- [ ] Align command discovery visibility with runtime-compatible paths per active provider, with clear fallback behavior. +- [ ] Preserve current intentional SCM exception design: `gh-*` / `sl-*` remain project-local and are not globally mirrored. +- [ ] Normalize Copilot global path handling and documentation to eliminate `~/.copilot` vs `~/.config/.copilot` ambiguity. +- [ ] Add discovery observability so mismatches are detectable via logs/metrics, not user reports. +- [ ] Avoid discovery-mode configuration bloat; use deterministic conventions instead of runtime mode flags. + +### 3.2 Non-Goals (Out of Scope) + +- [ ] We will NOT redesign SKILL.md format, frontmatter schema, or the Agent Skills standard. +- [ ] We will NOT remove Atomic's slash skill injection path in this iteration. +- [ ] We will NOT globally mirror SCM-managed skills (`gh-*`, `sl-*`) to `~/.atomic`. +- [ ] We will NOT rewrite provider SDK client architecture beyond discovery/runtime-prep boundaries. +- [ ] We will NOT introduce timeline-based rollout commitments in this document. + +## 4. Proposed Solution (High-Level Design) + +### 4.1 System Architecture Diagram + +```mermaid +flowchart TB + classDef sync fill:#4a90e2,stroke:#357abd,stroke-width:2px,color:#ffffff + classDef runtime fill:#5a67d8,stroke:#4c51bf,stroke-width:2px,color:#ffffff + classDef ui fill:#48bb78,stroke:#38a169,stroke-width:2px,color:#ffffff + classDef data fill:#718096,stroke:#4a5568,stroke-width:2px,color:#ffffff + classDef decision fill:#f6ad55,stroke:#dd6b20,stroke-width:2px,color:#ffffff + + Templates["Bundled Templates\n.claude .opencode .github"]:::data + GlobalSync["syncAtomicGlobalAgentConfigs\n(non-SCM only)"]:::sync + AtomicHome["~/.atomic mirrors\n.claude .opencode .copilot"]:::data + ProjectCfg["Project Config\n.claude .opencode .github"]:::data + UserCfg["User Config\n~/.claude ~/.opencode ~/.copilot\nXDG config roots"]:::data + + DiscoveryContract["Provider Discovery Contract\n(NEW: resolved plan per provider)"]:::decision + ClaudePrep["Claude Runtime Prep\ndeterministic merge"]:::runtime + OpenCodePrep["OpenCode Runtime Prep\nOPENCODE_CONFIG_DIR"]:::runtime + CopilotPrep["Copilot Runtime Prep\ncustomAgents + skillDirectories"]:::runtime + + UIDiscovery["Command Discovery\n(agent/skill registries)"]:::ui + UIFilter["Runtime-Compatibility Filter\n(NEW)"]:::ui + ChatSession["Active Chat Session\nprovider-specific"]:::ui + + Templates --> GlobalSync --> AtomicHome + ProjectCfg --> DiscoveryContract + UserCfg --> DiscoveryContract + AtomicHome --> DiscoveryContract + DiscoveryContract --> ClaudePrep + DiscoveryContract --> OpenCodePrep + DiscoveryContract --> CopilotPrep + DiscoveryContract --> UIDiscovery + UIDiscovery --> UIFilter --> ChatSession + ClaudePrep --> ChatSession + OpenCodePrep --> ChatSession + CopilotPrep --> ChatSession +``` + +### 4.2 Architectural Pattern + +**Capability-Normalized Discovery Contract** + +Atomic will compute a provider-specific discovery plan before session start and command initialization. The plan acts as the source of truth for: + +1. runtime-prep environment behavior (e.g., deterministic `CLAUDE_CONFIG_DIR` and `OPENCODE_CONFIG_DIR` binding), +2. command visibility/compatibility in UI, and +3. observability fields for mismatches. + +This pattern keeps existing sync/discovery primitives but removes implicit assumptions that all providers interpret directories the same way ([R1], [R5], [R6]). + +### 4.3 Key Components + +| Component | Responsibility | Technology Stack | Justification | +| ---------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------ | ------------------------------------------------------------------------------ | +| Provider Discovery Planner (new utility) | Resolve effective discovery sources per provider with deterministic precedence | TypeScript (`src/utils/*`) | Centralizes path precedence and removes duplicated heuristics ([R1]) | +| Claude Runtime Merger | Always build merged Claude runtime rooted in `~/.atomic/.claude` | TypeScript + env prep in `chat` path | Removes split discovery between UI and Claude runtime ([R1]) | +| UI Compatibility Filter | Show runtime-compatible skills/agents for active provider by default | Command registry integration | Reduces "listed but unavailable" confusion ([R1], [R5]) | +| Copilot Path Resolver | Normalize user-global path handling and fallback policy | TypeScript (`src/config/*`, `src/utils/*`) | Fixes path source-of-truth drift (`~/.copilot` vs `~/.config/.copilot`) ([R1]) | +| Discovery Telemetry Hooks | Emit structured events for plan, mismatches, and startup errors | Existing telemetry/event layer | Makes discovery issues debuggable in production-like sessions ([R6]) | + +## 5. Detailed Design + +### 5.1 Internal Interfaces + +Introduce a deterministic path planning contract (no user-facing discovery mode toggles): + +```ts +type Provider = "claude" | "opencode" | "copilot"; + +interface ProviderPathSet { + atomicBaseline: string[]; + userGlobal: string[]; + projectLocal: string[]; +} + +interface ProviderDiscoveryPlan { + provider: Provider; + paths: ProviderPathSet; + mergedRuntimeDir?: string; + runtimeEnv: Record; + runtimeCompatibility: { + compatibleSkillNames: Set; + compatibleAgentNames: Set; + }; + notes: string[]; +} +``` + +Implementation touchpoints: + +- `src/commands/chat.ts` consumes `ProviderDiscoveryPlan` before client start. +- `src/ui/commands/skill-commands.ts` and `src/ui/commands/agent-commands.ts` consume compatibility hints to filter or annotate entries. +- `src/sdk/clients/claude.ts`, `src/sdk/clients/copilot.ts` consume plan-derived runtime env/path settings. + +Research basis: runtime split and broad UI discovery are explicitly documented in [R1]. + +### 5.2 Deterministic Path Convention (No Mode Config) + +Atomic will always support these config roots together, with later layers overriding earlier layers where merging applies. + +| Provider | Atomic Baseline (required) | User Global (supported) | Project Local (supported) | Runtime Binding | +| -------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ----------------------------------------------------------------- | +| Claude | `~/.atomic/.claude` | `~/.claude` | `/.claude` | `CLAUDE_CONFIG_DIR=` | +| OpenCode | `~/.atomic/.opencode` | XDG-guided OpenCode root (`$XDG_CONFIG_HOME/.opencode`, default `~/.config/.opencode`), plus `~/.config/opencode` legacy compatibility and `~/.opencode` | `/.opencode` | `OPENCODE_CONFIG_DIR=` | +| Copilot | `~/.atomic/.copilot` | XDG-guided Copilot root + fallback (`~/.copilot` and `$XDG_CONFIG_HOME/.copilot`), plus `~/.claude`, `~/.opencode` compatibility inputs | `/.github`, `/.claude`, `/.opencode` compatibility inputs | Manual `customAgents` + `skillDirectories` + instructions loading | + +This explicitly satisfies the required convention: `~/.atomic/.opencode`, `~/.atomic/.copilot`, `~/.atomic/.claude` plus existing `~/.opencode`, `$XDG_CONFIG_HOME/.opencode`, `~/.copilot` / `$XDG_CONFIG_HOME/.copilot`, `~/.claude`, `.opencode`, `.github`, and `.claude`. + +### 5.3 Runtime Preparation + +#### 5.3.1 Claude (Deterministic merged runtime) + +- Always construct merged Claude runtime from `~/.atomic/.claude`, then `~/.claude`, then `/.claude`. +- Always set `CLAUDE_CONFIG_DIR` to that merged directory for Claude sessions. +- If merge cannot be prepared, fail session startup with an actionable error (do not silently continue with split discovery behavior). + +#### 5.3.2 OpenCode (Deterministic merged runtime) + +- Keep current merged layering but require it in all install types: + 1. `~/.atomic/.opencode` + 2. XDG-guided OpenCode root (`$XDG_CONFIG_HOME/.opencode`, default `~/.config/.opencode`) + 3. Remove Legacy compatibility root `~/.config/opencode` (covered by XDG-guided root) + 4. `~/.opencode` + 5. `/.opencode` +- Always set `OPENCODE_CONFIG_DIR` to merged output before session start. + +#### 5.3.3 Copilot (Manual injection with XDG-aware roots) + +- Build `customAgents`, `skillDirectories`, and instructions candidates from: + - `~/.atomic/.copilot` baseline, + - XDG-guided canonical Copilot root plus fallback root, + - compatibility roots in `~/.claude` and `~/.opencode`, + - project roots in `.github`, `.claude`, and `.opencode`. +- De-duplicate by normalized path and preserve project-local precedence for conflicting names. + +### 5.4 UI Discovery Compatibility Filtering + +Current UI discovery scans broad directories and can surface entries that runtime may not natively see for a provider ([R1], [R5]). + +Proposed behavior: + +1. Discover all entries as today. +2. Validate definition integrity (required frontmatter fields, parseability, naming constraints). +3. Compute runtime compatibility set from `ProviderDiscoveryPlan`. +4. Register only compatible and well-formed entries; ignore incompatible or malformed definitions. +5. Emit diagnostic events for skipped entries (reason: malformed/incompatible) without polluting slash command registry. + +Compatibility rules (initial): + +- **Claude:** compatible if reachable through the deterministic merged roots (`~/.atomic/.claude`, `~/.claude`, `/.claude`) or via Atomic skill-injection execution policy. +- **OpenCode:** compatible if in merged OpenCode discovery roots or accepted shared paths. +- **Copilot:** compatible if present in `skillDirectories`/`customAgents` plan. + +This policy intentionally does not provide a "show incompatible" registration path. + +### 5.5 Copilot Global Path Normalization + +Resolve path ambiguity by introducing deterministic resolution with compatibility: + +1. Resolve canonical root with XDG guidance: + - if `XDG_CONFIG_HOME` is set: `$XDG_CONFIG_HOME/.copilot` + - otherwise: `~/.copilot` +2. Read the non-canonical root as compatibility fallback. +3. Emit warning when canonical and fallback roots both exist and differ. +4. Align `AGENTS.md` and `CLAUDE.md` with this XDG-guided canonical policy. + +Rationale and conflict are documented in [R1] and Copilot docs references used there. + +### 5.6 Source-Install Sync Behavior + +Atomic will always run global sync ensure for source, npm, and binary installs so `~/.atomic` baselines are deterministic everywhere. + +No discovery sync policy setting is introduced. + +### 5.7 File-Level Change Plan + +| File | Change Type | Planned Change | +| -------------------------------------- | ----------- | ------------------------------------------------------------------------------------ | +| `src/commands/chat.ts` | update | Consume deterministic discovery plan, always bind runtime env, emit discovery events | +| `src/utils/claude-config.ts` | update | Merge atomic+user+project Claude config into deterministic runtime directory | +| `src/utils/opencode-config.ts` | update | Reuse contract-based plan input instead of local ad-hoc path assembly | +| `src/config/copilot-manual.ts` | update | Route global path lookup through shared Copilot path resolver | +| `src/sdk/clients/copilot.ts` | update | Use normalized skill/agent directory plan | +| `src/ui/commands/skill-commands.ts` | update | Add compatibility-aware registration/filtering | +| `src/ui/commands/agent-commands.ts` | update | Add compatibility-aware registration/filtering | +| `src/utils/provider-discovery-plan.ts` | new | Compute provider discovery plan and compatibility sets | +| `src/utils/copilot-paths.ts` | new | Resolve canonical + fallback Copilot config roots | +| `AGENTS.md` / `CLAUDE.md` | update | Align documented Copilot path and discovery contract notes | + +## 6. Alternatives Considered + +| Option | Pros | Cons | Reason for Rejection / Selection | +| ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------------------------------------- | +| Option A: Keep current behavior | No migration risk | Persistent confusion, hidden mismatch bugs | Rejected: does not solve primary problem ([R1]) | +| Option B: Deterministic atomic+user+project convention (Selected) | No mode/config bloat; aligns with required path support; predictable runtime | Requires careful merge ordering and migration validation | **Selected**: directly matches requested behavior | +| Option C: Provider-native-only discovery (drop `~/.atomic` baseline authority) | Simpler mental model per SDK | Fails required `~/.atomic/*` convention and parity goals | Rejected | + +## 7. Cross-Cutting Concerns + +### 7.1 Security and Privacy + +- Restrict discovery to approved directory roots; reject path traversal or symlink escapes outside configured roots. +- Avoid logging full skill contents or sensitive user config values in telemetry; log metadata only (path class, name, source). +- Maintain SCM skill locality policy to prevent globally leaking repo-specific automation assumptions ([R1], [R2]). + +### 7.2 Observability Strategy + +- Add structured events: + - `discovery.plan.generated` + - `discovery.compatibility.filtered` + - `discovery.definition.skipped` + - `discovery.runtime.startup_error` + - `discovery.path.conflict` +- Attach provider, install type, and path-class tags for diagnostics. +- Add debug command output (or log dump) to print active discovery plan for support triage. + +### 7.3 Scalability and Capacity Planning + +- Directory scan costs are bounded by small config trees but still cached per startup/session. +- Reuse existing short-TTL caches where present (e.g., Copilot agent loader) and centralize invalidation strategy. +- Ensure compatibility filtering runs in-memory after discovery to avoid repeated filesystem traversal. + +## 8. Migration, Rollout, and Testing + +### 8.1 Deployment Strategy + +- [ ] Phase 1: Implement deterministic provider path planner and remove install-type sync gating. +- [ ] Phase 2: Wire Claude/OpenCode/Copilot runtime preparation to the unified convention. +- [ ] Phase 3: Enforce strict registration rules (skip malformed/incompatible definitions). +- [ ] Phase 4: Align docs/config guidance and finalize migration validation. + +### 8.2 Data Migration Plan + +- Detect canonical-vs-fallback Copilot config roots under XDG-guided policy and generate a non-destructive reconciliation recommendation. +- If policy requires canonicalization, copy missing files from secondary root to primary root (no destructive delete). +- Keep SCM skill reconciliation unchanged: project-local `init`/auto-init remains authority. + +### 8.3 Test Plan + +- **Unit Tests:** + - Discovery-plan precedence resolution for each provider convention. + - Copilot dual-path conflict detection and deterministic root ordering. + - Claude merged runtime binding and startup error behavior. +- **Integration Tests:** + - `chatCommand` startup applies expected plan for `claude`, `opencode`, `copilot`. + - Skill/agent command registries respect runtime compatibility filter. + - Malformed slash command definitions are skipped and never registered. + - SCM skill exclusion remains intact in global sync + project init paths. +- **End-to-End Tests:** + - Run `bun run src/cli.ts chat -a claude`, `-a opencode`, and `-a copilot` with equivalent config fixtures. + - Validate slash discovery and invocation parity for compatible skills/agents. + - Validate behavior when both `~/.copilot` and `~/.config/.copilot` are present. + - Validate OpenCode path precedence with `$XDG_CONFIG_HOME/.opencode`, `~/.config/opencode`, and `~/.opencode` present together. + +## 9. Open Questions / Unresolved Issues + +- [x] **Q1: Discovery mode config** - Decision: do not add discovery mode settings; use deterministic path conventions that always include `~/.atomic/*` + user + project configs. +- [x] **Q2: Copilot canonical global path** - Decision: follow XDG guidance (`~/.copilot` default; `$XDG_CONFIG_HOME/.copilot` when XDG override is set), with compatibility reads and non-destructive reconciliation across both roots. +- [x] **Q3: Source install sync behavior** - Decision: always ensure sync, including source installs, so `~/.atomic` baseline state is deterministic across development and packaged runtimes. +- [x] **Q4: UI visibility policy** - Decision: strictly ignore and do not register incompatible or malformed slash command definitions. + +No remaining open questions. + +## Appendix A: Research Citations + +- **[R1]** `research/docs/2026-03-04-claude-sdk-discovery-and-atomic-config-sync.md` +- **[R2]** `research/docs/2026-02-25-global-config-sync-mechanism.md` +- **[R3]** `research/docs/2026-02-25-install-postinstall-analysis.md` +- **[R4]** `research/docs/2026-02-17-legacy-code-removal-skills-migration.md` +- **[R5]** `research/docs/2026-02-08-skill-loading-from-configs-and-ui.md` +- **[R6]** `research/docs/2026-03-02-copilot-sdk-ui-alignment.md` diff --git a/src/AGENTS.md b/src/AGENTS.md deleted file mode 120000 index 681311eb9..000000000 --- a/src/AGENTS.md +++ /dev/null @@ -1 +0,0 @@ -CLAUDE.md \ No newline at end of file diff --git a/src/CLAUDE.md b/src/CLAUDE.md deleted file mode 100644 index 510a5e8bb..000000000 --- a/src/CLAUDE.md +++ /dev/null @@ -1,113 +0,0 @@ -# Atomic CLI - -## Overview - -This project is a TUI application built on OpenTUI and powered in the backend by coding agent SDKs: OpenCode SDK, Claude Agent SDK, and Copilot SDK. - -It works out of the box by reading and configuring `.claude`, `.opencode`, `.github` configurations for the Claude Code, OpenCode, and Copilot CLI coding agents and allowing users to build powerful agent workflows defined by TypeScript files. - -## Tech Stack - -- bun.js for the runtime -- TypeScript -- @clack/prompts for CLI prompts -- figlet for ASCII art -- OpenTUI for tui components -- OpenCode SDK -- Claude Agent SDK -- Copilot SDK - -## Quick Reference - -### Commands by Workspace - -Default to using Bun instead of Node.js. - -- Use `bun ` instead of `node ` or `ts-node ` -- Use `bun test` instead of `jest` or `vitest` -- Use `bun lint` to run the linters -- Use `bun typecheck` to run TypeScript type checks -- Use `bun build ` instead of `webpack` or `esbuild` -- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install` -- Use `bun run