Files
msd-core/docs/reference/host-integration-capability-matrix.md
Jakub Zych 6cfa0c55d2 refactor: drop 12 runtimes, keep Claude, Codex, OpenCode, Cursor, ZCode, Antigravity
Removes kilo, kimi, kimi-code, copilot, windsurf, augment, trae, qwen, hermes,
cline, codebuddy and pi end to end: capability descriptors, installer branches
and converters (bin/install.js 14.9k -> 11.2k lines), TypeScript converters,
hook surfaces and runtime homes, review lanes qwen/kimi-code, the two pi
migrations, Kimi payload normalization in the hook guards, dead hostBehaviors
vocabulary, launcher home probes, fixtures, runtime-specific tests and the
prose that presented them as supported.

Installer output for the six kept runtimes is byte-identical to before the
prune. The Kimi tool-vocabulary tests in workflow-guard, read-guard and
read-injection-scanner are left in place pending a decision.
2026-10-06 20:02:40 +02:00

52 KiB

Host Integration Capability Matrix

This document is the maintainer-facing source of truth for the hostIntegration block in every capabilities/<cli>/capability.json runtime descriptor. Every per-CLI axis value is either:

  • documented — backed by a cited authoritative source and evidence quote, or
  • undocumented — the explicit fail-closed sentinel used when the CLI's public documentation does not state a value for that axis. undocumented validates in the registry but never propagates into effective axes: negotiation degrades closed to the safe default.

Values are generated from per-CLI documentation research (Context7 + official docs). They are consumed verbatim by gen:capability-registry and validated by capability-validator.cjs.


Axes legend

Axis Meaning
embeddingMode Whether the CLI exposes an in-process programmatic API (imperative) or integrates purely through configuration files (declarative).
commandSurface How slash commands are registered: slash-file (markdown), slash-toml (TOML), slash-programmatic (code API), palette, prose-only.
modelMode Whether extensions can programmatically request or supply a model (active) or select only by config (passive).
hookBus Who owns the hook lifecycle: host (the CLI fires hooks), engine (VS Code/Electron extension host), none.
stateIO Filesystem access model: filesystem (full local FS), sandboxed-storage, session-log-append.
transport Integration transport: mcp (Model Context Protocol), native-extension.
runtime Plugin/extension execution runtime: node, bun, python, go, rust, electron, sandboxed-web, other.
effortSurface How reasoning effort reaches this host: argv (deliverable as an argument on the host's own invocation), none (the host exposes no reasoning-effort mechanism), or undocumented. Added by #2481; there is deliberately no config-file member — the only host that ever had one (Gemini CLI's thinkingConfig) was removed as a sunset runtime, and naming a member with no host would be a guess.

dispatch sub-axes

Sub-axis Meaning
namedDispatch Whether agents can be invoked by name (true/false/undocumented).
nested Whether subagents can themselves spawn subagents (true/false/undocumented).
maxDepth Maximum nesting depth (integer; -1 = unbounded; undocumented).
background Whether subagents can run asynchronously in the background (true/false/undocumented).
subagentToolkit Tool surface available to subagents: full, read-only, built-in-only, or undocumented. built-in-only means the host ships a fixed set of built-in subagent types whose tool surfaces differ from one another, so no single full/read-only value describes them; it degrades closed to read-only in the negotiated axes.
backgroundDispatch Whether a BACKGROUND-dispatched sub-agent can itself spawn further named sub-agents — the #853 discriminator (true/false/undocumented).

Interface points

Point Meaning
command Slash-command routing and invocation capability.
dispatch Subagent/multi-agent dispatch capability.
model Programmatic model selection capability.
hooks Lifecycle hook registration capability.
state Filesystem/state I/O capability.
artifact Artifact delivery (skills, commands) surface capability.

