Skip to content

bridge — AgentTeamsModule

Lightweight cross-framework compatibility bridges that preserve source canonical documentation. Unlike convert, which migrates a team into another framework's format, the bridge keeps the source canonical and emits a thin compatibility layer beside it; the CAI transport path is interop. Bridge-merge refreshes fit into the broader update lifecycle guide.

Source: agentteams/bridge.py


Public Types

BridgeResult

Summary of bridge generation or bridge check run.

Fields:

  1. written: written (or would-be-written) paths
  2. skipped: skipped existing paths
  3. errors: error messages
  4. dry_run: whether writes were simulated
  5. check_only: whether run was check mode
  6. check_ok: bridge freshness verdict
  7. check_report_path: report path when check mode runs
  8. manifest_missing (bool): in check mode, True when the bridge manifest file does not exist at the expected path (default False)
  9. notices (list[str]): human-readable per-file notices accumulated during the run — e.g. merge-mode files skipped because they lack an AGENTTEAMS-BRIDGE fence (default empty)

Property:

  • success: True when no errors and check passes (for check mode)

Public Function

run_bridge(*, source_dir, target_framework, output_root, source_framework=None, dry_run=False, overwrite=False, check_only=False, merge_only=False, emit_skills=True, host_features=None, description=None)

When subagent stubs are requested for a team under write_policy: "orchestrator-only" (read from the target's build-log, which fails closed when present but unreadable, or from description), it raises ValueError before any write (interop_write_policy.refuse_bridge_stubs). The stubs copy the source's tools.

Generate bridge artifacts or validate bridge freshness.

Args:

  1. source_dir (Path): canonical source agent directory.
  2. target_framework (str): target runtime framework.
  3. output_root (Path): root where bridge artifacts are written.
  4. source_framework (str | None): optional source override.
  5. dry_run (bool): simulate writes.
  6. overwrite (bool): destructively overwrite existing target-framework entry files at output_root (CLAUDE.md, .claude/agent-team.md, etc.) and existing bridge-internal artifacts. Triggered by --bridge-refresh.
  7. check_only (bool): run freshness check only; no writes.
  8. merge_only (bool): non-destructive update of target-framework entry files. Bridge-internal artifacts under references/bridges/.../ are always regenerated. For target entry files, only content inside <!-- AGENTTEAMS-BRIDGE:BEGIN <region> v=N --> ... <!-- AGENTTEAMS-BRIDGE:END <region> --> fences is re-rendered; content outside fences is preserved verbatim. Files lacking any bridge fence are skipped with notices in bridge-merge.report.md. With the bridge:copilot-vscode-to-claude:subagents host feature, existing non-stub .claude/agents/*.md files (native agent bodies) are kept rather than replaced by stubs. Triggered by --bridge-merge.
  9. emit_skills (bool): emit .claude/skills/recall/SKILL.md and .claude/skills/code-recall/SKILL.md skill templates (claude target only). Default True. Set to False (via --bridge-no-skills) if your team manages skills separately.
  10. host_features (list[str] | None): opt-in subselectors that gate additional emission paths. When None or [], default emission is unchanged. Recognised tokens (claude target):

    • bridge:copilot-vscode-to-claude:subagents — emit per-agent stubs via bridge_subagents.
    • bridge:copilot-vscode-to-claude:hooks — emit hook settings + guard via hooks_emit.
    • bridge:copilot-vscode-to-claude:cache-split — emit cache-aware CLAUDE.md via instructions_split in place of the default pointer file.
    • bridge:copilot-vscode-to-claude:schedule — emit .claude/schedules.agentteams.json via schedule_emit.
    • bridge:copilot-vscode-to-claude:todo-projection — emit .claude/skills/todo-from-plan/SKILL.md (rendered by plan_steps_todo.render_skill).
    • bridge:copilot-vscode-to-claude:parallelize — emit .claude/skills/parallelize-plan/SKILL.md via parallel_plan.render_skill.

    Recognised tokens (goose target; <source> is the detected/declared source framework, e.g. copilot-vscode): - bridge:<source>-to-goose:subagents — emit per-agent Goose recipe stubs via bridge_subagents_goose. - bridge:<source>-to-goose:mcp — wire the source project's declared MCP servers into the .goose/recipes/bridge-orchestrator.yaml recipe.

    Tokens are parsed and validated by host_features. CLI surface: --target-host-features TOKENS.

Returns:

  • BridgeResult

Raises:

  1. FileNotFoundError when source directory is missing.
  2. ValueError for unknown framework ids.

Artifacts

Bridge artifacts are generated in:

  • references/bridges/<source>-to-<target>/

Core files:

  1. bridge-manifest.json
  2. agent-inventory.md
  3. quickstart-snippet.md
  4. entrypoint.md
  5. domain-boundary.md — clarifies the memory-index vector-mode boundary vs project-level retrieval-integrator contracts.

Check mode also emits:

  • bridge-check.report.md

Merge mode also emits:

  • bridge-merge.report.md — per-file status: merged / skipped (no fence) / skipped (no rendered fence).

Claude target with emit_skills=True (default) also emits at output_root:

  • .claude/skills/recall/SKILL.md — wraps agentteams --query-index for in-session retrieval. Not under references/bridges/...; lives in the consumer's .claude/skills/ directory.
  • .claude/skills/code-recall/SKILL.md — wraps agentteams --query-code for in-session code/API index retrieval. Same location convention as recall/SKILL.md.

Goose target emits these fenced entry files at output_root (regions goose-bridge-entry/-hints/-readme):

  • AGENTS.md — repo-root pointer to the source inventory/quickstart. Shared multi-tool file (Cursor/Codex/Cline also read it) — see the warning below.
  • .goosehints — @AGENTS.md integrator so Goose's default context discovery loads the bridged brief.
  • .goose/README.md — bridge note.

Goose target also always emits (bridge-owned; not fence-scoped, regenerated on every run regardless of mode):

  • .goose/recipes/bridge-orchestrator.yaml — Goose recipe stub wiring the developer (CLI) extension and, when the bridge:<source>-to-goose:mcp host-feature token is set, the source project's declared MCP servers.

Goose is supported as both a bridge source and target: any of copilot-vscode/copilot-cli/claude/canonical → goose, and goose → claude/copilot-vscode/copilot-cli. Only goose → goose is rejected (raises ValueError) as meaningless.


Notes

  1. Designed for runtime interoperability without full cross-framework regeneration.
  2. Hash-based freshness checks detect changed, missing, and newly added source files.
  3. Target entry files are emitted to help route users through source orchestrator-first flow.

Operator-Facing Helpers

rel_to_root(path, output_root) -> str

Source: agentteams/bridge.py

Render a path relative to output_root when it lies inside it.

Bridge artifacts are committed, so an absolute path baked into one leaks the operator's home directory and username. 1937cbc fixed this for bridge-manifest.json's source_dir — one field, one file — leaving the sibling artifacts the same run writes still absolute: agent-inventory.md's source-file column and bridge-merge.report.md's per-file lines, across all three pairs. This is the shared form so the three sites cannot drift again.

Returns: str — Relative to output_root, or unchanged when the path lies outside it (a genuinely external path is information, not a leak).

Guarded by tests/test_bridge_mode_safety.py::test_no_committed_bridge_artifact_contains_an_absolute_home_path, which scans every file under references/bridges/ rather than the manifest alone.

skip_notice(count, *, merge_only) -> str

Source: agentteams/bridge.py

Build the notice for target files the bridge left alone. The two cases are opposite in meaning and must not share advice.

Under --bridge-merge a skip is the contract: a target file with no AGENTTEAMS-BRIDGE fence holds user-authored content, and leaving it untouched is the entire reason merge mode exists. This notice previously recommended --bridge-refresh in both cases — advising the operator to overwrite precisely the files that had just been protected, and calling it "recommended when bridge state is incomplete or stale", which is when the advice is most likely to be followed. That is the 2026-05-27 incident recorded in references/bridge-refresh-safety.md, still live in the tool.

Args:

  • count (int) — How many target files were skipped.
  • merge_only (bool, keyword-only) — True under --bridge-merge.

Returns: str — Under merge, explains the skip and warns against refresh; otherwise offers merge first and gates refresh behind the mandatory Pre-Flight reference.

Mode Selection Guidance

Situation Use
First-time bridge generation for a project --bridge-refresh (or --bridge-from with no mode flag, on a project that has no target entry files yet)
Re-running after source agents changed; consumer's CLAUDE.md/.claude/* have been customized --bridge-merge — preserves customization outside the bridge's fenced regions
Re-running with no consumer customization to preserve Either --bridge-refresh or --bridge-merge works; --bridge-merge is the safer default
Verifying source has not drifted from manifest --bridge-check

Warning: --bridge-refresh unconditionally overwrites CLAUDE.md and .claude/* at the consumer's output_root with terse stubs. If your team has rich entry files, use --bridge-merge for refreshes. Consumer-managed sections should live outside the <!-- AGENTTEAMS-BRIDGE:BEGIN ... --> fences so the merge logic preserves them.

Goose target — extra caution: AGENTS.md is a shared, multi-tool standard file read by Cursor, Codex, Cline, and others. The bridge writes it (fenced) on first contact in every mode — including --bridge-merge — when it is absent, and --bridge-refresh overwrites the whole file. An existing unfenced AGENTS.md (another tool's) is safely skipped under --bridge-merge. Always prefer --bridge-merge for Goose and review references/bridge-refresh-safety.md (in the repo) before any --bridge-refresh.

Fence Convention

Target entry files emitted by the bridge contain AGENTTEAMS-BRIDGE fences (distinct from the AGENTTEAMS fences used by the agent-template emit pipeline):

<!-- AGENTTEAMS-BRIDGE:BEGIN <region-id> v=<version> -->
<bridge-managed content>
<!-- AGENTTEAMS-BRIDGE:END <region-id> -->

--bridge-merge updates only the content inside these fences. Place consumer-side notes, project-specific context, or richer documentation OUTSIDE the fences so they survive every merge.