CrewRig

CLI Support Matrix

Reference of every CLI-specific integration point in CrewRig. Update this file in the same PR as any change that adds, removes, or modifies a CLI-specific feature — drift here is a parity bug.

Supported CLIs

CLI Config root Entry point file Notes
Claude Code .claude/ CLAUDE.md (re-exports AGENTS.md) Plugin-based loading. Components must be declared in a marketplace and installed via the CLI.
Gemini CLI .gemini/ .gemini/GEMINI.md (extension form) / GEMINI.md Extension-based loading. Settings live in ~/.gemini/settings.json.
Copilot CLI Split: .github/copilot/ (settings + hooks) + .github/skills/ (skills) + .github/agents/ (agents) .github/copilot-instructions.md (re-exports AGENTS.md) Open Agent Skills standard. No single config root by design — Copilot reads each sibling path independently. @copilot mentions on issues / PRs trigger the coding agent natively.

Feature matrix

One row per integration point. ✅ = present, ❌ = absent, note when relevant.

# Feature / integration point Source of truth Claude Code Gemini CLI Copilot CLI
1 Workspace config root directory repo layout .claude/ .gemini/ ✅ Split: .github/copilot/ + .github/skills/ + .github/agents/
2 Top-level agent-context entry point repo layout CLAUDE.md GEMINI.md (in extensions; absent at repo root) .github/copilot-instructions.md
3 Skill definitions directory (built output) — the build is tier-agnostic (globs artifacts/*/); output is routed by tier (ADR-0011, spec 0019): core → committed project tree (paths shown); every non-core tier (library, community, org) → gitignored staging dist/<tier>/.<cli>/skills/<name>/SKILL.md. The init-expertise and init-team guided skills (spec 0021) are core artifact sources and build to all three CLI skill surfaces through this path. scripts/build-components.sh build_skills + output_root_for_tier core: .claude/skills/<name>/SKILL.md · non-core: dist/<tier>/.claude/skills/<name>/SKILL.md core: .gemini/skills/<name>/SKILL.md · non-core: dist/<tier>/.gemini/skills/<name>/SKILL.md core: .github/skills/<name>/SKILL.md · non-core: dist/<tier>/.github/skills/<name>/SKILL.md
4 Agent definitions directory (built output) — same tier routing as row 3 (core → project tree; non-coredist/<tier>/) scripts/build-components.sh build_agents + output_root_for_tier .claude/agents/<name>/AGENT.md (directory) .gemini/agents/<name>.md (flat file) .github/agents/<name>.md (flat file) [GAP-confirmation] — repo-level layout not in the public reference
4b Agent provenance carrier scripts/build-components.sh build_agents + gemini_provenance_comment ✅ YAML metadata.provenance block inside frontmatter (Claude accepts arbitrary frontmatter keys) ✅ HTML comment <!-- crewrig-provenance: version="…" canonical="…" feedback="…" --> as first line of body — Gemini CLI 0.42.0+ rejects any frontmatter key outside name / description ⚠️ YAML metadata.provenance block inside frontmatter (parallel with Claude — [GAP-confirmation] — public Copilot reference does not document tolerated frontmatter keys; verify and downgrade to HTML comment if rejected)
5 Slash-command directory (built output) scripts/build-components.sh build_commands ✅ Compiled into .claude/skills/<name>/SKILL.md (commands are wrapped as user-invocable skills) .gemini/commands/<name>.toml (native TOML) ✅ Compiled into .github/skills/<name>/SKILL.md (no first-class slash-command file format — [GAP])
6 Settings file in config/ config/ config/claude/settings.json.template config/gemini/settings.json config/copilot/settings.json.template
7 Active workspace settings file .claude/, .gemini/, .github/copilot/ .claude/settings.json ❌ (loaded from ~/.gemini/settings.json by the CLI; no in-repo workspace file) .github/copilot/settings.json
7b User-level layered context (00–65 priority files) config/SOUL.md, config/level/, config/ORGANIZATION.md, config/PROFILE.md, config/expertise/, config/teams/, artifacts/core/rules/60-tools.md (priority 60, core), config/TOOLS.md (priority 65, overlay) ~/.claude/rules/60-tools.md (core) + ~/.claude/rules/65-org-tools.md (overlay), plus other *.md files — deployed by setup-claude-interactive.sh ~/.gemini/60_TOOLS.md (core) + ~/.gemini/65_TOOLS.md (overlay), plus other [0-6][0-9]_*.md files — deployed by setup-gemini-interactive.sh ~/.copilot/instructions/60-tools.instructions.md (core) + ~/.copilot/instructions/65-org-tools.instructions.md (overlay), plus other *.instructions.md files — deployed by setup-copilot-interactive.sh
7c MCP server configuration file config/ ✅ User-managed via claude mcp add / ~/.claude/mcp.json (no repo template — managed per-user by the CLI) config/gemini/settings.json~/.gemini/settings.json (3 servers: GitHub HTTP, MemPalace, SequentialThinking) config/copilot/mcp-config.json.template~/.copilot/mcp-config.json (3 servers: GitHub HTTP, MemPalace, SequentialThinking; deployed by setup-copilot-interactive.sh)
7d MemPalace MCP backend scripts/lib/mempalace-http-wrapper.py + ADR 0006 ✅ MCP entry → <mempalace-python> scripts/lib/mempalace-http-wrapper.pyHttpClient → chroma run (registered by setup-claude-interactive.sh via claude mcp add) ✅ Same wrapper invoked from mcpServers.mempalace in ~/.gemini/settings.json; setup script substitutes __CREWRIG_REPO_DIR__ with the repo root at install time ✅ Same wrapper invoked from mcpServers.mempalace in ~/.copilot/mcp-config.json; setup script substitutes __CREWRIG_REPO_DIR__ with the repo root at install time. Shared ChromaDB HTTP daemon (chroma run) supervised by launchd (macOS) or systemd-user (Linux); replaces concurrent PersistentClient instances (#98)
7e Org-rules extension delivery (AGENTS.org.md) (spec 0020) AGENTS.org.md, AGENTS.md (@ import), scripts/setup-{gemini,copilot}-interactive.sh ✅ Native recursive @AGENTS.org.md import (CLAUDE.md@AGENTS.md@AGENTS.org.md); no setup deployment needed ✅ Fallback: setup-gemini-interactive.sh deploys AGENTS.org.md~/.gemini/66_ORG_RULES.md (priority 66, after 65 org-tools). Gemini resolves @file imports only in GEMINI.md (absent at repo root), so the directive does not resolve — setup copy is the equivalent ✅ Fallback: setup-copilot-interactive.sh deploys AGENTS.org.md~/.copilot/instructions/66-org-rules.instructions.md. Copilot does not resolve @file includes in instruction files and auto-reads only the standard AGENTS.md name. Fallback drift: the deployed copy is taken at setup time; editing AGENTS.org.md requires re-running setup (org rules change rarely; setup is idempotent)
8 Hook-integration manifest hooks/ hooks/claude-transcript-hooks.json (UserPromptSubmit, PostToolUse, Stop, SessionEnd) hooks/gemini-transcript-hooks.json (BeforeAgent, AfterTool, AfterModel, SessionEnd) hooks/copilot-transcript-hooks.json — deployed as opt-in by setup-copilot-interactive.sh to: ~/.copilot/hooks/copilot-transcript-hooks.json (user-level, all projects) and .github/copilot/settings.json (workspace-level, rewritten with absolute path). Committed settings.json has "hooks": [] by design. (SessionStart, UserPromptSubmit, PostToolUse, Stop, SessionEnd)
9 Project-dir env var consumed by hooks hooks/*-transcript-hooks.json $CLAUDE_PROJECT_DIR ${GEMINI_PROJECT_DIR} ❌ No $COPILOT_PROJECT_DIR[GAP]. Workaround: hook reads workspace path from stdin JSON, falls back to $PWD
10 Interactive setup script scripts/ scripts/setup-claude-interactive.sh (offers MemPalace auto-install via pipx; installs built artifacts from dist/<tier>/ to ~/.claude/skills+agentslibrary automatically, community/org per opt-in prompt — ADR-0011, spec 0019) scripts/setup-gemini-interactive.sh (same MemPalace offer; installs from dist/<tier>/ to ~/.gemini/skills+agentslibrary auto, community/org opt-in) scripts/setup-copilot-interactive.sh (same MemPalace offer; installs skills from dist/<tier>/.github/skills/ to ~/.copilot/skillslibrary auto, community/org opt-in; agents skipped, see row 4 [GAP-confirmation])
11 Transcript backfill script scripts/ scripts/import-claude-history.sh (reads ~/.claude/projects) scripts/import-gemini-history.sh (reads ~/.gemini/tmp) scripts/import-copilot-history.sh (reads ~/.copilot/session-state/<session-id>/events.jsonl)
12 Component-management script scripts/ scripts/manage-claude-component.sh (overlay claude-skills source repointed to the per-tier staging root dist/{community,org}/.claude/skills/ — spec 0019) scripts/manage-workspace-component.sh (Gemini target; org tier added as an overlay source fallback alongside community) scripts/manage-copilot-component.sh (skills, agents, commands, mcp-servers; artifacts/org/ added to the skill/agent source search)
13 Plugin / extension build script scripts/ scripts/build-claude-plugin.shdist-claude-plugin/.claude-plugin/marketplace.json ❌ Gemini consumes extensions in-place; no separate build script ❌ No analog — [GAP] by design (same as Gemini); Copilot consumes .github/ in-place
14 Plugin / extension install script scripts/ scripts/install-claude-plugin.sh ❌ (not yet implemented; Gemini auto-discovers extensions) ❌ No analog — [GAP] by design (same as Gemini)
15 Build-components target flag scripts/build-components.sh --target claude --target gemini --target copilot
15b REPO_DIR build-root override scripts/build-components.sh REPO_DIR env var — redirects the inferred repo root to an arbitrary directory (e.g. a temp dir for test isolation); introduced in spec 0018; CLI-agnostic ✅ same ✅ same
16 Taskfile entries Taskfile.yml setup-claude-interactive, install-claude-workspace, link-claude-workspace, install-claude-component, link-claude-component, build-claude-plugin, install-claude-plugin, import-claude-history, build-components-claude setup-gemini-interactive, import-gemini-history, build-components-gemini setup-copilot-interactive, import-copilot-history, build-components-copilot
17 Per-CLI extension manifest extensions/<tier>/<name>/ extension.json (+ CLAUDE.md) gemini-extension.json (+ GEMINI.md) .github/copilot/extension.json (placeholder) + copilot-instructions.md[GAP-soft] (no public per-extension manifest spec)
18 CI workflow targeting the CLI .github/workflows/ claude.yml (anthropics/claude-code-action on @claude mentions) ❌ No gemini.yml equivalent copilot.yml (placeholder — native @copilot mention trigger is set at repo / org level, not via this workflow)
19 Documentation prose references README.md, AGENTS.md, CONTRIBUTING.md, DEVELOPMENT.md ✅ Documented throughout ✅ Documented throughout ✅ Documented throughout
20 .gitignore carve-outs .gitignore dist-claude-plugin/, .claude/settings.local.json, CLAUDE.local.md ❌ No Gemini-specific entries .github/copilot/settings.local.json, copilot-instructions.local.md
21 e2e dedicated-account auth flow scripts/e2e/auth-<cli>.sh, Taskfile.ymle2e:auth:*, ADR 0002 scripts/e2e/auth-claude.sh — interactive claude /login in crewrig/e2e-claude:latest, persists ~/.crewrig-e2e/claude/{.credentials.json,.claude.json} (RW one-shot, RO at scenario time) scripts/e2e/auth-gemini.sh — interactive gemini "Login with Google" in crewrig/e2e-gemini:latest. Persists ~/.crewrig-e2e/gemini/ with oauth_creds.json, settings.json, google_accounts.json, google_account_id, installation_id, gemini-credentials.json, extension_integrity.json, trustedFolders.json, acknowledgments/, history/, projects.json, state.json, etc. — full ~/.gemini minus the antigravity* and tmp/ subtrees and backup leftovers (.bak, .ori, .orig). Bundle dir is chmod 0700. Mounted :ro at /run/gemini-creds; a container-side wrapper copies it to /home/agent/.gemini before exec gemini (see issue #147 §5). ⚠️ scripts/e2e/auth-copilot.shguidance-only, no container. Prints PAT setup steps for the test account; scenarios consume $COPILOT_GITHUB_TOKEN at run time via docker run -e. Nothing persisted under ~/.crewrig-e2e/copilot/. [GAP-soft] — empirically justified divergence (see Parity gaps). The e2e runner (#78) consumes this asymmetry first-class via mounts = [] in tests/e2e/defaults.toml [cli.copilot], so no CLI-branching is needed in tests/e2e/run.sh. When local.toml routes Copilot through Ollama Cloud, task e2e:auth:ollama persists an Ed25519 keypair under ~/.crewrig-e2e/ollama/ that is mounted RO into the copilot container (see ADR 0002 Decision 8).
22 e2e pillar 01 — layered context tests/e2e/scenarios/01-layered-context/, ADR 0005 ✅ host-orchestrated probe via claude -p; mounts ${CREWRIG_E2E_HOME}/claude ro; structural + LLM-judge assertions ✅ host-orchestrated probe via gemini -p; dual :ro mounts — ${CREWRIG_E2E_HOME}/gemini at /run/gemini-creds (auth bundle) and ${HOME}/.gemini at /run/gemini-rules (layered-context rules, [0-6]0_*.md only); container-side bootstrap copies both into /home/agent/.gemini before exec gemini (see issue #148 Decision 5 Revision 2) ✅ host-orchestrated probe via copilot -p; mounts ${CREWRIG_E2E_HOME}/copilot ro (auth-copilot.sh currently writes nothing here — scenario soft-skips if the dir is absent)
23 e2e pillar 02 — cross-tool memory tests/e2e/scenarios/02-cross-tool-memory/, ADR 0005 ✅ MemPalace sidecar (per-run volume); drawer write + read across two short-lived containers ✅ same path [GAP-soft]crewrig/e2e-copilot:latest (docker/e2e/copilot.Dockerfile) does not embed the mempalace CLI, and Copilot CLI ships no MemPalace MCP integration in artifacts/community/. Empirical reproduction: docker run --rm crewrig/e2e-copilot:latest which mempalace → exit 1 (binary absent). Scenario excluded via applies_to = ["claude","gemini"] until the Copilot image gains a MemPalace surface.
24 e2e pillar 03 — skill build tests/e2e/scenarios/03-skill-build/, ADR 0005 ✅ runs scripts/build-components.sh --target claude inside the container; asserts .claude/ populated + first SKILL.md has metadata: frontmatter ✅ same with --target gemini.gemini/ ✅ same with --target copilot.github/
25 e2e pillar 04 — harness loop tests/e2e/scenarios/04-harness-loop/, ADR 0005 ✅ simulated path (drawer write to wing=harness-friction + curator-style search); MemPalace sidecar; LLM-judge on the friction summary ✅ same simulated path ✅ same simulated path. [GAP-soft] — full interactive harness-report skill invocation is not yet driven non-interactively from any CLI; the simulation matches what the curator reads and is parity-equivalent for v1.

Parity gaps

The following features exist for one CLI but not the other. Each gap is a candidate follow-up issue. Do not fix them in this ticket.

  • [GAP] CI workflow — present for Claude Code (.github/workflows/claude.yml), missing for Gemini CLI.
  • [GAP] Plugin/extension build script — present for Claude Code (scripts/build-claude-plugin.sh), missing for Gemini CLI (extensions are consumed in place, but no symmetric packaging path exists).
  • [GAP] Plugin/extension install script — present for Claude Code (scripts/install-claude-plugin.sh), missing for Gemini CLI.
  • [GAP] In-repo workspace settings file — present for Claude Code (.claude/settings.json), missing for Gemini CLI (settings live only in ~/.gemini/settings.json).
  • [GAP] .gitignore carve-outs — Claude-specific entries (dist-claude-plugin/, .claude/settings.local.json, CLAUDE.local.md) have no Gemini equivalents (e.g., a .gemini/settings.local.json analog).
  • [GAP] Top-level entry point file — CLAUDE.md lives at the repo root; GEMINI.md only appears inside extensions (no repo-root GEMINI.md).
  • [GAP] Slash commands — Copilot CLI has no user-definable slash-command file format. CrewRig commands compile as user-invocable skills under .github/skills/ (same workaround Claude uses). Same trade-off, documented and accepted.
  • [GAP] Project-dir env var — Copilot does not export a $COPILOT_PROJECT_DIR. hooks/mempalace-transcript.sh extracts the workspace path from the hook stdin JSON payload and falls back to $PWD.
  • [GAP-confirmation] Repo-level Copilot agent layout — the public Copilot reference only documents the user-level ~/.copilot/agents/ directory. CrewRig adopts .github/agents/<name>.md by parallelism with the skills layout; implementers must verify loading behavior and downgrade to a hard [GAP] if the path is rejected.
  • [GAP] Plugin / extension build & install — same status as Gemini. Copilot consumes .github/ artifacts in place; no analog to scripts/build-claude-plugin.sh / scripts/install-claude-plugin.sh exists.
  • [GAP-confirmation] Copilot agent provenance carrier — CrewRig currently emits the same metadata.provenance YAML block in .github/agents/<name>.md that it emits for Claude. Copilot CLI's tolerance for non-standard frontmatter keys is undocumented; if Copilot rejects the block (as Gemini CLI 0.42.0 did, see issue #54), migrate Copilot agents to the same HTML-comment carrier used by Gemini. Follow-up ticket to be filed.
  • [GAP-soft] Per-extension Copilot manifest — no public spec for a repo-level Copilot extension manifest. CrewRig ships .github/copilot/extension.json as a placeholder convention; revisit when GitHub publishes a spec.
  • [GAP-soft] e2e pillar 02 (cross-tool memory) for Copilot CLI — the crewrig/e2e-copilot:latest image does not embed the mempalace CLI (docker/e2e/copilot.Dockerfile installs only Node, gh, and @github/copilot; verified via docker run --rm crewrig/e2e-copilot:latest which mempalace → exit 1) and no MemPalace MCP wiring ships in artifacts/community/ for Copilot. The scenario excludes Copilot via applies_to = ["claude","gemini"] in tests/e2e/defaults.toml. Re-evaluate when either the Copilot image gains the mempalace binary or a MemPalace MCP integration appears for Copilot.
  • [GAP-soft] e2e pillar 04 (harness loop) full interactive leg — the scenario currently uses the simulated path (direct drawer write to wing=harness-friction, curator-style search) for all three CLIs. The fully interactive path that drives the harness-report skill end-to-end through the CLI's slash-command surface is not yet supported non-interactively from any CLI. The simulated path is parity-equivalent for v1: it writes the same drawer shape the skill would write and the curator reads the same lane regardless of the writer's identity.
  • [GAP-soft] e2e auth flow for Copilot CLI — auth-claude.sh and auth-gemini.sh persist on-disk OAuth credentials under ~/.crewrig-e2e/<cli>/; auth-copilot.sh is guidance-only and relies on an env-var PAT ($COPILOT_GITHUB_TOKEN) at scenario time. Empirical evidence supporting the divergence is captured in docs/adr/0002-e2e-auth-flow.md Decision 4: the crewrig/e2e-copilot:latest image lacks libsecret (verified via ldconfig -p | grep libsecret → empty), so the upstream desktop-keychain path is unavailable; the documented plaintext-fallback works but adds login-flow friction without scenario-coverage gain in v1. The env-var precedence chain (COPILOT_GITHUB_TOKEN > GITHUB_TOKEN > GH_TOKEN > gh CLI > GITHUB_ASKPASS > OAuth device flow) makes the PAT path strictly simpler. Re-evaluate when the scenario runner (#78) or pillar scenarios (#80) prove the need for an interactive on-disk credential.

Adding a new CLI

Every checklist item below is governed by the Symmetric-script rule and Gap-acceptance evidence rule in AGENTS.mdCLI Matrix Maintenance. Unchecking an item requires the evidence the gap rule demands; it is not a free-form choice.

Use this checklist when onboarding a new CLI. Each item maps to a row in the feature matrix above — leaving one unchecked produces a parity gap.

  1. [ ] Create the workspace config root (./.<cli>/).
  2. [ ] Add a top-level agent-context entry point that re-exports AGENTS.md (analogous to CLAUDE.md).
  3. [ ] Extend scripts/build-components.sh with a --target <cli> branch and emit skills via the tier-routed output root (output_root_for_tier): core.<cli>/skills/<name>/SKILL.md in the project tree; non-coredist/<tier>/.<cli>/skills/<name>/SKILL.md (or the native form). The build is tier-agnostic — do not hardcode tier names.
  4. [ ] Extend build_agents in the same script to emit agents in the CLI's native layout.
  5. [ ] Extend build_commands in the same script to emit commands in the CLI's native form.
  6. [ ] Add a per-CLI settings template under config/<cli>/.
  7. [ ] Decide whether a checked-in workspace settings file at .<cli>/settings.json is required, and add it if so.
  8. [ ] Provide a hook-integration manifest under hooks/<cli>-transcript-hooks.json covering the CLI's lifecycle events.
  9. [ ] Document the CLI's project-dir env var convention and wire hooks/mempalace-transcript.sh to read it.
  10. [ ] Add an interactive setup script scripts/setup-<cli>-interactive.sh, including the artifact-install phase that reads dist/<tier>/ and routes by tier scope: library auto-installed to the user home, community/org each behind an opt-in prompt (ADR-0011, spec 0019). core is never installed here — it ships in the project tree.
  11. [ ] Add a transcript backfill script scripts/import-<cli>-history.sh.
  12. [ ] Add or extend a component-management script for the CLI.
  13. [ ] If the CLI requires a build step before install, add scripts/build-<cli>-plugin.sh (or equivalent).
  14. [ ] If a separate install step is required, add scripts/install-<cli>-plugin.sh.
  15. [ ] Register --target <cli> invocations in Taskfile.yml, plus setup-, import-, install-, link-, and build-components- task entries.
  16. [ ] Add a per-CLI extension manifest convention to extension-skeleton/ and update extensions/core/hello-world/ with an example.
  17. [ ] Add a CI workflow .github/workflows/<cli>.yml if the CLI offers an automation entry point.
  18. [ ] Update prose references in README.md, AGENTS.md, CONTRIBUTING.md, and DEVELOPMENT.md.
  19. [ ] Add .gitignore carve-outs for the CLI's local settings and any generated dist-<cli>-* directories.
  20. [ ] Append a new column to this matrix and re-check every row.