Trigger precedence (#2871 Phase 2 — adjacent to, not part of, hostIntegration)

runtime.triggerPrecedence (an ordered list of trigger-bearing kind names, highest priority first) is declared as a sibling of hostIntegration in capability.json's runtime body, not inside it — it is not researched per-CLI documentation the way the axes above are, so it carries no per-host Source/Evidence row. Only commands and skills are members of the vocabulary; agents are excluded because they are not trigger-bearing (a /msd-<name> a user types) — an agent is invoked through named/subagent_type dispatch, the separate dispatch interface point above, never through the command interface point. Every shipped runtime descriptor declares the same value, ["skills", "commands"] (skills wins a same-scope collision), matching capability-validator.cjs's DEFAULT_TRIGGER_PRECEDENCE — the axis is required-with-default (absence resolves to that default) so a third-party descriptor authored before this phase keeps validating unchanged. runtime-artifact-layout.cts's resolveTriggerSurface reads it to decide the winner among same-trigger candidates once scope rank (Install Scope Module) has already been applied. See CONTEXT.md's Runtime Artifact Layout Module entry and .msd/phase/feat-2871-trigger-resolution/40-design.md.


claude

Axis Value Source Evidence
embeddingMode imperative https://code.claude.com/docs/en/agent-sdk/overview "The Agent SDK offers hooks to execute custom code at critical points within the agent's lifecycle. These callback functions enable developer"
commandSurface slash-file https://code.claude.com/docs/en/agent-sdk/slash-commands "Each custom command is a markdown file where the filename (without the .md extension) becomes the command name. The file content defines w"
modelMode passive https://code.claude.com/docs/en/agent-sdk/typescript "setModel(model?: string): Changes the model (only available in streaming input mode) ... model overrides the default model for this subagent"
hookBus host https://code.claude.com/docs/en/agent-sdk/python "HookEvent = Literal['PreToolUse', 'PostToolUse', 'PostToolUseFailure', 'UserPromptSubmit', 'Stop', 'SubagentStop', 'PreCompact', 'Notificati"
stateIO filesystem https://code.claude.com/docs/en/sandboxing "The sandboxed Bash tool restricts file system access, granting read and write access to the current working directory and session temp direc"
transport mcp https://code.claude.com/docs/en/mcp "Project-Scoped MCP Server Configuration in .mcp.json ... This JSON structure illustrates the format for a project-scoped MCP server configur"
runtime node https://code.claude.com/docs/en/agent-sdk/typescript "import { query } from "@anthropic-ai/claude-agent-sdk"; ... pathToClaudeCodeExecutable (string) - Specifies the path to the Claude Code CLI"
effortSurface argv https://code.claude.com/docs/en/cli-reference ; claude --help --effort <level> is a documented flag on the host's own invocation, so MSD renders the resolved universal effort straight onto the argv it spawns (#2481).
dispatch.namedDispatch true https://code.claude.com/docs/en/agent-sdk/subagents "agents: { 'code-reviewer': AgentDefinition({ description: 'Expert code reviewer.', ... }) } ... subagent_type: block.inp"
dispatch.nested true https://code.claude.com/docs/en/sub-agents "As of Claude Code v2.1.172, a subagent can spawn its own subagents, allowing delegated tasks to split into parallel subt"
dispatch.maxDepth 5 https://code.claude.com/docs/en/sub-agents "foreground subagents can spawn at any depth, blocking their parent until completion. Background subagents are limited to"
dispatch.background true https://code.claude.com/docs/en/sub-agents "Subagents can run in the foreground, blocking the main conversation and passing permission prompts to you, or in the bac"
dispatch.subagentToolkit full https://code.claude.com/docs/en/sub-agents "If all tools remain selected, the subagent inherits all tools available to the main conversation."
dispatch.backgroundDispatch false https://code.claude.com/docs/en/sub-agents "Background subagents are limited to a depth of five and cannot spawn further, "
dispatch.isolation harness-worktree https://code.claude.com/docs/en/sub-agents ; Claude Code Agent tool (Agent(isolation="worktree")) The Claude Code Agent tool accepts an isolation="worktree" harness primitive — the host's own harness creates + binds a git worktree per executor; MSD passes the flag and calls no git itself (#2584)
dispatch.maxConcurrency 20 https://code.claude.com/docs/en/sub-agents The subagent documentation states a default concurrent-subagent limit of 20, configurable via the CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS environment variable (#3673).

Sources consulted:

Cross-scope trigger shadowing and spec-root reachability (#2873, epic #2866 Phase 4, resolving #2218). MSD's claude artifactLayout installs global=[skills] and local=[commands, agents] (see "Trigger precedence" above). Claude Code's own documented precedence — personal overrides project, and a same-named skill overrides a same-named command — means both rules point the same direction when a user installs both scopes: the global skill always wins the /msd-<name> trigger, and the project-local .claude/msd-core/ spec tree the local command correctly points at becomes unreachable through that trigger, silently. MSD Core now (a) detects this at install time and from /msd-health (diagnostic W028) and prints which scope wins — an advisory only, exit code unchanged; and (b) for claude at global scope only, resolves the winning skill's own workflow-spec @-include at runtime rather than pre-expanding it: the skill body carries an explicit imperative instruction that resolves .claude/msd-core/workflows/<name>.md relative to the working directory first, falling back to ~/.claude/msd-core/workflows/<name>.md when no local tree exists. This is instruction-following, not the guaranteed inclusion a real @-include provides — it costs the agent one file read — and is deliberately confined to this one reference, in this one runtime, at this one scope: the skill's references//templates/ includes and the local scope's own emission are unchanged. See Interpret install-shadow warnings and Install on your runtime — Claude Code.


codex

Note: ADR-1239's host matrix lists Codex as prose-only; current OpenAI Codex dev docs document slash-commands, so commandSurface is slash-file here (docs are the source of truth).

Axis Value Source Evidence
embeddingMode declarative https://developers.openai.com/codex/plugins/build "No in-process programmatic API exists. Plugins integrate through: External command execution (hooks), MCP server processes, Configuration fi"
commandSurface slash-file https://github.com/openai/codex/blob/main/codex-rs/core-skills/src/loader.rs "const SKILLS_FILENAME: &str = "SKILL.md"; ... Each skill is a folder with a SKILL.md file containing YAML frontmatter with name and descript"
modelMode passive https://github.com/openai/codex/blob/main/codex-rs/config/src/config_toml.rs "pub model_provider: Option ... model is selected by config field; no programmatic model request API"
hookBus host https://github.com/openai/codex/blob/main/codex/codex-rs/hooks/src/lib.rs "pub const HOOK_EVENT_NAMES: [&str; 10] = ["PreToolUse", "PermissionRequest", "PostToolUse", "PreCompact", "PostCompact", "SessionStart", "Us"
stateIO filesystem https://developers.openai.com/codex/concepts/sandboxing "workspace-write: The default mode allowing Codex to read files, edit within the workspace, and run routine local commands inside that bounda"
transport mcp https://github.com/openai/codex/blob/main/codex-rs/config/src/config_toml.rs "pub mcp_servers: HashMap<String, McpServerConfig> ... Definition for MCP servers that Codex can reach out to for tool calls."
runtime node https://github.com/openai/codex/blob/main/codex-cli/package.json ""engines": {"node": ">=16"} ... The npm-distributed CLI wrapper is a Node.js script (#!/usr/bin/env node)"
effortSurface argv https://github.com/openai/codex/blob/main/codex-rs/exec/src/cli.rs ; https://developers.openai.com/codex/config-reference model_reasoning_effort is a config.toml key and not a dedicated CLI flag, so the generic -c <key>=<value> override is the only argv route — which is still argv, hence argv rather than a config-file member (#2481).
dispatch.namedDispatch true https://github.com/openai/codex/blob/main/codex-rs/core/src/tools/handlers/multi_agents_spec.rs ""agent_type".to_string(), JsonSchema::string(Some(agent_type_description.to_string())) ... apply_role_to_config(&mut con"
dispatch.nested true https://developers.openai.com/codex/multi-agent "agents.max_depth defaults to 1, which allows a direct child agent to spawn but prevents deeper nesting."
dispatch.maxDepth 1 https://developers.openai.com/codex/config-reference "agents.max_depth: Maximum nesting depth allowed for spawned agent threads (root sessions start at depth 0; default: 1)"
dispatch.background true https://github.com/openai/codex/blob/main/codex-rs/core/src/tools/handlers/multi_agents_spec.rs "spawn_agent returns the spawned agent id immediately; a separate wait_agent tool polls for final status."
dispatch.subagentToolkit full https://developers.openai.com/codex/multi-agent "Subagents inherit the sandbox policy and tool surface from the parent session."
dispatch.backgroundDispatch true https://github.com/openai/codex/blob/main/codex-rs/core/templates/collab/experimental_prompt.md "Sub-agents have access to the same set of tools as you do so you must tell them if they are allowed to spawn sub-agents themselves or not." The config (codex-rs/config/src/config_toml.rs) exposes an
dispatch.isolation orchestrator-worktree https://learn.chatgpt.com/docs/environments/git-worktrees ; https://github.com/openai/codex/blob/main/codex-rs/utils/cli/src/shared_options.rs "Worktrees are available only in Codex in the ChatGPT desktop app." (no native CLI worktree) + codex exec --cd <dir> sets an explicit working root, so MSD creates+manages the worktree and points the executor at it (#2584)
dispatch.maxConcurrency undocumented https://developers.openai.com/codex/config-reference agents.max_concurrent_threads_per_session is a documented config key, but the reference states no numeric default — "Codex chooses the default" — so there is no single value to cite (#3673).

MSD integration status — Phase D dogfood complete (#2088, ADR-1239). Codex installs through the declarative embedding adapter (createDeclarativeAdapter → installRuntimeArtifacts); the hardcoded runtime === 'codex'/isCodex projection is folded into descriptor-driven runtime.hostBehaviors, and install/uninstall output is byte-parity-gated at the time (tests/fixtures/golden-install-parity/codex.json; superseded by the differential attribution check, #2724). Three capability upgrades land, each with a test driving the user-reachable surface:

  • Skill root — global skills install to the canonical $HOME/.agents/skills (Codex core-skills loader.rs user-scope root), not the deprecated $CODEX_HOME/skills fallback; local skills install to <project>/.codex/skills. The global path is declared via the global skills-kind home: ".agents" override, while the local kind intentionally has no home override. Pre-move global installs are migrated (stale ~/.codex/skills/msd-* cleaned on both install and uninstall); local installs do not remove $HOME/.agents/skills because those skills may be intentionally global.
  • Hook events (corrected #2586) — MSD registers the SessionStart event only, wired to msd-check-update.js. The SubagentStart/Stop/PostToolUse (#772) + six #2088 extended events (PreToolUse, PermissionRequest, PreCompact, PostCompact, SubagentStop, UserPromptSubmit) described in earlier revisions of this doc were routed through msd-context-monitor.js, which reads a remaining-context-percentage bridge file (${TMPDIR}/claude-ctx-{session_id}.json) that only msd-statusline.js writes — a Claude-only mechanism Codex never installs. Every one of those events was therefore a guaranteed silent no-op on Codex (confirmed: readSentinel throws ENOENT on every invocation, unconditionally). #2586 stops copying/registering msd-context-monitor.js on fresh installs and cleans up a pre-#2586 install's stale registrations + orphaned script on reinstall/uninstall. Agent-facing context warnings and MSD phase/lifecycle display are consequently unsupported on Codex (capabilities/codex/capability.json's hostBehaviors.unsupportedFeatures: ["context-warnings","phase-lifecycle-display"]) — no working warning path existed before this change either, so nothing regresses. Native Codex /statusline configuration remains a separate, out-of-scope surface. (The descriptor extendedHookEvents field's SubagentStop/Stop/PreCompact value is a pre-existing, unrelated drift against the fuller event set bin/install.js used to register — not corrected by #2586.)
  • Dispatch tuning — [agents] max_depth = 1 is written explicitly into the managed config.toml block, pinning the dispatch.maxDepth: 1 axis instead of relying on codex-cli's implicit default. Because maxDepth === 1, degradationFor flattens MSD-hosted wave dispatch to single-level even though dispatch.nested/background/backgroundDispatch are all true. The block is a bare [agents] AgentsToml scalar table; it does not carry per-role [agents.msd-*] sub-tables — those pointed config_file back at the standalone agents/msd-*.toml files Codex already auto-discovers, so emitting them was a duplicate role registration (Codex logged "Ignoring malformed agent role definition: duplicate agent role name" once per agent) removed in #2406. validateCodexConfigSchema permits a known-scalar-only [agents] while still rejecting [[agents]] and unknown-key forms.

Sources consulted:

Documentation gaps:

  • dispatch.maxDepth is configurable (Option with no documented upper bound); the documented default is 1 but the actual enforced maximum is not stated.
  • dispatch.subagentToolkit: docs say subagents 'inherit the tool surface' but do not enumerate whether any tools are excluded.
  • runtime: the Node.js entry point is a thin launcher shim; the actual agent execution runtime is a compiled Rust binary — axis classification is ambiguous.

opencode

Axis Value Source Evidence
embeddingMode imperative https://opencode.ai/docs/plugins "Plugins are JavaScript/TypeScript modules that export plugin functions; they register hooks via `import type { Plugin } from '@opencode-ai/p'"
commandSurface slash-file https://opencode.ai/docs/commands ""Create markdown files in the commands/ directory to define custom commands." and "The markdown file name becomes the command name."
modelMode active /anomalyco/opencode (Context7) — packages/plugin/src/v2/promise/README.md "ctx.aisdk.sdk(async (event) => { ... event.sdk = mod.createXai(event.options) }) and `ctx.aisdk.language((event) => { ... event.language ="
hookBus host https://opencode.ai/docs/plugins "Host fires events including: tool.execute.before, tool.execute.after, session.created, session.compacted, session.deleted"
stateIO filesystem https://opencode.ai/docs/plugins "Plugin context includes directory (working directory path), worktree (git worktree path), and $ ("Bun's shell API")"
transport mcp https://opencode.ai/docs/mcp-servers ""OpenCode supports both local and remote servers." and "Once added, MCP tools are automatically available to the LLM""
runtime bun https://opencode.ai/docs/plugins ""$": Bun's shell API for executing commands" (plugin context property); "OpenCode runs bun install at startup""
effortSurface argv https://opencode.ai/docs/cli ; opencode run --help --variant is accepted on opencode run, so the resolved effort is deliverable as an invocation argument (#2481).
dispatch.namedDispatch true https://opencode.ai/docs/agents ""Subagents can be invoked: Automatically by primary agents for specialized tasks based on their descriptions. Manually b"
dispatch.nested undocumented no authoritative doc — searched: https://opencode.ai/docs/agents —
dispatch.maxDepth undocumented no authoritative doc — searched: https://opencode.ai/docs/agents —
dispatch.background false https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/effect/runtime-flags.ts ; https://github.com/anomalyco/opencode/issues/29638 "experimentalBackgroundSubagents: enabledByExperimental(\"OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS\") — enabledByExperimental falls back to the experimental flag, and bool() defaults to false, so the Task tool's background parameter is hidden from the model unless the operator opts in by env var. #29638 (OPEN) confirms the session loop still tasks.pop()s one subtask at a time. (#2598 — corrects #2087, whose "v1.17 default-on in all modes" reading does not hold against current dev)"
dispatch.subagentToolkit full https://opencode.ai/docs/agents "The 'general' subagent "Has full tool access (except todo), so it can make file changes when needed.""
dispatch.backgroundDispatch false https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/effect/runtime-flags.ts ; https://github.com/anomalyco/opencode/issues/29638 ; https://github.com/anomalyco/opencode/issues/14195 "Concurrent dispatch requires the opt-in OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS flag (default false), so it cannot be relied on. #14195: "the session loop does tasks.pop() to grab a single subtask, awaits it, then continues the loop — so even 3 simultaneous Task calls run sequentially." Declaring true would overstate the capability, against the fail-closed posture negotiation is built for. (#2598 — corrects #2087)"
dispatch.isolation orchestrator-worktree https://opencode.ai/docs/cli ; opencode.ai/docs/plugins ; opencode issues #14195/#29638/#5887 "opencode run --dir <path> sets an explicit working root at the process level" — native subagent dispatch is synchronous-only, so MSD creates + manages the worktree and process-spawns the executor into it via --dir (#2584)
dispatch.maxConcurrency undocumented not researched / no documented concurrent-subagent capacity for this axis no authoritative source consulted for concurrent-executor capacity on this host — fails closed to 1 in negotiation (#3673)

Sources consulted:

Documentation gaps:

  • dispatch.nested
  • dispatch.maxDepth

cursor

Axis Value Source Evidence
embeddingMode imperative https://cursor.com/docs/sdk/typescript "local.customTools where you define tool functions that execute 'in your process, so it can reach anything your code can'; Agent.create()"
commandSurface slash-file https://cursor.com/docs/enterprise/llm-safety-and-controls "Commands are reusable prompts invoked via slash commands (e.g., /test), while workflows enable multi-step processes"
modelMode passive https://cursor.com/docs/sdk/python "The model used for a run can be overridden by passing a ModelSelection object in SendOptions to agent.send()."
hookBus host https://cursor.com/docs/hooks "Agent hooks: sessionStart, sessionEnd, preToolUse, postToolUse, subagentStart, subagentStop, beforeShellExecution, afterShellExecution"
stateIO filesystem https://cursor.com/docs/reference/sandbox "Local agents run with sandbox options disabled by default."
transport mcp https://cursor.com/docs/mcp "The Model Context Protocol (MCP) allows Cursor to connect to external tools and data sources."
runtime node https://cursor.com/docs/sdk/typescript "The SDK runs on Node.js. It requires Node.js 22.13 or later and is described as a Node-first package."
effortSurface undocumented no authoritative doc — per-host reasoning-effort survey, #2481 (09b535ac0) This host's documentation states no reasoning-effort setting, so the axis carries the fail-closed sentinel rather than inheriting a profile baseline. No host-specific URL is cited because the finding is an ABSENCE: #2481 surveyed all hosts for a reasoning-effort mechanism and found one only for claude/opencode/codex.
dispatch.namedDispatch true https://cursor.com/docs/subagents "Invoke specific subagents using slash commands in your prompt. This allows for direct control over which agent performs"
dispatch.nested true https://cursor.com/docs/sdk/typescript "The top-level agent and its direct subagents can launch subagents, but a subagent launched by another subagent can't lau"
dispatch.maxDepth 2 https://cursor.com/docs/sdk/typescript "The top-level agent and its direct subagents can launch subagents, but a subagent launched by another subagent can't lau"
dispatch.background true https://cursor.com/docs/subagents "Background, which returns immediately while the subagent works independently, best for long-running tasks or parallel wo"
dispatch.subagentToolkit full https://cursor.com/docs/subagents "Subagents can utilize MCP tools, inheriting all tools available to their parent agent, including those from configured s"
dispatch.backgroundDispatch true https://cursor.com/docs/subagents (FAQ: Can subagents launch other subagents?) and https://cursor.com/docs/sdk/typescript (Subagents > Nested subagents) FAQ: "As of Cursor 2.5, subagents have the capability to launch child subagents, enabling the creation of a hierarchical structure for coordinated tasks. This nested launching functionality requires T
dispatch.isolation harness-worktree https://cursor.com/docs/cli/reference/parameters ; cursor.com/docs/cli/using ; cursor.com/docs/cli/changelog "-w, --worktree [name] — cursor-agent creates/binds a git worktree per agent (~/.cursor/worktrees/…); native parallel-agent dispatch" (#2584)
dispatch.maxConcurrency undocumented not researched / no documented concurrent-subagent capacity for this axis no authoritative source consulted for concurrent-executor capacity on this host — fails closed to 1 in negotiation (#3673)

Sources consulted:

MSD integration status — Phase D dogfood complete (#2089, ADR-1239). Cursor installs through the imperative embedding adapter (createImperativeAdapter → installRuntimeArtifacts); the hardcoded runtime === 'cursor' / isCursor projection is folded into descriptor-driven runtime.hostBehaviors, and install/uninstall output is byte-parity-gated at the time (tests/fixtures/golden-install-parity/cursor.json; superseded by the differential attribution check, #2724). Two capability upgrades land, each with a test driving the user-reachable surface:

  • Expanded hook-bus coverage — MSD registers all 6 managed lifecycle events in hooks.json beyond the original sessionStart/postToolUse: preToolUse, stop, subagentStart, subagentStop (AC4a, cite https://cursor.com/docs/hooks). The hook-bus binding is descriptor-driven via src/host-integration-adapters/imperative-hook-bus.cts (reads hostBehaviors.managedHookEvents), not a hardcoded event pair.
  • Named/background nested subagent dispatch — dispatch.background/backgroundDispatch/nested are all true with maxDepth: 2; shouldFlattenDispatch(cursor) returns false so MSD's wave-based execution drives Cursor's native background + depth-2 nested subagent dispatch instead of flattening to inline sequential calls (AC4b, cite https://cursor.com/docs/subagents + https://cursor.com/docs/sdk/typescript).

antigravity

Axis Value Source Evidence
embeddingMode declarative https://github.com/alphaperseii3000/google-antigravity-docs/blob/master/google-antigravity-docs.md "Skills require a SKILL.md file; Workflows are saved as markdown files; Rules are manually defined constraints — all configuration-file-based"
commandSurface slash-file https://github.com/alphaperseii3000/google-antigravity-docs/blob/master/google-antigravity-docs.md "Workflows are saved as markdown files, providing a repeatable method for executing key processes. They can be invoked in the Agent using a s"
modelMode passive https://dev.to/arindam_1729/antigravity-cli-a-hands-on-guide-to-googles-terminal-coding-agent-5bc7 "Selection occurs via -m flag or /model command inside the TUI. No programmatic model request API is documented for extensions/skills"
hookBus host https://www.aibuilderclub.com/blog/antigravity-cli-guide "The CLI fires hooks, not the engine. These are JSON lifecycle interceptors (before tool call, after file edit, on session start)."
stateIO filesystem live agy 1.1.17 install probe — https://github.com/open-gsd/gsd-core/issues/3747 "Global skills discovery scans ~/.gemini/config/skills/: a probe skill placed there is visible to agy, while an identical probe skill under the configHome is not. An earlier third-party blog claim about configHome skills placement was disproved by that probe; MSD installs global skills/agents under ~/.gemini/config (#3738)"
transport mcp https://dev.to/arindam_1729/antigravity-cli-a-hands-on-guide-to-googles-terminal-coding-agent-5bc7 "Both local (stdio) and remote (HTTP) Model Context Protocol servers are supported"
runtime go https://developers.googleblog.com/an-important-update-transitioning-gemini-cli-to-antigravity-cli/ "Built in Go, Antigravity CLI is snappier and more responsive."
effortSurface undocumented no authoritative doc — per-host reasoning-effort survey, #2481 (09b535ac0) This host's documentation states no reasoning-effort setting, so the axis carries the fail-closed sentinel rather than inheriting a profile baseline. No host-specific URL is cited because the finding is an ABSENCE: #2481 surveyed all hosts for a reasoning-effort mechanism and found one only for claude/opencode/codex.
dispatch.namedDispatch undocumented no authoritative doc — searched: https://www.aibuilderclub.com/blog/antigravity-cli-guide, https://antigravity.google/docs/agents —
dispatch.nested undocumented no authoritative doc — searched: https://antigravity.google/docs/agents —
dispatch.maxDepth undocumented no authoritative doc — searched: https://antigravity.google/docs/agents —
dispatch.background true https://developers.googleblog.com/an-important-update-transitioning-gemini-cli-to-antigravity-cli/ "Antigravity CLI orchestrates multiple agents for complex tasks in the background"
dispatch.subagentToolkit full https://antigravity.google/docs/cli/features "Capabilities: Subagents have full access to tools such as code search, file editing, terminal commands, and web searches to complete their assigned tasks." (#2096 EoS migration — the page is JS-rendered/blank on a static fetch; confirmed via headless-browser render)
dispatch.backgroundDispatch undocumented no authoritative doc — Multiple sources consulted: antigravity.google/docs/cli-subagents (returned blank/JS-rendered), antigravity.google/docs/agent (blank), github.com/google-antigravity/antigravity-cli README, Context7 /google-antigravity/antigravity-cli All documentation consulted describes a two-level orchestrator→subagent architecture. Background subagents run asynchronously while the main agent continues accepting prompts. The DataCamp tutorial st
dispatch.isolation undocumented not researched / no concurrent fan-out documented for this axis no authoritative source consulted for concurrent-executor isolation on this host — fails closed to none (sequential) in negotiation (#2584)
dispatch.maxConcurrency undocumented not researched / no documented concurrent-subagent capacity for this axis no authoritative source consulted for concurrent-executor capacity on this host — fails closed to 1 in negotiation (#3673)

Sources consulted:

Documentation gaps:

  • dispatch.namedDispatch — docs describe dynamic plain-English goal dispatch where agent names subagents at runtime; no pre-registered named sub-agent API documented.
  • dispatch.nested — no documentation found on whether subagents can themselves spawn further subagents.
  • dispatch.maxDepth — no documented depth limit or explicit unbounded statement found.

EoS migration status (#2096): Migrated onto the declarative adapter. All runtime === 'antigravity' / isAntigravity / canonical === 'antigravity' branches folded into descriptor-driven runtime.hostBehaviors + runtime.hostIntegration: getConfigDirFromHome (bin/install.js) now branches on configHome.kind === 'dot-home-nested' instead of a hardcoded runtime literal; projectLocalHookPrefix (src/shell-command-projection.cts) reads hostBehaviors.hookPathStyle ('raw' → bare dirName, no $CLAUDE_PROJECT_DIR anchor); applyAgentPathRewrites (src/runtime-artifact-conversion.cts) reads hostBehaviors.noPathRewrite to skip the ~/.claude/ → pathPrefix rewrites; and getProjectInstructionFile (src/runtime-name-policy.cts) reads hostBehaviors.projectInstructionFile ("GEMINI.md" — Antigravity CLI's contextFileName, successor to the sunset Gemini CLI per #1928) instead of a hardcoded canonical === 'antigravity' check. The dead isAntigravity branches these functions previously carried are removed. dispatch.subagentToolkit flipped undocumented → full per the citation above (antigravity.google/docs/cli/features); dispatch.namedDispatch/nested/maxDepth/backgroundDispatch stay undocumented — no authoritative source states named/nested/depth-bounded dispatch or a run_in_background-style call-time param, so negotiateHostCapabilities degrades all four closed to their most-restrictive value (false/0), and shouldFlattenDispatch still forces antigravity's dispatch to flatten (inline) despite dispatch.background: true, because backgroundDispatch itself never reaches true. Two upgrades land: UPGRADE 1 — permission-writer (configureAntigravityPermissions, runtime.permissionWriter: "antigravity") writes Antigravity's native {"permissions":{"allow":[...]}} schema (antigravity.google/docs/cli/permissions) into the same settings.json MSD's own hook registration writes, granting MSD's own read_file/command rules non-destructively. UPGRADE 2 — MCP companion config (configureAntigravityMcpConfig) writes a standalone mcp_config.json (antigravity.google/docs/cli/gcli-migration) registering the msd MCP server, non-destructively preserving any other mcpServers entries. Both upgrades are covered by tests/antigravity-upgrades.test.cjs; the axis/negotiation/source-grep coverage above is in tests/declarative-reference-antigravity.test.cjs.


zcode

ZCode (Z.ai) is a desktop Agentic Development Environment for the GLM-5.2 model, distributed as an Electron app. It exposes a Claude-Code-shaped extensibility surface (per-user ~/.zcode/skills/<name>/SKILL.md, slash commands, named subagents, native MCP, and a plugin system). All values below are sourced verbatim from the official ZCode docs.

Axis Value Source Evidence
embeddingMode declarative https://zcode.z.ai/en/docs/plugin "A single plugin can bundle several capabilities. ZCode detects which components a plugin includes from its directory layout" — plugins/skills/commands/agents are config/markdown files; no in-process programmatic extension API is documented.
commandSurface slash-file https://zcode.z.ai/en/docs/commands "Custom commands are stored as .md files under ~/.zcode/commands ... invoke the command with /command-name"
modelMode passive https://zcode.z.ai/en/docs/configuration Models are connected by provider config (Z.ai/BigModel/OpenAI-compat/Anthropic-compat base URLs + API keys in Model Settings); no programmatic model request API is documented.
hookBus host https://zcode.z.ai/en/docs/plugin A plugin's bundled components include a "Hook — Automation hooks triggered on specific events" — the host fires the events a plugin subscribes to.
stateIO filesystem https://zcode.z.ai/en/docs/skill "User-level skills for ZCode Agent: ~/.zcode/skills/<skill-name>/SKILL.md" — full local filesystem (desktop app).
transport mcp https://zcode.z.ai/en/docs/mcp-services "MCP (Model Context Protocol) connects external capabilities ... type as stdio (SSE and HTTP remote servers are also supported)" — native MCP.
runtime electron https://zcode.z.ai/en/docs/install (download path cdn-zcode.z.ai/zcode/electron/releases/3.2.5/ZCode-3.2.5-mac-arm64.dmg) ZCode is shipped as an Electron desktop application; the release artifact lives under the electron/releases path.
effortSurface undocumented no authoritative doc — per-host reasoning-effort survey, #2481 (09b535ac0) This host's documentation states no reasoning-effort setting, so the axis carries the fail-closed sentinel rather than inheriting a profile baseline. No host-specific URL is cited because the finding is an ABSENCE: #2481 surveyed all hosts for a reasoning-effort mechanism and found one only for claude/opencode/codex.
dispatch.namedDispatch true https://zcode.z.ai/en/docs/subagents "you can let the Agent pick the subagent automatically, or reference it with @ in the chat box" — subagents are invoked by name via the Agent tool.
dispatch.nested undocumented searched: https://zcode.z.ai/en/docs/subagents The docs do not state whether a subagent can itself spawn further subagents.
dispatch.maxDepth undocumented searched: https://zcode.z.ai/en/docs/subagents No maximum nesting depth is documented.
dispatch.background false https://zcode.z.ai/en/docs/subagents "Foreground execution. Subagents run in the foreground ... Background execution is not enabled yet."
dispatch.subagentToolkit full https://zcode.z.ai/en/docs/subagents "general-purpose is the default built-in subagent ... It has access to all tools"; custom subagents default to "All permissions by default" (inherits every tool).
dispatch.backgroundDispatch false https://zcode.z.ai/en/docs/subagents "Background execution is not enabled yet" — background dispatch is therefore impossible.
dispatch.isolation none https://zcode.z.ai/en/docs/subagents (shipped descriptor: dispatch.backgroundDispatch: false) "Background execution is not enabled yet" — no concurrent fan-out primitive, so same-wave plans run inline/sequentially (#2584)
dispatch.maxConcurrency undocumented not researched / no documented concurrent-subagent capacity for this axis no authoritative source consulted for concurrent-executor capacity on this host — fails closed to 1 in negotiation (#3673)

Sources consulted:

Documentation gaps:

  • dispatch.nested / dispatch.maxDepth — ZCode's subagent docs do not state whether subagents can spawn further subagents or any depth bound.
  • configHome — skills/commands/agents homes are documented (~/.zcode/skills, ~/.zcode/commands, ~/.zcode/agents); the exact settings filename under ~/.zcode (where MCP server config is stored) is not fully documented at time of writing.
  • Maintenance note — ZCode is a young, fast-moving app (observed at v3.2.x); these axes may need revision as its on-disk config layout stabilizes. Because ZCode also natively imports skills/MCP from ~/.claude, installing MSD to BOTH claude and zcode can surface duplicated skills inside ZCode; this overlap is expected and documented.

EoS migration status (#2101, ADR-1239): ZCode's install is fully dogfooded through the declarative adapter — its shared-hooks exclusion (previously a hardcoded !isZcode branch in bin/install.js) is now folded onto hostBehaviors.skipSharedHooksInstall, byte-parity with the prior install (ZCode's golden install tree has zero hook files). The two capability upgrades anticipated for ZCode both remain blocked on undocumented on-disk formats — hookBus and transport above stay documented-but-unimplemented pending ZCode publishing those formats, and implementing a guessed format risks a false-green descriptor, so neither upgrade is wired:

  • Hook automation (the plugin Hook component, hookBus: host above) — https://zcode.z.ai/en/docs/plugin documents the capability only at a high level ("Automation hooks triggered on specific events"; components are "detected from directory layout, shown as badges"). No config file format, on-disk location, event-name vocabulary, or payload schema is published, so MSD cannot faithfully wire hook events into a plugin bundle. BLOCKED (undocumented on-disk hook-config format).
  • MCP registration (transport: mcp above) — https://zcode.z.ai/en/docs/mcp-services confirms servers are "stored in the .zcode configuration file of the chosen scope" and accepts both a bare {"server-name":{...}} map and an {"mcpServers":{...}} wrapper shape, but does not document the exact settings filename/path or full schema (the docs describe the UI flow, not the on-disk contract) — this is the same gap already noted under configHome above. BLOCKED (undocumented settings-filename/schema gap).

vscode

VS Code is the IDE-profile reference host: a Marketplace/VSIX-distributed extension, NOT file-projected onto a config directory — it has no runtime.localConfigDir in the usual sense (configHome.kind: "none", localConfigDir: null) and no CLI install surface at all (installSurface: "none"; it is never installed by bin/install.js — no --vscode flag, no allRuntimes membership; see capabilities/vscode/capability.json). The extension IS the host. Sourcing note: the citations below are the VS Code extension API documentation pages named in ADR-1239 (#2103) as the source for each axis; this environment did not have live Context7/ web-fetch access at authoring time, so the Evidence column is a paraphrase of VS Code's documented extension model rather than a verbatim excerpt — a maintainer with Context7/web access should verify the exact wording before treating this section as fully cited.

Axis Value Source Evidence
embeddingMode imperative https://code.visualstudio.com/api/references/vscode-api The extension is loaded in-process by the extension host and calls the vscode namespace API directly (vscode.commands.registerCommand, vscode.chat.createChatParticipant, vscode.lm.registerTool) — an in-process programmatic API, not a config-file-only integration.
commandSurface palette https://code.visualstudio.com/api/extension-guides/command Commands are contributed via contributes.commands in package.json and registered with vscode.commands.registerCommand, surfaced through the Command Palette (and the Chat view via the chat participant) — not a markdown/TOML slash-command file format.
modelMode active https://code.visualstudio.com/api/extension-guides/ai/language-model The vscode.lm namespace lets an extension actively select a model (vscode.lm.selectChatModels) and send requests to it programmatically, rather than only reading a static config value.
hookBus engine https://code.visualstudio.com/api/references/activation-events VS Code has no cross-extension lifecycle-hook bus that MSD subscribes to; the extension host (the "engine" here, per this axis's own host/engine/none vocabulary) owns activation events, and MSD's own hook lifecycle runs fully in-process/engine-owned inside the extension.
stateIO sandboxed-storage https://code.visualstudio.com/api/references/vscode-api#Memento context.globalState/context.workspaceState (both Memento) are the extension's persistent storage surface — sandboxed key/value storage scoped to the extension, not unrestricted local filesystem access.
transport mcp https://code.visualstudio.com/api/extension-guides/ai/mcp VS Code 1.99 added native MCP client support; on the Web (webworker) entry, full MSD command dispatch is available through VS Code's native MCP client connecting to the MSD companion MCP server (msd-mcp-server), not an in-process Node dispatch (which the web entry cannot run at all).
runtime sandboxed-web https://code.visualstudio.com/api/extension-guides/web-extensions The browser entry point (vscode/browser.js) runs in a webworker context with no Node core modules — the Web Extension execution model VS Code documents for extensions that must run in vscode.dev/github.dev.
effortSurface undocumented no authoritative doc — per-host reasoning-effort survey, #2481 (09b535ac0) This host's documentation states no reasoning-effort setting, so the axis carries the fail-closed sentinel rather than inheriting a profile baseline. No host-specific URL is cited because the finding is an ABSENCE: #2481 surveyed all hosts for a reasoning-effort mechanism and found one only for claude/opencode/codex.
dispatch.namedDispatch true https://code.visualstudio.com/docs/copilot/chat/chat-agent-mode#_agent-mode-tools Registered languageModelTools (and the chat participant) are addressable by name — the primary agent references a tool/participant by its declared name/toolReferenceName, not only positionally.
dispatch.nested true https://code.visualstudio.com/docs/copilot/copilot-chat-agents (subagents) VS Code's chat subagent model (#runSubagent) explicitly supports a subagent invoking further subagents, gated by chat.subagents.allowInvocationsFromSubagents.
dispatch.maxDepth 5 https://code.visualstudio.com/docs/copilot/copilot-chat-agents (subagents) Documented as VS Code's maximum nesting depth for #runSubagent chains — also matches this repo's existing PROFILE_BASELINES.ide.dispatch.maxDepth baseline.
dispatch.background true https://code.visualstudio.com/api/extension-guides/ai/tools Language Model Tools can be invoked as part of an asynchronous agent turn (the primary agent does not block synchronously on a single extension call).
dispatch.subagentToolkit undocumented no authoritative doc found at authoring time VS Code's subagent documentation does not state whether a subagent's tool surface is restricted to read-only tools or the full set an extension registers; recorded undocumented (fails closed to read-only in negotiation) rather than guessed.
dispatch.backgroundDispatch undocumented no authoritative doc found at authoring time Whether a background-dispatched subagent can itself spawn further NAMED subagents (the #853 discriminator) is not stated in the sources reviewed; recorded undocumented (fails closed to false) rather than guessed.
dispatch.isolation undocumented not researched / no concurrent fan-out documented for this axis no authoritative source consulted for concurrent-executor isolation on this host — fails closed to none (sequential) in negotiation (#2584)
dispatch.maxConcurrency undocumented not researched / no documented concurrent-subagent capacity for this axis no authoritative source consulted for concurrent-executor capacity on this host — fails closed to 1 in negotiation (#3673)

Sources consulted:

Documentation gaps:

  • dispatch.subagentToolkit / dispatch.backgroundDispatch — the reviewed sources document that #runSubagent exists (v1.105+, chat.subagents.allowInvocationsFromSubagents, max nesting depth 5) but do not state the subagent tool-restriction model or whether a background-dispatched subagent can itself spawn further named subagents; both stay undocumented and negotiation fails closed.
  • This section's Evidence-column wording was authored without live Context7/web-fetch access (see the sourcing note above the table) — verify against the cited pages before relying on it for a future capability upgrade.

EoS migration status (#2103): vscode lands as a registry runtime (role:runtime) for validator/host-integration coverage ONLY — it is deliberately NOT a CLI-installable runtime (installSurface: "none", never in bin/install.js's allRuntimes; see the NON_INSTALLABLE_RUNTIMES carve-out in tests/runtime-flags.test.cjs). The extension surface (vscode/extension.js, vscode/browser.js, vscode/host-binding.js, vscode/package.json) is distributed via the Marketplace/VSIX, not npx --vscode — there is no docs/how-to/install-on- your-runtime.md entry for it. Dispatch is SUBPROCESS REUSE on desktop (the same shared dispatchMsdCommand in msd-core/bin/lib/shell-command-projection.cjs the companion MCP server uses) via vscode/extension.js's main entry (Node). The browser entry (vscode/browser.js) is a SEPARATE, independently zero-Node-API file: it does NOT require host-binding.js because that module's engine-lib dependencies (state-io.cjs, adapter-imperative.cjs → install-engine.cjs/capability-loader.cjs, model-adapter.cjs → model-resolver.cjs → config-loader.cjs/configuration.cjs) all pull in Node's fs/os/path at module-load time — requiring any of them from a webworker context would throw immediately. browser.js instead composes its own minimal surface directly against vscode.lm, and its command/tool/chat handlers surface an honest "full dispatch is unavailable on web; configure the MSD MCP server" message rather than a silent failure. The chat participant (@msd) and Language Model Tools (a representative 3-tool set — msd_progress, msd_workstreams, msd_plan_phase — matching real shipped skills that map onto a single, safe, read-only msd-tools.cjs command) are registered on BOTH entries identically; only the dispatch behavior differs. #runSubagent wiring (registerSubagentDispatch/dispatchAsSubagent, gated on chat.subagents.allowInvocationsFromSubagents availability, fail-soft on older/Insiders-gated hosts) adds a belt-and-suspenders maxDepth: 5 ceiling independent of whatever VS Code's own chat engine enforces natively — there is no separate extension-side "subagent contribution" registration API beyond the chat participant + Language Model Tools already registered; VS Code's chat engine surfaces them to #runSubagent on its own.