|
224 | 224 | "date": "2026-08-26", |
225 | 225 | }, |
226 | 226 | }, |
227 | | -} |
228 | | - |
229 | | -#: Why a specific agent cannot hold a specific part. Without these the generic message |
230 | | -#: ("this format has no place for it") would understate Gemini, which supports MCP servers |
231 | | -#: perfectly well -- just in the manifest rather than in a file of its own. |
232 | | -PART_LIMITS = { |
233 | | - ("codex_cli", MCP): "MCP servers are declared inside .codex-plugin/plugin.json under " |
234 | | - "`mcp_servers`, not in a file of their own", |
235 | | - ("codex_cli", COMMAND): "the manifest reads command paths from a `commands` field, but the " |
236 | | - "command FILE format was not established here -- a guessed format ships a plugin whose " |
237 | | - "commands silently do not load", |
238 | | - ("codex_cli", SUBAGENT): "no subagent field exists in the plugin manifest", |
239 | | - ("codex_cli", EXECUTABLE): "RawPluginManifest's field list is exhaustive (name, version, " |
240 | | - "description, keywords, skills, mcp_servers, apps, hooks, interface) and none names a " |
241 | | - "bundled executable or scripts path; whether an undeclared file elsewhere in the plugin " |
242 | | - "directory survives installation to be referenced by a hook command was not established here", |
243 | | - ("cursor", MCP): "no MCP declaration was established for this plugin format", |
244 | | - ("cursor", COMMAND): "no command format was established for this plugin format", |
245 | | - ("cursor", SUBAGENT): "no subagent format was established for this plugin format", |
246 | | - ("cursor", EXECUTABLE): "no scripts/executable location was established for this closed-source " |
247 | | - "plugin format; the documented layout (.cursor-plugin/, skills/, rules/, mcp.json) names " |
248 | | - "no place for one", |
249 | | - ("gemini_cli", MCP): "MCP servers are declared inside gemini-extension.json, not in a file " |
250 | | - "of their own; a rendered .mcp.json would simply be ignored", |
251 | | - ("vscode_copilot", MCP): "MCP servers are configured by the editor rather than shipped alongside these parts", |
252 | | -} |
253 | | - |
254 | | -#: Folders an agent reads that belong to *another* agent. This is the interop surface: |
255 | | -#: a repository that ships .claude/skills is already shipping skills to VS Code. |
256 | | -ALSO_READS = { |
257 | | - "vscode_copilot": { |
258 | | - SKILL: (SHARED_SKILL_DIR, ".claude/skills", "~/.agents/skills", "~/.copilot/skills", "~/.claude/skills"), |
259 | | - SUBAGENT: (".claude/agents", "~/.copilot/agents", "~/.claude/agents"), |
260 | | - HOOKS: (".claude/settings.json", ".claude/settings.local.json", "~/.claude/settings.json"), |
| 227 | + "copilot": { |
| 228 | + # The Agent Plugins 1.0 MARKETPLACE bundle -- a distinct artifact from vscode_copilot's |
| 229 | + # repo-local .github/hooks/agentseam.json, per the spec: skills and MCP are the |
| 230 | + # standard's own portable component types, found by location; everything else Copilot |
| 231 | + # can hold is client-specific and lives under the com.github.copilot/ namespace inside |
| 232 | + # the bundle. No "declares": both portable and namespaced parts are discovered by |
| 233 | + # location, never resolved from the manifest. |
| 234 | + "unit": "plugin", |
| 235 | + "manifest": "plugin.json", |
| 236 | + "manifest_format": "json", |
| 237 | + # Required and fixed, not bundle-varying: without it a rendered plugin.json is |
| 238 | + # auto-detected as the unrelated Legacy "Copilot" format instead (VS Code's own |
| 239 | + # fallback rule -- see the row's "verified" -- silently mislabeling the whole bundle). |
| 240 | + "manifest_fixed": {"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json"}, |
| 241 | + "project_root": "{bundle}", |
| 242 | + "plugin_root": ("${PLUGIN_ROOT}",), |
| 243 | + "parts": { |
| 244 | + SKILL: "skills/{name}/SKILL.md", |
| 245 | + SUBAGENT: "com.github.copilot/agents/{name}.agent.md", |
| 246 | + COMMAND: None, |
| 247 | + HOOKS: "com.github.copilot/hooks/hooks.json", |
| 248 | + MCP: "mcp.json", |
| 249 | + EXECUTABLE: "scripts/{name}", |
| 250 | + }, |
| 251 | + "notes": ( |
| 252 | + "skills/ and mcp.json are the standard's own portable component types -- " |
| 253 | + "byte-identical skills/{name}/SKILL.md to every other plugin format here -- found " |
| 254 | + "by location like the manifest fields say. Everything else Copilot can hold " |
| 255 | + "(agents, hooks, and slash commands) is client-specific and lives under " |
| 256 | + "com.github.copilot/, which other clients ignore so the bundle stays portable. " |
| 257 | + "scripts/ sits at the bundle root, outside the namespace, exactly as the vendor's " |
| 258 | + "own example places a hook's script -- referenced via ${PLUGIN_ROOT}, the token " |
| 259 | + "this format defines (NOT ${CLAUDE_PLUGIN_ROOT}, which is the Legacy Copilot " |
| 260 | + "format's spelling, alongside ${PLUGIN_ROOT}, per the same vendor table). " |
| 261 | + "See MATRIX['copilot'] for whether these hooks actually run once installed -- " |
| 262 | + "the honesty gate this row exists to pass." |
| 263 | + ), |
| 264 | + "verified": { |
| 265 | + "method": "vendor source read from a clone: microsoft/vscode-docs " |
| 266 | + "docs/agent-customization/agent-plugins.md -- the directory example, the plugin " |
| 267 | + "manifest field table ($schema required), the plugin-format auto-detection rule " |
| 268 | + "(no $schema falls back to the unrelated Legacy Copilot format), and the " |
| 269 | + "plugin-root token table (Agent Plugins 1.0: ${PLUGIN_ROOT} only)", |
| 270 | + "date": "2026-08-29", |
| 271 | + }, |
261 | 272 | }, |
262 | 273 | } |
263 | 274 |
|
264 | | -#: Every agent the matrix knows that has no packaging format recorded here, and why. |
265 | | -#: |
266 | | -#: Exhaustive on purpose, and enforced by a test: recorded plus unrecorded must equal the |
267 | | -#: matrix exactly. A missing agent reads as "nothing to package here" when the truth is |
268 | | -#: "nobody looked", and that is the one thing this module must never say by accident. |
269 | | -#: |
270 | | -#: Several of these are *not* blanks. Where a vendor's own hook documentation proves that |
271 | | -#: skills or subagents exist -- a SubagentStop event, a define_subagent tool, a loader that |
272 | | -#: mentions skills -- that is recorded, because "we could not find the layout" and "there is |
273 | | -#: no such thing" are different answers and only one of them is true. |
274 | | -UNRECORDED = { |
275 | | - "aider": "no packaging format established here", |
276 | | - "antigravity": "subagents provably exist -- define_subagent and invoke_subagent are tools it " |
277 | | - "offers, and its file reader takes an IsSkillFile argument -- but the on-disk layout was " |
278 | | - "not established here", |
279 | | - "devin": "skills provably exist -- its hook loader is documented as following the same " |
280 | | - "discovery rules as skills and rules -- but their layout was not read here", |
281 | | - "grok": "subagents provably exist (SubagentStart and SubagentStop hook events), and it has an " |
282 | | - "extensions system, but neither layout was established here", |
283 | | - "junie": "extensions provably exist and ship hooks at hooks/hooks.json in the Claude " |
284 | | - "plugin layout, with ${JUNIE_EXTENSION_ROOT} aliasing ${CLAUDE_PLUGIN_ROOT} -- but the " |
285 | | - "rest of the extension layout, and how skills and commands sit in it, was not read here", |
286 | | - "kimi_code": "subagents provably exist (a SubagentStop hook event, and a documented agents " |
287 | | - "and sub-agents feature) but their layout was not read here", |
288 | | - "replit": "no packaging format established here", |
289 | | - "tabnine": "no packaging format established here; vendor documentation is unreachable from this environment", |
290 | | - "windsurf": "vendor documentation unreachable from the environment this was written in", |
291 | | - "zed": "no packaging format established here", |
292 | | -} |
| 275 | +#: PART_LIMITS, ALSO_READS, and UNRECORDED moved to packaging_limits.py to keep this module |
| 276 | +#: under the line budget; re-exported here so `from .packaging_data import ...` still works |
| 277 | +#: everywhere it already did. |
| 278 | +from .packaging_limits import ALSO_READS, PART_LIMITS, UNRECORDED # noqa: E402,F401 |
0 commit comments