Skip to content

Interop Matrix

Gregor Biswanger edited this page Aug 28, 2026 · 3 revisions

Interop Matrix

VS Code Copilot has grown to read most of Claude Code's configuration natively. FeatherSpec leans on that overlap: rules, the constitution, the workflow bodies and the Memory Bank are single files that both tools read. Only genuinely tool-specific things stay separate.

What GitHub Copilot in VS Code reads from .claude/

Artifact Claude Code VS Code Copilot Caveats
AGENTS.md (constitution) via @AGENTS.md import in CLAUDE.md native, chat.useAgentsMdFile (default on) the single source of truth for both
CLAUDE.md native native, chat.useClaudeMdFile (default on) — off here on purpose we point Copilot straight at AGENTS.md, so the one-line import file is redundant for it
.claude/rules/*.md (paths:) native, loads when a matching file is read not read directly — reached through six thin loaders in .github/instructions/ VS Code cannot read instruction files from .claude/rules, whatever the custom instructions page once suggested. Each rule ships a <name>.instructions.md loader whose applyTo: mirrors the rule's paths: globs and whose body is one pointer at the .claude/rules file — the rules stay single-source, the loaders hold none of their own
.claude/commands/<name>.md (workflow body) native, /<name> from the file name; disable-model-invocation: true keeps the description out of context not read directly — reached through the .github/prompts loader below the body is written once and both tools execute the same text
.github/prompts/<name>.prompt.md (loader) — (ignored) native, /<name>; .github/prompts is the default location and the .prompt.md extension is required a prompt file is user-invoked only, never offered to the model; each loader is a link to the body and holds no rules
Web research from inside a workflow native WebSearch (US-only) and WebFetch built-in #fetch for a page, plus the web tool in agent mode /sdd-plan asks for "your web search or fetch capability" rather than naming a tool, and requires the model to say so when none is available instead of guessing
.github/agents/*.agent.md — (kept Copilot-only, see below) native — .github/agents is a default location (chat.agentFilesLocations) a Copilot custom agent is a selectable persona — or, with user-invocable: false, a subagent-only worker like sdd-scout
Subagent delegation (the scan's sdd-scout) native — .claude/agents/sdd-scout.md is a project subagent with its own context window native — .github/agents/sdd-scout.agent.md runs as a subagent; the calling agent needs the agent tool the frontmatter dialects are incompatible (comma-separated tools string vs. YAML array), so the scout ships once per dialect with a byte-identical body; environments that cannot delegate use the scan body's documented sequential fallback
hooks in .claude/settings.json native (with matchers) reads .claude/settings.json, .claude/settings.local.json and ~/.claude/settings.json; parses Claude's format VS Code ignores matcher values — hooks run on all tool invocations, so a shared hook must filter on tool_name in the script

Not shared — stays separate

Artifact Claude Code VS Code Copilot
The slash-command entry point .claude/commands/*.md .github/prompts/*.prompt.md — different folder and extension, so one file cannot serve both; FeatherSpec ships a one-line Copilot loader per command and keeps the body in .claude/commands/
Agent skills (.claude/skills/<name>/SKILL.md) native, /<name> native, .claude/skills is a default location
!`shell` injection, $ARGUMENTS, $0/$1 supported not supported — the documented mechanism is ${input:…} — so the shared bodies use neither
Everything in .claude/settings.json except hooks (autoMemoryEnabled, permissions, …) native no documented support (treat as ignored)
MCP servers .mcp.json, root key mcpServers .vscode/mcp.json, root key servers
Auto memory ~/.claude/projects/<project>/memory/ — shipped off via autoMemoryEnabled: false the copilot-chat extension's local memory tool — shipped off via github.copilot.chat.tools.memory.enabled: false (caveats below)
Output styles, plugins/marketplaces Claude-specific Copilot-specific

The .vscode/settings.json that makes it explicit

Every location above is already a VS Code default, so a fresh clone works untouched. The shipped settings file restates them — and deliberately flips a few — so the setup survives a changed default or a workspace that overrode one:

{
  "chat.useAgentsMdFile": true,
  "chat.useClaudeMdFile": false,
  "chat.instructionsFilesLocations": { ".github/instructions": true, ".claude/rules": false },
  "chat.promptFilesLocations": { ".github/prompts": true },
  "chat.agentFilesLocations": { ".github/agents": true, ".claude/agents": false },
  "github.copilot.chat.tools.memory.enabled": false
}

.claude/rules is explicitly off: VS Code cannot read instruction files from that folder, so the path-scoped rules reach Copilot through the .github/instructions loaders instead — pointing the location at the folder anyway could only surface files in a dialect VS Code does not parse.

github.copilot.chat.tools.memory.enabled: false is the Copilot counterpart to autoMemoryEnabled: false in .claude/settings.json: it disables the copilot-chat extension's local memory tool, which otherwise writes memory files into the extension's storage and auto-injects them into every session. Honest caveat: some bundled builds of the extension lack the setting key entirely, and vscode #318131 (open) reports memory writes despite the setting — treat it as a mitigation, not a guarantee. The actual guard is the constitution's preference-capture rule: a preference claimed by tool memory is proposed and asked about, never silently followed.

.claude/agents is a flip: VS Code also reads Claude-format agent files from that folder, and it now contains the deep scan's scout in Claude dialect — loading it would surface a duplicate scout whose tools string VS Code cannot interpret, i.e. a second scout with an unrestricted tool set. See the asymmetry below.

The SpecDrivenAgent asymmetry

.github/agents/SpecDrivenAgent.agent.md is kept Copilot-only on purpose. VS Code would also read a .claude/agents/ file, but the semantics differ:

  • In Copilot, a custom agent is a persona you pick from a dropdown — it shapes the same conversation you are already in.
  • In Claude Code, a .claude/agents/ file is an isolated subagent with its own context window that does not share your conversation.

Same file location, different meaning. Claude Code has no persona picker, and that is fine: the persona there is AGENTS.md (always loaded via @AGENTS.md) plus /sdd-overview for the greeting and the map.

The deep scan sharpened this asymmetry: its sdd-scout must exist for both tools, so it ships twice with a byte-identical body — .claude/agents/sdd-scout.md (Claude dialect: subagent, comma-separated tools string) and .github/agents/sdd-scout.agent.md (VS Code dialect: YAML tools array plus user-invocable: false, so it never appears in the persona dropdown and is only reachable as a subagent). Both files carry an annotation naming the other; change them together. This pair is why the shipped settings turn .claude/agents off for VS Code.

Sources

VS Code: custom instructions · agent skills · custom agents · hooks · agent tools · settings reference. Claude Code: skills · memory/rules.

Clone this wiki locally