MCPcopy
hub / github.com/wshobson/agents / CopilotAdapter

Class CopilotAdapter

tools/adapters/copilot.py:67–239  ·  view source on GitHub ↗

Emit Copilot agent profiles and skills (commands mapped to runnable skills). Agents go to ``.copilot/agents/ __ .agent.md``, skills to ``.copilot/skills/ __ /SKILL.md``. Plugin commands are emitted as runnable skills at ``.copilot/skills/ - /SKIL

Source from the content-addressed store, hash-verified

65
66
67class CopilotAdapter(HarnessAdapter):
68 """Emit Copilot agent profiles and skills (commands mapped to runnable skills).
69
70 Agents go to ``.copilot/agents/<plugin>__<agent>.agent.md``, skills to
71 ``.copilot/skills/<plugin>__<skill>/SKILL.md``. Plugin commands are emitted as
72 runnable skills at ``.copilot/skills/<plugin>-<command>/SKILL.md`` with
73 ``user-invocable: true`` and ``disable-model-invocation: true`` so they appear
74 in the VS Code ``/`` menu but are not auto-loaded by the agent.
75 Tool names are rewritten from Claude Code CamelCase to Copilot lowercase.
76 Model aliases are mapped to the GPT-5 family (same as Codex CLI).
77
78 Run ``make install-copilot`` to symlink artifacts to ``~/.copilot/``
79 for user-level discovery.
80 """
81
82 harness_id = "copilot"
83
84 def __init__(self, output_root: Path | None = None, repo_root: Path | None = None) -> None:
85 """Set output root (defaults to WORKTREE) and optional repo root."""
86 super().__init__(output_root=output_root)
87 if repo_root is not None:
88 self.repo_root = repo_root
89
90 def emit_plugin(self, plugin: PluginSource) -> EmitResult:
91 """Emit agent profiles, skills, and command-as-skill files for one plugin."""
92 result = EmitResult()
93 for agent in plugin.agents:
94 self._emit_agent(plugin, agent, result)
95 for skill in plugin.skills:
96 self._emit_skill(plugin, skill, result)
97 for command in plugin.commands:
98 self._emit_command_as_skill(plugin, command, result)
99 # Legacy: also emit as .copilot/commands/ for backward compat
100 self._emit_command_index(plugin, result)
101 for command in plugin.commands:
102 self._emit_command(plugin, command, result)
103 return result
104
105 def emit_global(self, plugins: list[PluginSource]) -> EmitResult:
106 """No cross-plugin artifacts needed for Copilot."""
107 return EmitResult()
108
109 def _emit_agent(self, plugin: PluginSource, agent: AgentSource, result: EmitResult) -> None:
110 """Emit one .agent.md profile into the agents/ directory.
111
112 Builds frontmatter (name, description, model, tools), rewrites tool
113 names, and resolves model aliases before writing.
114 """
115 agent_id = f"{plugin.name}__{agent.name}"
116 rel = Path(".copilot") / "agents" / f"{agent_id}.agent.md"
117
118 model, warning = resolve_model("copilot", agent.model)
119 if warning:
120 result.warnings.append(f"agent `{agent_id}`: {warning}")
121
122 fm: dict = {
123 "name": agent_id,
124 "description": agent.description or f"{agent.name} (from {plugin.name})",

Calls

no outgoing calls