Output of scripts/sync-plugin-content.sh --all against this round's .apm/ source edits. No file here is hand-edited. Carries the agent-author and agent-audit documentation changes into the flat mirrors. No compiled manifest changed: nothing in this round touched apm.yml, so apm pack and sync-marketplace-mirror.sh both produced byte-identical output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01X7GvKuJfy2WrdBmUttV4DT
4.7 KiB
source_keys
| source_keys | ||||||
|---|---|---|---|---|---|---|
|
Agent Deployment Modes
Agent definitions deploy at three scopes and behave differently at each. The scope determines which fields are honoured, where files must live, and what identifiers users invoke.
Scope hierarchy and precedence
| Scope | Claude Code path | Copilot CLI path | Who it affects |
|---|---|---|---|
| User | ~/.claude/agents/ |
~/.copilot/agents/ |
All sessions for this user |
| Project | .claude/agents/ |
.github/agents/ or .copilot/agents/ |
This repo only |
| Plugin/APM | <package-root>/.apm/agents/<name>.agent.md — single vendor-neutral file, apm compile emits it to both targets |
(same file) | Sessions with the plugin/package installed |
When the same agent name appears at multiple scopes, user scope wins over project scope wins over plugin scope in Claude Code. In Copilot CLI, repo-level agents override enterprise and org-level; home-directory (user) agents override repo-level on name collision.
Plugin scope restrictions
Plugin/APM agents (.apm/agents/<name>.agent.md) carry only the fields in the apm-agent-allowlist section of agent-audit's references/field-inventory.md. That section is the authoritative list — agent-audit's validate.sh reads it from there as data, and it changes — so consult it rather than any restatement of it. apm compile copies this frontmatter verbatim to both the Claude Code and Copilot CLI compile targets with no per-target integrator, so a harness-specific value is guaranteed wrong on at least one target (ADR-0016).
The rule is about a field's shape, not a fixed roster. tools is an allowlist whose vocabulary differs per harness — Claude Code names its own tools, Copilot CLI uses aliases (execute/read/edit/search/agent/web) — so under verbatim copy one value is wrong on one target. It stays out. disallowedTools is a denylist, and denying by name has no such conflict: a name the other harness does not recognise denies nothing, so the worst case is that the fence is absent there, never that a capability is wrongly granted. That asymmetry is why the denylist is admitted where the allowlist is not (ADR-0016's 2026-08-14 amendment). Claude Code honours it for plugin subagents — docs/research/docs/claude-code-plugins/agent-definition.md:99 names the three fields plugin agents silently ignore (hooks, mcpServers, permissionMode) and disallowedTools is not among them. It is a partial fence: it denies only the tools it names, not Bash, which a plugin-scope agent with no tools inherits — so state read-only intent in the body too.
This makes the old "silently ignored at plugin scope" framing moot for the excluded fields. It's not that hooks, mcpServers, permissionMode, tools, isolation, maxTurns, effort, memory, skills, color, initialPrompt, or background are merely ignored at this scope — they are never written to the file at all. Copy the agent to .claude/agents/ (project scope) or ~/.claude/agents/ (user scope) to use any of them.
Scoped identifiers (Claude Code plugin agents only)
Plugin agents in subdirectories get compound identifiers:
plugins/my-plugin/.apm/agents/review/security.agent.md → my-plugin:review:security
Users must invoke with @agent-my-plugin:review:security. Keep agents flat in agents/ to avoid this — subdirectory nesting is rarely worth the UX cost.
At project and user scope, subdirectory path does not affect the agent's name.
Cache isolation
When a plugin is installed, its directory is copied to a cache. Any path that leaves the agent's plugin directory breaks post-install. Agent definition files must be self-contained — they cannot reference scripts, templates, or shared files outside the plugin.
Agents at project or user scope are read directly from disk; cache isolation does not apply.
Copilot CLI path conventions
| Scope | Expected path | Notes |
|---|---|---|
| User | ~/.copilot/agents/<name>.agent.md |
Home directory |
| Project | .github/agents/<name>.agent.md |
Standard; also .copilot/agents/ |
| Plugin/APM | <package-root>/.apm/agents/<name>.agent.md |
Not a Copilot-only file — this is the single vendor-neutral source apm compile reads for the Copilot CLI target |
The .agent.md extension is mandatory for real Copilot CLI files (project/user scope) — Copilot CLI does not pick up plain .md files in the agents/ directory. The plugin/APM source file also uses .agent.md by convention, since it compiles to Copilot CLI too, but it is not itself a Copilot file.