
Synapse A2a
- 372 installs
- 10 repo stars
- Updated July 21, 2026
- s-hiraoku/synapse-a2a
synapse-a2a is a Claude Code skill that teaches Google A2A Protocol workflows for synapse CLI so developers who run multiple coding agents can send messages, spawn workers, and lock files safely.
About
synapse-a2a is the companion skill for Synapse A2A, a framework that connects CLI coding agents through Google's A2A Protocol without modifying Claude Code, Codex, Gemini, OpenCode, or GitHub Copilot CLIs. The skill catalogs commands such as synapse send, synapse spawn with --task-file, synapse team start, synapse memory, synapse wiki, and synapse file-safety for coordinating multi-agent work on one repository. It explains spawn flags per runtime, prefers JSON outputs like synapse list --json for automation, and covers worktree discipline when subagents inherit shell state. Developers reach for synapse-a2a when delegating fixes to Codex from Claude Code, broadcasting status across agents, or orchestrating three-plus phase tasks that need specialists, file locks, and regression-tested handoffs instead of a single monolithic agent session. Install via gh skill install s-hiraoku/synapse-a2a synapse-a2a --agent claude-code or npx skills add when you need agents to understand delegation, interrupts, and broadcast messaging primitives.
- synapse-a2a
- Claude Code
- Enhanced workflow
Synapse A2a by the numbers
- 372 all-time installs (skills.sh)
- +2 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,118 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Jul 30, 2026 (Skillselion catalog sync)
npx skills add https://github.com/s-hiraoku/synapse-a2a --skill synapse-a2aAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 372 |
|---|---|
| repo stars | ★ 10 |
| Last updated | July 21, 2026 |
| Repository | s-hiraoku/synapse-a2a ↗ |
How do CLI coding agents coordinate safely?
Support build phase development with Claude Code
Who is it for?
Developers running Claude Code alongside Codex, Copilot, or Gemini CLIs who need structured multi-agent messaging, spawning, and file-lock coordination on one repo.
Skip if: Developers completing a small single-file edit in one agent session who do not need cross-agent orchestration overhead or A2A messaging infrastructure.
When should I use this skill?
The user runs or asks about synapse send, synapse spawn, synapse file-safety, multi-agent delegation, or Google A2A Protocol coordination between CLI agents.
What you get
Spawned agent processes, A2A message threads, file-safety locks, shared memory entries, and JSON status from synapse list or synapse status.
- agent spawn commands
- A2A message workflows
- file lock policies
By the numbers
- Built on Google A2A Protocol for inter-agent messaging and task delegation
- Documents synapse spawn, send, file-safety, memory, and wiki CLI commands
- Supports Claude Code, Codex, Copilot, Gemini, and OpenCode agent runtimes
Files
Synapse A2A Communication
Inter-agent communication framework via Google A2A Protocol.
Worktree Discipline (subagents, read this first)
NEVER `cd` into `.synapse/worktrees/<name>/` directories.
>
Subagents (Claude Code Agent tool, Codex subprocess, and any other
sub-process driven by the parent session) inherit a persistent shell
from the parent. A stray cd into a worktree leaks out of the subagentturn and silently corrupts the parent's working directory — git status,git diff, and evengit committhen land on the wrong worktree, which
wastes debugging time and can put commits on the wrong branch.
>
Rules for working with .synapse/worktrees/:>
- Do not cd into a worktree, ever. Stay in the original workingdirectory for the entire session.
- Read and write files inside a worktree using absolute paths only
(for example Read /Volumes/.../.synapse/worktrees/foo/src/bar.py, not cd .synapse/worktrees/foo && cat src/bar.py).- Rungitagainst a worktree withgit -C /abs/path/to/worktree ...
instead of changing directory.
- Worktrees are managed by Synapse (synapse spawn --worktree, synapse team start --worktree). Treat them as read/write datasurfaces, not as places to live.
>
If you need to operate from inside a worktree (e.g. running pytestthere), spawn a dedicated agent for it with synapse spawn --worktreerather than changing the parent shell's directory.
Quick Reference
| Task | Command |
|---|---|
| List agents | synapse list for humans (auto-refresh, interactive: arrows/1-9 select, Enter jump, k kill, / filter). For AI/scripts use synapse list --json, synapse list --plain, or MCP list_agents |
| Agent detail | synapse status <target> [--json] |
| Stuck-agent watchdog (Stage 1) | synapse watchdog check [--alarm-only] [--json] (one-shot heuristic scan; #646) |
| Send message | synapse send <target> "<msg>" (default: --notify; --from auto-detected) |
| Broadcast | synapse broadcast "<msg>" |
| Wait for reply | synapse send <target> "<msg>" --wait |
| Fire-and-forget | synapse send <target> "<msg>" --silent |
| Reply | synapse reply "<response>" |
| Reply to specific | synapse reply "<response>" --to <sender_id> |
| Reply with failure | synapse reply --fail "<reason>" |
| Interrupt (priority 4) | synapse interrupt <target> "<msg>" |
| Send keys to PTY (escape hatch for TUI dialogs; #695) | synapse send-keys <target> <keys> (e.g. a for codex "don't ask again", \r for Enter; bypasses A2A — use when an agent is stuck on an interactive dialog without synapse jump) |
| Spawn agent | synapse spawn <type> --name <n> --role "<r>" -- <tool-specific-automation-args> |
| Spawn + send first task (preferred for delegation) | synapse spawn <type> --name <n> --role "<r>" --task-file <path> --task-timeout 600 --notify |
| Spawn with worktree | synapse spawn <type> --worktree --name <n> --role "<r>" -- <tool-specific-automation-args> |
| Team start | synapse team start <homogeneous-profiles...> [--worktree] -- <tool-specific-automation-args> |
| Approve plan | synapse approve <id> |
| Reject plan | synapse reject <id> --reason "<feedback>" |
| Save knowledge | synapse memory save <key> "<content>" --tags <t> --notify |
| Search knowledge | synapse memory search "<query>" |
| Lock file | synapse file-safety lock <file> <agent_id> --intent "..." |
| Check locks | synapse file-safety locks |
| Task history | synapse history list --agent <name> |
| Kill agent | synapse kill <name> -f |
| Cleanup orphans | synapse cleanup --dry-run (list); synapse cleanup -f (kill all orphans whose parent crashed/cleared) |
| Attach files | synapse send <target> "<msg>" --attach <file> --wait |
| Saved agents | synapse agents list / synapse agents set <profile> / synapse agents unset <profile> / synapse agents roles / synapse spawn <agent_id>; live agents expose agent_definition_id as a stable target alias |
| Shared session handoff | synapse session publish <name> / synapse session import <name> using SYNAPSE_SHARED_SESSION_DIR |
| Post to Canvas | synapse canvas post <format> "<body>" --title "<title>" |
| Link preview | synapse canvas link "<url>" --title "<title>" |
| Post template | synapse canvas briefing '<json>' --title "<title>" |
| Post plan card | synapse canvas plan '<json>' --title "<title>" (Mermaid DAG + step list with status tracking) |
| Open Canvas | synapse canvas open (auto-starts server, opens browser) |
| Restart Canvas | synapse canvas restart (stop + start; use when canvas status reports ⚠ STALE after upgrade) |
| Sync workflow skills | synapse workflow sync (regenerate skills from workflow YAMLs, remove orphans) |
| Run workflow (auto-spawn) | synapse workflow run <name> --auto-spawn (supports DAG steps with depends_on and condition) |
| Multi-agent patterns | synapse map init/list/show/run/status/stop (built-in: generator-verifier, orchestrator-subagent, agent-teams, message-bus, shared-state) |
| Wiki ingest | `synapse wiki ingest <source> [--scope project\ |
| Wiki query | `synapse wiki query "<question>" [--scope project\ |
| Wiki lint | `synapse wiki lint [--scope project\ |
| Wiki status | `synapse wiki status [--scope project\ |
Collaboration Decision Framework
Evaluate collaboration opportunities before starting work:
| Situation | Action |
|---|---|
| Small task within your role | Do it yourself |
| Task outside your role, READY agent exists | Delegate: synapse send --notify or --silent |
| No suitable agent exists, need to delegate a task | Spawn + task in one command: synapse spawn <type> --name <n> --role "<r>" --task-file <spec.md> --task-timeout 600 --notify. This spawns, waits for READY, and sends the first task — no manual readiness polling needed. |
| Need a bare agent (no initial task) | synapse spawn <type> --name <n> --role "<r>" (send tasks later via synapse send) |
| Stuck or need expertise | Ask: synapse send <target> "<question>" --wait |
| Completed a milestone | Report: synapse send <manager> "<summary>" --silent |
| Discovered a pattern | Share: synapse memory save <key> "<pattern>" --tags ... --notify |
Recommended Collaboration Gate (3+ phases OR 10+ file changes): Consider these steps before diving into large work: 1. synapse list --json or MCP list_agents — check available agents 2. synapse memory search "<topic>" — check if someone already solved this 3. Build Agent Assignment Plan (Phase / Agent / Rationale) when delegation is beneficial 4. Spawn specialists if needed (prefer different model types for diversity)
Skip this gate for small/medium tasks where the overhead exceeds the benefit.
Use Synapse Features Actively
| Feature | Why It Matters | Commands |
|---|---|---|
| Shared Memory | Collective knowledge survives agent restarts | synapse memory save/search/list |
| File Safety | Locking prevents data loss when two agents edit the same file -- skip inside worktrees (SYNAPSE_WORKTREE_PATH) | synapse file-safety lock/unlock/locks |
| Worktree | File isolation eliminates merge conflicts in parallel editing | synapse spawn --worktree |
| Broadcast | Team-wide announcements reach all agents instantly | synapse broadcast "<msg>" |
| History | Audit trail tracks what happened and when | synapse history list/show/stats |
| Probabilistic Recall | Recall relevant past task observations by recency, importance, and keyword overlap without dumping all history | HistoryManager.recall_observations |
| Plan Approval | Gated execution ensures quality before action | synapse approve/reject |
| Canvas | Visual dashboard for sharing rich cards and templates (briefing, comparison, dashboard, steps, slides, plan); cards downloadable as Markdown, JSON, CSV, or native format via browser button or GET /api/cards/{card_id}/download | synapse canvas post/link/briefing/plan/open/list/restart |
| Agent Control | Browser-based agent management via Canvas #/admin view (select agents, send messages, view responses, double-click agent row to jump to terminal) | synapse canvas open → navigate to #/admin |
| Workflow View | Browser-based workflow management via Canvas #/workflow view (list workflows, inspect steps, create/edit/delete/import/export workflow YAML, trigger runs, monitor progress with live SSE updates; run history persisted to SQLite across restarts) | synapse canvas open → navigate to #/workflow |
| Harnesses View | Browser-based browser for agent harness resources at Canvas #/harnesses — sub-views #/harnesses/skills (SKILL.md inventory across user/project/synapse/plugin scopes, scanned per active project root) and #/harnesses/mcp (MCP server configs from project .mcp.json per active root, plus user-scope: Claude Code ~/.claude.json, Codex ~/.codex/config.toml, Gemini ~/.gemini/settings.json, OpenCode ~/.config/opencode/opencode.json, and Claude Desktop config) | synapse canvas open → navigate to #/harnesses |
| Plan Cards | Mermaid DAG + step list with dependency visualization | synapse canvas plan |
| LLM Wiki | Structured knowledge base for ingesting, querying, and validating project/global docs | synapse wiki ingest/query/lint/status |
| Smart Suggest | MCP tool that analyzes prompts and suggests team/task splits for large work | MCP tool: analyze_task |
| Project Learnings | Saved definitions can load project-adaptive learnings from .synapse/learnings/<agent_definition_id>.md on startup | synapse agents set + Markdown learnings |
| Proactive Mode | Task-size-based feature usage guide (SYNAPSE_PROACTIVE_MODE_ENABLED=true) | See references/features.md |
| MCP Bootstrap | Distribute instructions via MCP resources for compatible clients (opt-in, including Copilot via tools-only). MCP tools: bootstrap_agent, list_agents, analyze_task, canvas_post | synapse mcp serve / python -m synapse.mcp |
When to Use Canvas
Use Canvas when the output benefits from visual structure or will be referenced later:
- Use Canvas for: diagrams, comparison tables, multi-step plans, design docs, results with rich formatting
- Skip Canvas for: simple completion reports, single-file changes, quick status updates (use broadcast or reply instead)
Template selection guide:
briefing— structured reports, status updates, release summariescomparison— before/after, option trade-offs, review diffssteps— plans, migration sequences, execution checklistsslides— walkthroughs, demos, page-by-page narrativesdashboard— multi-widget operational snapshots, compact status boardsplan— task DAGs with Mermaid visualization and step tracking
Use raw synapse canvas post <format> for single blocks; templates for multi-section content.
Spawning Decision Table
⚠️ Same-model rule — try subagents first. When a Claude Code agent needs
another claude (or a codex agent needs another codex), use the in-process
subagent (Agent/Tasktool for Claude, subprocess for Codex) before
reaching for synapse spawn. Spawning the same model on the same accountshares the rate-limit window — it doubles consumption against the same quota
instead of distributing it. Reserve same-model synapse spawn for caseswhere the helper must outlive the parent session, needs file isolation that
subagents can't provide, or holds a distinct long-running role.
>
synapse spawn is the right tool for cross-model delegation(Claude → codex / gemini), agents that lack subagent support
(Gemini / OpenCode / Copilot), or persistent multi-task helpers.
Default spawn policy: When using synapse spawn, pass the underlying CLI's tool-specific automation args after -- so spawned agents can run unattended. For most CLIs this is an approval-skip / auto-approve flag; for OpenCode use --agent build to select the build agent profile and rely on OpenCode's permission config for approval behavior.
Apply the same rule to synapse team start: include the appropriate forwarded CLI args by default, and keep teams homogeneous when those args are CLI-specific.
Common defaults (Synapse already injects these automatically — pass --no-auto-approve to opt out):
- Claude Code:
synapse spawn claude --name <n> --role "<r>" -- --permission-mode=auto - Gemini CLI:
synapse spawn gemini --name <n> --role "<r>" -- --approval-mode=yolo - Codex CLI:
synapse spawn codex --name <n> --role "<r>"(synapse injects-cdefault_permissions=":workspace"; Codex 0.128+ removed--full-auto) - OpenCode:
synapse spawn opencode --name <n> --role "<r>" -- --agent build(selects the build agent profile; not a skip-approval flag) - Copilot CLI:
synapse spawn copilot --name <n> --role "<r>" -- --allow-all - Claude team:
synapse team start claude claude -- --permission-mode=auto - Gemini team:
synapse team start gemini gemini -- --approval-mode=yolo - Codex team:
synapse team start codex codex(synapse injects-cdefault_permissions=":workspace") - OpenCode team:
synapse team start opencode opencode -- --agent build(selects the build agent profile; permission prompts still depend on OpenCode config) - Copilot team:
synapse team start copilot copilot -- --allow-all
2026-04 migration: Anthropic deprecated --dangerously-skip-permissionsin favor of --permission-mode=auto (safety classifier instead of disablingall checks). Gemini similarly recommends --approval-mode=yolo over thelegacy--yolo/-yshort forms. Synapse now injects the new flags by
default; the legacy forms still work and remain in each profile's
alternative_flags.| Condition | Action |
|---|---|
| Existing READY agent can handle it | synapse send — reuse is faster (avoids startup overhead) |
| Same-model helper needed (Claude → claude, Codex → codex) | Use the in-process subagent first (Agent/Task tool for Claude, subprocess for Codex). synapse spawn same-model shares the rate-limit window. |
| Need parallel execution | synapse spawn with --worktree -- <tool-specific-automation-args> for file isolation (cross-model preferred) |
| Task needs a different model's strengths | synapse spawn a different type (Claude spawns Gemini / Codex, etc.) |
| User specified agent count | Follow exactly |
| Single focused subtask | Subagent (same model) or synapse spawn (cross model) |
| N independent subtasks | Subagents for same-model fan-out, synapse spawn for cross-model |
Spawn lifecycle (preferred, one-command): synapse spawn --task-file ... --task-timeout 600 --notify → wait for A2A completion notification → evaluate result → synapse kill <name> -f → confirm in synapse list --json
Legacy lifecycle (only when you need control between spawn and first task): spawn → poll synapse list --json or synapse status <target> --json for READY (allow several minutes; default 30s timeout is too short for most profiles) → synapse send --notify → evaluate → synapse kill -f → confirm cleanup.
⚠️ Common pitfall: sending to an agent that is not yet READY either hangs at the HTTP layer or blocks on the internal readiness wait. Either usesynapse spawn --task-file(preferred — it handles readiness for you), or explicitly confirm"status": "READY"before callingsynapse send. Do not assume 30 seconds is enough — most profiles take 1-5 minutes.
Agent status set (synapse list --json .status):
| Status | Meaning | Action |
|---|---|---|
READY | Idle, can accept new work | synapse send |
SENDING_REPLY | Temporarily sending an outbound A2A send/reply POST | Wait; previous status is restored after the POST finishes |
PROCESSING | Actively working a task | Wait, or synapse interrupt if stuck |
WAITING | Awaiting a permission/approval prompt | synapse approve / synapse reject |
WAITING_FOR_INPUT | Task is paused asking for non-permission input (#538) | synapse reply <task_id> with the answer |
RATE_LIMITED | Last task failed due to LLM provider rate limit (#561) | Wait for the provider window to reset, then re-send |
DONE | Task complete; demotes to READY after ~10s | Read result, then proceed |
SHUTTING_DOWN | Agent is exiting | Do not send |
Stuck on a CLI dialog (not A2A `WAITING`)? When an agent looks idle but is
blocked on its own TUI prompt (codex edit-confirmation, model picker,
rate-limit dialog), use synapse send-keys <target> <keys> to write directlyto the PTY withoutsynapse jump. Example:synapse send-keys Impl asends
the codex "don't ask again" shortcut. (#695)
Killing spawned agents after completion frees ports, memory, and PTY sessions, and prevents orphaned agents from accidentally accepting future tasks.
# Preferred: one-command spawn + delegate (handles readiness wait internally)
synapse spawn gemini \
--name Tester \
--role "test writer" \
--task-file /tmp/test-spec.md \
--task-timeout 600 \
--notify
# (do other work; receive async A2A notification when Tester finishes)
# Evaluate result, then cleanup
synapse kill Tester -f
synapse list --json # Verify cleanup (AI-safe)If synapse kill fails or the agent still appears in synapse list --json, retry with -f, check the agent status/logs, and report the cleanup failure instead of leaving an orphaned agent behind.
Response Mode Guide
Choose based on whether you need the result:
| Mode | Flag | Use When |
|---|---|---|
| Wait | --wait | You need the answer before continuing (questions, reviews) |
| Notify | --notify (default) | Async — you'll be notified on completion |
| Silent | --silent | Fire-and-forget delegation (no response needed; sender history still updates best-effort on completion) |
Worker Agent Guide
When you receive a task from a manager:
On Task Receipt
1. Start work immediately (synapse reply is valid for Synapse-tracked messages with a registered reply target, including [REPLY EXPECTED] and --response; otherwise user-pasted A2A: text has no reply target, so respond with synapse send instead) 2. Check shared knowledge: synapse memory search "<task topic>" 3. Lock files before editing (skip if SYNAPSE_WORKTREE_PATH is set): synapse file-safety lock <file> $SYNAPSE_AGENT_ID
During Work
- Report progress if task takes >5 minutes:
synapse send <manager> "Progress: <update>" --silent - Report blockers immediately:
synapse send <manager> "<question>" --wait - Save findings:
synapse memory save <key> "<finding>" --tags <topic> - You can delegate subtasks too — spawn helpers (prefer different model types)
- Always clean up agents you spawn:
synapse kill <name> -f
On Completion
1. Report to manager: synapse send <manager> "Done: <summary>" --silent
On Failure
1. Report details: synapse send <manager> "Failed: <error details>" --silent
Related Skills
| Skill | Purpose |
|---|---|
synapse-manager | Multi-agent orchestration workflow (delegation, monitoring, verification) |
synapse-reinst | Re-inject instructions after /clear or context reset |
References
For detailed information, consult these reference files:
| Reference | Contents |
|---|---|
references/commands.md | Full CLI command documentation with all options |
references/api.md | A2A endpoints, readiness gate, error handling |
references/examples.md | Multi-agent workflow examples and patterns |
references/file-safety.md | File locking workflow and commands |
references/messaging.md | Sending, replying, priorities, status states, interactive controls |
references/spawning.md | Spawn lifecycle, patterns, worktree, permissions, API |
references/collaboration.md | Agent naming, external agents, auth, resume, path overrides |
references/features.md | Sessions, workflows, saved agents, tokens, skills, settings, Canvas |
A2A Protocol Reference
This document provides technical details for developers and advanced users. For normal agent communication, use `synapse send` and `synapse reply` commands.
Message Format
Receiving Messages
Messages arrive with a simple A2A: prefix:
A2A: <message content>Replying to Messages
Use synapse reply to respond:
synapse reply "<your response>"
synapse reply --fail "<reason>"
synapse reply --list-targets
synapse reply "<your response>" --to <sender_id>The framework automatically handles routing - you don't need to know where the message came from.
API Endpoints
A2A Compliant
| Endpoint | Method | Description |
|---|---|---|
/.well-known/agent.json | GET | Agent Card |
/tasks/send | POST | Send message (subject to Readiness Gate) |
/tasks/{id} | GET | Get task status |
/tasks | GET | List tasks |
/tasks/{id}/cancel | POST | Cancel task (Synapse extends with mode/repeat query params — see "Task Cancel Interrupt Modes" below) |
/status | GET | READY/PROCESSING status |
Synapse Extensions
| Endpoint | Method | Description |
|---|---|---|
/tasks/send-priority | POST | Send with priority (1-5, 5=interrupt; subject to Readiness Gate) |
/tasks/create | POST | Create task without PTY send (for --wait) |
/tasks/{id}/reply | POST | Record an explicit reply on the receiver's local task before routing it back to the sender |
/history/update | POST | Update sender-side history observation (completion callback) |
/reply-stack/list | GET | List sender IDs available for reply (synapse reply --list-targets) |
/reply-stack/get | GET | Get sender info without removing (supports ?sender_id=) |
/reply-stack/pop | GET | Pop sender info from reply map (supports ?sender_id=) |
Task Cancel Interrupt Modes
POST /tasks/{task_id}/cancel cancels a submitted or working task and interrupts the agent process. It accepts optional query parameters:
| Parameter | Values | Default | Description |
|---|---|---|---|
mode | auto, pty, signal | auto | auto uses the active profile's interrupt.default_mode; pty injects Ctrl+C bytes into the PTY; signal sends the legacy process SIGINT. |
repeat | integer >= 1 | 1 | Number of Ctrl+C injections when mode=pty; ignored by mode=signal. When mode=auto, the profile's interrupt.pty_repeat overrides this value. |
Invalid mode values return HTTP 400. Profiles can declare interrupt.default_mode, interrupt.pty_repeat, and interrupt.graceful_supported; older controllers without profile interrupt config fall back to signal.
Completion Callback (--silent Flow)
When --silent is used, the sender does not wait for a reply. However, the receiver still notifies the sender when the task completes (or fails) by calling POST /history/update on the sender's server. This updates the sender's history record from sent to the final status.
1. Sender calls /tasks/send on the target agent with response_mode: "silent" and sender metadata (endpoint, UDS path, task ID) 2. Target agent processes the message until completion 3. Target agent calls POST /history/update on the sender's endpoint (UDS first, HTTP fallback) 4. Sender's history record is updated from sent to completed/failed/canceled
Characteristics:
- Best-effort: Callback failures are logged but do not affect the receiver's processing
- Transport preference: Uses UDS (Unix Domain Socket) when available, falls back to HTTP
- Timeout: 10 seconds per callback attempt
- Metadata marker: Updated observations include
completion_callback: truein metadata - Failure semantics: Quota/limit output from the receiver is classified as task failure rather than a successful reply body
Agent Teams Endpoints
| Endpoint | Method | Description |
|---|---|---|
/tasks/{id}/approve | POST | Approve a plan |
/tasks/{id}/reject | POST | Reject a plan with reason |
/team/start | POST | Start multiple agents in terminal panes (agent-initiated) |
/spawn | POST | Spawn a single agent in a new terminal pane (supports worktree field for isolation) |
Permission Detection Endpoints
| Endpoint | Method | Description |
|---|---|---|
/tasks/{task_id}/permission/approve | POST | Approve a runtime permission prompt (task must be input_required) |
/tasks/{task_id}/permission/deny | POST | Deny a runtime permission prompt (task must be input_required) |
When a spawned agent hits a permission prompt (e.g., tool approval), the controller detects WAITING status, which maps to the A2A input_required task state. The child automatically notifies its caller with the permission context and a structured permission_escalation block. The parent-side Approval Gate can then auto-dispatch approve/deny/escalate, or a human/Canvas UI can still call these endpoints manually. In synapse send --wait, the sender keeps polling until that parent intervention resolves the child task or the intervention timeout expires.
Preconditions:
- Returns HTTP 404 if the task is not found
- Returns HTTP 400 if the task is not in
input_requiredstatus
Debug Endpoints
| Endpoint | Method | Description |
|---|---|---|
/debug/pty | GET | Return the pyte-rendered virtual terminal state as JSON (display, cursor, alt_screen, rows, columns) |
/debug/waiting | GET | Return the recent WAITING-detection attempts ring buffer plus renderer_available |
GET /debug/pty exposes exactly what waiting_detection regexes see: the raw PTY stream is replayed through a pyte-backed virtual terminal (PtyRenderer) so cursor-motion CSI sequences, ratatui-style redraws, and alt-screen overlays are resolved against a real screen before matching. Use it when tuning profile waiting_detection patterns or diagnosing why a WAITING prompt was (or was not) detected.
GET /debug/waiting returns an in-memory ring buffer (default 50 entries) of recent WAITING detection attempts, one per incoming PTY chunk. Response shape:
{
"renderer_available": true,
"attempts": [
{
"timestamp": 1776819000.12,
"profile": "codex",
"path_used": "renderer",
"renderer_on": true,
"pattern_matched": true,
"pattern_source": "primary",
"confidence": 1.0,
"idle_gate_passed": false,
"new_data_hex_prefix": "50726f636565643f",
"rendered_text_tail": "...Proceed?"
}
]
}Field meanings:
path_used:"renderer"(pyte virtual terminal path) or"strip_ansi"(fallback path)renderer_on: whetherPtyRendereris initialised on this agent (seerenderer_availablebelow)pattern_source:"primary"(profile-specific regex),"heuristic"(generic fallback), ornullconfidence:1.0for primary regex,0.6for heuristic,0.0for no matchidle_gate_passed: whethertime_since_output >= waiting_idle_timeoutwas satisfiednew_data_hex_prefix: first 64 bytes of the raw PTY chunk as hex (preserves ANSI/binary data)rendered_text_tail: last 256 chars of the rendered (or strip-ANSI'd) text
Returns HTTP 503 when the controller predates Phase 1 (#627). Use synapse status <agent> --debug-waiting for formatted aggregates; query this endpoint directly when you need the raw attempts for custom analysis or periodic collection.
`renderer_available`: reflects whether PtyRenderer initialised successfully for this agent. If pyte failed to start, the agent falls back to the strip-ANSI path (lower fidelity for ratatui TUIs). This field appears in synapse list --json, synapse status --json, and the /debug/waiting snapshot. The text output of synapse list / synapse status annotates the status as WAITING (renderer: off) when the renderer is down.
Shared Memory Endpoints
| Endpoint | Method | Description |
|---|---|---|
/memory/list | GET | List memories (query params: author, tags, limit) |
/memory/save | POST | Save/update memory ({key, content, tags?, notify?}) |
/memory/search | GET | Search memories (query param: q) |
/memory/{id_or_key} | GET | Get memory by ID or key |
/memory/{id_or_key} | DELETE | Delete memory by ID or key |
Webhook Endpoints
| Endpoint | Method | Description |
|---|---|---|
/webhooks | POST | Register a webhook for task notifications |
/webhooks | GET | List all registered webhooks |
/webhooks | DELETE | Unregister a webhook (query param: url) |
/webhooks/deliveries | GET | Get recent webhook delivery attempts |
SSE Streaming
| Endpoint | Method | Description |
|---|---|---|
/tasks/{id}/subscribe | GET | Subscribe to task updates via Server-Sent Events |
Canvas Card Endpoints (served by Canvas server)
| Endpoint | Method | Description |
|---|---|---|
/api/cards | POST | Create a new card |
/api/cards | GET | List cards (with optional filters) |
/api/cards | DELETE | Delete cards |
/api/cards/{card_id}/download | GET | Download card as file (optional `?format=md\ |
Canvas Agent Control Endpoints (served by Canvas server)
| Endpoint | Method | Description |
|---|---|---|
/api/admin/agents | GET | List agents with status |
/api/admin/send | POST | Send message to agent |
/api/admin/replies/{task_id} | GET | Get replies for a task |
/api/admin/tasks/{task_id} | GET | Get task details |
/api/admin/start | POST | Start agents |
/api/admin/stop | POST | Stop agents |
/api/admin/agents/spawn | POST | Spawn a new agent |
/api/admin/agents/{agent_id} | DELETE | Stop agent by ID |
/api/admin/jump/{agent_id} | POST | Jump to agent's terminal (uses PID-based terminal detection with TTY fallback) |
Canvas Workflow Endpoints (served by Canvas server)
| Endpoint | Method | Description |
|---|---|---|
/api/workflow | GET | List all workflows with full step details (response includes project_dir) |
/api/workflow/{name} | GET | Get a single workflow by name |
/api/workflow/run/{name} | POST | Start a workflow execution (body: {continue_on_error?}) |
/api/workflow/runs | GET | List active and recent workflow runs |
/api/workflow/runs/{run_id} | GET | Get the status of a specific workflow run |
SSE event: workflow_update — broadcast when a workflow run progresses (step completion, status change).
Execution engine: Workflow steps are sent directly via A2A HTTP (/tasks/send-priority) rather than subprocess. When a step has response_mode: wait, the runner polls the target agent's task (GET /tasks/{id}) until it reaches a terminal state (completed, failed, canceled) or the 10-minute timeout expires. If the target returns HTTP 409 (agent busy), the runner retries up to 5 times with a 2-second interval before reporting failure.
Persistent execution history: Runs are persisted to .synapse/workflow_runs.db (SQLite, WAL mode). The /api/workflow/runs and /api/workflow/runs/{run_id} endpoints return both in-memory and DB-persisted runs, so run history is available across process restarts.
External Agent Endpoints
| Endpoint | Method | Description |
|---|---|---|
/external/discover | POST | Discover and register external A2A agent |
/external/agents | GET | List registered external agents |
/external/agents/{alias} | GET | Get external agent details |
/external/agents/{alias} | DELETE | Remove external agent |
/external/agents/{alias}/send | POST | Send message to external agent |
Roundtrip Communication (--wait / --notify Flow)
When --wait or --notify is used, Synapse expects an explicit reply:
1. Sender calls /tasks/create to create a task without PTY send (stores task context) 2. Sender calls /tasks/send on the target agent with [REPLY EXPECTED] marker 3. Target agent stores sender routing info in the reply stack, including the receiver-side local task ID when available 4. Target agent processes the message and replies via synapse reply or synapse reply --fail 5. Reply first records the explicit reply locally via /tasks/{id}/reply when receiver_task_id is available, then routes the response back to the sender via /tasks/send 6. Sender receives either reply artifacts or a structured task error and the roundtrip completes
This flow ensures reliable request-response patterns between agents.
While an agent is performing an outbound A2A send/reply POST, the registry status is set to SENDING_REPLY. The previous status is restored in finally after the POST completes; terminal/protective statuses (DONE, SHUTTING_DOWN, RATE_LIMITED) are not overwritten by this transient transport state.
Failure semantics:
synapse reply --fail "<reason>"records a failed explicit reply locally and returns a structuredfailedtask to the sender (REPLY_FAILED)- If a
--waitor--notifytask completes without an explicitsynapse reply, the receiver-side task is automatically marked asMISSING_REPLY - Legacy reply-stack entries may not include
receiver_task_id; in that case local reply recording is skipped and missing-reply detection remains the safety net
Readiness Gate
The /tasks/send and /tasks/send-priority endpoints enforce a Readiness Gate that blocks incoming messages until the agent has finished initialization (first READY state).
| Condition | Behavior |
|---|---|
| Agent initializing (not yet READY) | Waits up to AGENT_READY_TIMEOUT (default: 30s) for the agent to become ready |
| Agent still not ready after timeout | Returns HTTP 503 with Retry-After: 5 header |
| Priority 5 (emergency interrupt) | Bypasses the gate entirely |
Reply messages (in_reply_to set) | Bypasses the gate (replies are routed before the check) |
Caller behavior on 503:
- CLI callers (
synapse send) handle retries automatically - Direct API callers should respect the
Retry-Afterheader and retry after the indicated seconds
Configuration:
| Variable | Description | Default |
|---|---|---|
AGENT_READY_TIMEOUT | Seconds to wait for agent readiness before returning 503 | 30 |
Priority Levels
| Priority | Use Case |
|---|---|
| 1-2 | Low priority, background tasks |
| 3 | Normal tasks (send default) |
| 4 | Urgent follow-ups |
| 5 | Emergency interrupt (sends SIGINT first, bypasses Readiness Gate) |
Note: broadcast defaults to priority 1 (low), while send defaults to priority 3 (normal).
Long Message Handling
Messages exceeding the TUI input limit (~200-300 characters) are automatically stored in temporary files. The agent receives a reference message instead:
[LONG MESSAGE - FILE ATTACHED] Path: /tmp/synapse-a2a/messages/<task_id>.txt — Please read this file to get the complete message.Configuration:
| Variable | Description | Default |
|---|---|---|
SYNAPSE_LONG_MESSAGE_THRESHOLD | Character threshold for file storage | 200 |
SYNAPSE_LONG_MESSAGE_TTL | TTL for message files (seconds) | 3600 |
SYNAPSE_LONG_MESSAGE_DIR | Directory for message files | System temp |
Cleanup: Files are automatically cleaned up after TTL expires.
Error Handling
Agent Not Found
Error: No agent found matching 'xyz'Solution: Use synapse list to see available agents.
Multiple Agents Found
Error: Ambiguous target 'codex'. Multiple agents found.Solution: Use custom name (e.g., my-codex) or specific identifier (e.g., codex-8120).
Agent Not Ready (Initializing)
HTTP 503: Agent not ready (initializing). Retry after a few seconds.
Retry-After: 5Solution: The agent is still starting up. Wait a few seconds and retry. Priority 5 messages bypass this check. See "Readiness Gate" section above for details.
Working Directory Mismatch
Warning: Target agent "my-claude" is in a different directory:
Sender: /home/user/project-a
Target: /home/user/project-b
Agents in current directory:
gemini (gemini) - READY
Use --force to send anyway.Solution: The target agent is working in a different directory. Either send to an agent in your current directory, use --force to bypass the check, or spawn a new agent with synapse spawn.
Agent Not Responding
Error: Agent 'synapse-claude-8100' server on port 8100 is not responding.Solution: Restart the agent with synapse claude.
Collaboration Reference
This document covers agent naming, external agents, authentication, session resume, and path configuration — the pieces that make multi-agent collaboration work smoothly.
Agent Naming
Custom names and roles make agents easier to identify and address, especially when running multiple instances of the same type.
Assigning Names and Roles
# Start with name and role
synapse claude --name my-claude --role "code reviewer"
# Start with skill set
synapse claude --skill-set dev-set
# Start with saved agent definition (--agent / -A)
synapse claude --agent calm-lead
synapse claude --agent calm-lead --role "override role" # CLI args override saved values
# Role from file (@prefix reads file content as role)
synapse claude --name reviewer --role "@./roles/reviewer.md"
synapse gemini --role "@~/my-roles/analyst.md"
# Skip interactive name/role setup
synapse claude --no-setup
# Update name/role after agent is running
synapse rename synapse-claude-8100 --name my-claude --role "test writer"
synapse rename my-claude --role "documentation" # Change role only
synapse rename my-claude --clear # Clear name and roleOnce named, use the custom name for all operations:
synapse send my-claude "Review this code"
synapse jump my-claude
synapse kill my-claudeName vs ID
- Display/Prompts: Shows name if set, otherwise ID (e.g.,
Kill my-claude (PID: 1234)?) - Internal processing: Always uses Runtime ID (
synapse-claude-8100) - Target resolution: Name has highest priority when matching targets
Target Resolution Priority
When using commands like synapse send, synapse status, synapse kill, synapse jump, or synapse rename, targets resolve in this order:
1. Custom name (highest priority): my-claude 2. Full Runtime ID: synapse-claude-8100 3. Type-port shorthand: claude-8100 4. Agent type (only if a single instance exists): claude
Custom names are case-sensitive. Agent type resolution uses fuzzy partial matching, so clau can match claude when only one instance is running.
External Agent Management
External agents let you connect to A2A-compatible services running outside your local Synapse environment — useful for reaching remote analysis servers, cloud-hosted agents, or teammates' agents.
# Discover and add an external agent
synapse external add https://agent.example.com --alias myagent
# List registered external agents
synapse external list
# Show agent details (capabilities, skills)
synapse external info myagent
# Send message to external agent
synapse external send myagent "Analyze this data"
synapse external send myagent "Process file" --wait # Wait for completion
# Remove agent
synapse external remove myagentExternal agents are stored persistently in ~/.a2a/external/, so they survive restarts and remain available across sessions.
Authentication
API key authentication protects A2A communication, which matters when agents are exposed beyond localhost or when you want to prevent unauthorized message injection.
# Interactive setup (generates keys + shows instructions)
synapse auth setup
# Generate API key(s)
synapse auth generate-key
synapse auth generate-key -n 3 -e # 3 keys in export format
# Enable authentication
export SYNAPSE_AUTH_ENABLED=true
export SYNAPSE_API_KEYS=<key>
export SYNAPSE_ADMIN_KEY=<admin_key>
synapse claudeWithout authentication enabled, any process that can reach the agent's port can send it messages. Enabling auth ensures only holders of a valid API key can interact with your agents — important for shared networks or production-like setups.
Resume Mode
Resume mode starts an agent without sending initial instructions. This is valuable for session recovery — the agent picks up its existing context instead of receiving a fresh identity injection that could conflict with prior state.
synapse claude -- --resume
synapse gemini -- --resume
synapse codex -- resume # Codex: resume is a subcommand
synapse opencode -- --continue
synapse copilot -- --continueTo inject instructions later (e.g., after confirming the agent is in a clean state):
synapse instructions send <agent>The reason each tool has a different flag is that resume/continue is handled by the underlying CLI tool itself — Synapse passes the flag through after --.
Path Overrides
When running multiple environments, CI pipelines, or isolated test suites, you can override storage paths via environment variables to prevent collisions:
| Variable | Default | Purpose |
|---|---|---|
SYNAPSE_REGISTRY_DIR | ~/.a2a/registry | Running agent registry |
SYNAPSE_REPLY_TARGET_DIR | ~/.a2a/reply | Reply target persistence |
SYNAPSE_EXTERNAL_REGISTRY_DIR | ~/.a2a/external | External agent storage |
SYNAPSE_HISTORY_DB_PATH | ~/.synapse/history/history.db | Task history database |
SYNAPSE_SKILLS_DIR | ~/.synapse/skills | Central skill store |
SYNAPSE_SHARED_MEMORY_DB_PATH | ~/.synapse/memory.db | Shared memory database |
SYNAPSE_SHARED_MEMORY_ENABLED | true | Enable/disable shared memory |
Overriding these paths keeps parallel environments from stepping on each other's state — for example, a CI run using SYNAPSE_REGISTRY_DIR=/tmp/ci-registry avoids interfering with a developer's local agents.
Multi-Agent Workflow Examples
Basic Setup
Start Multiple Agents
# Terminal 1: Start Claude with File Safety (History is enabled by default since v0.3.13)
SYNAPSE_FILE_SAFETY_ENABLED=true synapse claude
# Terminal 2: Start Codex
SYNAPSE_FILE_SAFETY_ENABLED=true synapse codex
# Terminal 3: Start OpenCode
SYNAPSE_FILE_SAFETY_ENABLED=true synapse opencode
# Terminal 4: Monitor
synapse listCommunication Examples
Simple Message (Fire-and-forget)
# Delegate a task (no reply needed)
synapse send codex "Please refactor the authentication module" --silentRequest with Reply
# Ask a question and wait for response
synapse send gemini "What is the best approach for caching?" --waitWith Priority
# Urgent follow-up
synapse send gemini "Status update?" --priority 4 --wait
# Emergency interrupt
synapse send codex "STOP" --priority 5Broadcast to All Agents
# Ask all agents in the same directory for a status check
synapse broadcast "Status check - what are you working on?" --wait
# Notify all agents of a completed build
synapse broadcast "FYI: Build passed, main branch updated" --silent
# Urgent broadcast to stop all work
synapse broadcast "STOP: Critical bug found in shared module" --priority 4File Coordination Example
Delegating File Edit with Lock
# 1. Check Codex is ready
synapse list
# 2. Check file is not locked
synapse file-safety locks
# 3. Send task
synapse send codex "Please refactor src/auth.py. Acquire file lock before editing." --silent
# 4. Monitor progress
synapse file-safety locks
synapse history list --agent codex --limit 5Handling Lock Conflict
If a file is locked:
File src/auth.py is locked by gemini (expires: 12:30:00)
Options:
1. Wait for lock to expire
2. Work on different files first
3. Check with lock holder:
synapse send gemini "What's your progress on src/auth.py?" --waitCollaborative Development
Code Review Workflow
# Terminal 1 (Claude): Implement feature
# Make changes to src/feature.py
# Send for review (wait for feedback)
synapse send codex "Please review the changes in src/feature.py" --wait
# Terminal 2 (Codex): Reply after reviewing
synapse reply "LGTM. Two suggestions: ..."Parallel Research
# Ask multiple agents simultaneously (no reply needed - they'll work independently)
synapse send gemini "Research best practices for authentication" --silent
synapse send codex "Check how other projects implement this pattern" --silentMonitoring Tasks
Watch Agent Status
synapse listView Task History
# Recent tasks
synapse history list --limit 10
# By agent
synapse history list --agent codex
# Search
synapse history search "auth" --agent codexCheck Git Changes
git status
git log --oneline -5
git diffShared Memory Workflow
Saving and Sharing Knowledge
# Agent discovers a pattern and saves it for others
synapse memory save auth-pattern "Use OAuth2 with PKCE flow for all auth" --tags auth,security
# Save with broadcast notification so other agents learn immediately
synapse memory save db-schema "Use UUID primary keys, not auto-increment" --tags database,architecture --notify
# Update existing knowledge (UPSERT on key)
synapse memory save auth-pattern "Use OAuth2 with PKCE flow; add refresh token rotation" --tags auth,securitySearching and Retrieving Knowledge
# Search before starting a task
synapse memory search "auth"
synapse memory search "database"
# View full details of a specific memory
synapse memory show auth-pattern
# List all memories by a specific agent
synapse memory list --author synapse-gemini-8110
# List memories with specific tags
synapse memory list --tags architectureMulti-Agent Knowledge Sharing
# Agent 1 (Claude): Discovers architecture decision
synapse memory save api-style "REST with OpenAPI 3.1, JSON responses" --tags api,architecture --notify
# Agent 2 (Gemini): Receives broadcast, checks memory before implementation
synapse memory search "api"
synapse memory show api-style
# Agent 2 (Gemini): Adds implementation detail
synapse memory save api-auth "Bearer token in Authorization header" --tags api,auth --notify
# Any agent: Check overall knowledge base statistics
synapse memory statsCleanup
# Delete outdated knowledge
synapse memory delete old-pattern --force
# Review what is stored
synapse memory list --limit 20
synapse memory statsAgent Teams Workflow
Delegate Mode Setup
# Terminal 1: Start manager (cannot edit files)
synapse claude --delegate-mode --name manager
# Terminal 2-3: Start worker agents
synapse gemini --name worker-1
synapse codex --name worker-2
# Manager delegates tasks
synapse send worker-1 "Implement auth in src/auth.py"
synapse send worker-2 "Write tests in tests/test_auth.py"Manager + Worker with Worktree Isolation
Use --worktree to give each Worker its own copy of the repository, preventing file conflicts when multiple agents edit code simultaneously. The Manager stays in the main working tree (it delegates, not edits). --worktree is a Synapse-level flag that works for all agent types.
# Terminal 1: Manager (delegate-mode — no file editing)
synapse claude --delegate-mode --name manager
# Spawn Workers in isolated worktrees (each gets its own branch)
# --worktree is a Synapse flag — place it before '--', not after
synapse spawn claude --name worker-1 --role "auth implementer" --worktree
synapse spawn gemini --name worker-2 --role "test writer" --worktree
# Confirm readiness — worktree agents show [WT] prefix in WORKING_DIR
synapse list # Verify worker-1 and worker-2 show STATUS=READY
# Delegate parallel tasks — no file conflicts thanks to worktrees
synapse send worker-1 "Implement OAuth2 in src/auth.py" --silent
synapse send worker-2 "Write tests for src/auth.py in tests/test_auth.py" --silent
# Collect results
synapse send worker-1 "Report your progress" --wait
synapse send worker-2 "Report your progress" --wait
# Cleanup — MUST kill Workers when done (synapse kill also cleans up worktrees)
synapse kill worker-1 -f
synapse kill worker-2 -f
# After killing, handle worktree branches if changes were kept:
# - Merge worktree branch into current branch or create a PR:
# git merge worktree-<name>
# - Or delete if no changes remain:
# git branch -d worktree-<name>Note: --worktree is a Synapse-native flag (not a Claude Code flag). It creates a git worktree at .synapse/worktrees/<name>/ with a branch named worktree-<name>. Works for all agent types (Claude, Gemini, Codex, OpenCode, Copilot). Files listed in .gitignore (.env, .venv/, node_modules/) are not copied -- Workers may need uv sync or npm install before building/testing. On exit: cleanup checks for both uncommitted changes and new commits (vs. the base branch tracked via SYNAPSE_WORKTREE_BASE_BRANCH); worktrees with neither are auto-deleted along with their branch, worktrees with either prompt to keep or remove. The registry stores worktree_base_branch for accurate commit detection. synapse kill also handles worktree cleanup.
Quick Team Start (tmux)
# Start 3 agents in split panes
synapse team start claude gemini codex --layout splitSub-Agent Delegation Patterns
Spawn creates child agents for sub-task delegation — preserving context, parallelizing work for speed, and assigning specialist roles for precision. The parent always owns the lifecycle: spawn → send → evaluate → kill.
Waiting for Readiness
For automation, prefer synapse status <target> --json after spawning and poll until the agent shows STATUS=READY.
Note: Even without polling, the server-side Readiness Gate blocks /tasks/send requests until the agent finishes initialization. If the agent is not ready within 30 seconds (AGENT_READY_TIMEOUT), the API returns HTTP 503 with Retry-After: 5. Priority 5 messages and replies bypass this gate. Human operators can still use synapse list interactively.
# Poll until agent is ready (timeout after 30s)
elapsed=0
while ! synapse status Tester --json 2>/dev/null | grep -Eq '"status"[[:space:]]*:[[:space:]]*"READY"'; do
sleep 1
elapsed=$((elapsed + 1))
if [ "$elapsed" -ge 30 ]; then
echo "ERROR: Tester not READY after ${elapsed}s" >&2
exit 1
fi
doneFor Pattern 3 (multiple agents), wait for all of them:
# Poll until BOTH agents are ready (single snapshot per iteration)
elapsed=0
while true; do
tester=$(synapse status Tester --json 2>/dev/null || true)
fixer=$(synapse status Fixer --json 2>/dev/null || true)
echo "$tester" | grep -Eq '"status"[[:space:]]*:[[:space:]]*"READY"' \
&& echo "$fixer" | grep -Eq '"status"[[:space:]]*:[[:space:]]*"READY"' \
&& break
sleep 1
elapsed=$((elapsed + 1))
if [ "$elapsed" -ge 30 ]; then
echo "ERROR: agents not READY after ${elapsed}s" >&2
exit 1
fi
donePattern 1: Single-Task Delegation (Happy Path)
Spawn one agent, send one task, verify, kill.
# Spawn specialist
synapse spawn gemini --name Tester --role "test writer"
# Confirm readiness (re-run until STATUS=READY; this is a point-in-time snapshot)
synapse list # Verify Tester shows STATUS=READY
# Delegate and wait for result
synapse send Tester "Write unit tests for src/auth.py" --wait
# Evaluate: read reply, then verify artifacts
# (e.g., check git diff or run pytest to confirm tests exist and pass)
# Done — MUST kill
synapse kill Tester -f
# Or graceful kill (sends shutdown request, waits up to 30s): synapse kill TesterPattern 2: Re-Send When Result Is Insufficient
If the result doesn't meet requirements, re-send with refined instructions — don't kill and re-spawn.
# Spawn
synapse spawn codex --name Reviewer --role "code reviewer"
# Confirm readiness (re-run until STATUS=READY; this is a point-in-time snapshot)
synapse list # Verify Reviewer shows STATUS=READY
# First attempt
synapse send Reviewer "Review src/server.py for security issues" --wait
# Evaluate: reply is too vague → re-send with specifics
synapse send Reviewer "Also check for SQL injection in the query builder on lines 45-80" --wait
# Evaluate: now the review is thorough — MUST kill
synapse kill Reviewer -fPattern 3: Multiple Specialists for Parallel Subtasks
Spawn N agents for independent subtasks, collect results, verify, kill all.
# Spawn specialists
synapse spawn gemini --name Tester --role "test writer"
synapse spawn codex --name Fixer --role "bug fixer"
# Confirm readiness of all agents (re-run until both show STATUS=READY)
synapse list # Verify both Tester and Fixer show STATUS=READY
# Delegate parallel subtasks
synapse send Tester "Write tests for src/auth.py" --silent
synapse send Fixer "Fix the timeout bug in src/server.py" --silent
# Monitor progress, then collect results
synapse send Tester "Report your progress" --wait
synapse send Fixer "Report your progress" --wait
# Evaluate: verify artifacts (e.g., git diff, pytest)
# All done — MUST kill all
synapse kill Tester -f
synapse kill Fixer -fHow Many Agents to Spawn
1. User-specified count → follow it exactly (top priority) 2. No user specification → parent decides based on task structure:
- Single focused subtask → 1 agent
- Independent parallel subtasks → N agents (one per subtask)
Communication Notes
- Use
synapse send ...(notsynapse reply) for all communication with spawned agents (#237).--fromis auto-detected from$SYNAPSE_AGENT_ID(set by Synapse at startup, e.g.,synapse-claude-8100). - Pane auto-close: All supported terminals automatically close spawned panes when the agent terminates.
- Stdout capture:
synapse spawnprints<agent_id> <port>to stdout; warnings go to stderr, so command substitution captures only the clean output:
result=$(synapse spawn gemini --name Helper --role "helper")
agent_id=$(echo "$result" | awk '{print $1}') # e.g., synapse-gemini-8110
port=$(echo "$result" | awk '{print $2}') # e.g., 8110This works in all terminals but is most useful with tmux where the spawning shell remains interactive.
CI Monitoring and Auto-Fix Workflow
Automatic CI Monitoring (via hooks)
After git push or gh pr create, PostToolUse hooks automatically launch background monitors:
git push
└─ check-ci-trigger.sh (PostToolUse hook)
├─ poll-ci.sh → polls GitHub Actions → reports pass/fail
└─ poll-pr-status.sh → checks merge conflicts + CodeRabbit reviewYou receive systemMessage notifications:
[CI Monitor] CI PASSED on feature/x (abc1234)— all green[CI Monitor] CI FAILED on feature/x (abc1234)— suggests/fix-ci[PR Monitor] Merge conflict detected on PR #42— suggests/fix-conflict[PR Monitor] CodeRabbit review on PR #42— classifies comments, suggests/fix-review
Manual CI Check and Fix
# 1. Check current CI status manually
/check-ci
# 2. If issues found, fix them in priority order:
/fix-conflict # Resolve merge conflicts first (if any)
/fix-ci # Fix CI failures (lint, format, type, test)
/fix-review # Address CodeRabbit review comments
# 3. Preview without applying changes
/fix-ci --dry-run
/fix-conflict --dry-run
/fix-review --dry-run
# 4. Check status again after fixes
/check-ciTypical Fix Cycle
git push
→ CI fails (lint error)
→ [CI Monitor] suggests /fix-ci
→ /fix-ci → applies ruff fix → verifies → pushes
→ CI passes
→ [PR Monitor] CodeRabbit has 2 bugs, 1 style issue
→ /fix-review → fixes bugs + style → verifies → pushes
→ CI passes, review cleanCanvas Template Workflows
Briefing for Structured Status Reports
synapse canvas briefing '{"title":"Sprint Review","sections":[{"title":"Summary","blocks":[0]},{"title":"Risks","blocks":[1]}],"content":[{"format":"markdown","body":"## Summary\nAuth fixes merged."},{"format":"alert","body":{"severity":"warning","message":"Visual QA still pending","source":"Release"}}]}' --title "Sprint Review"Comparison for Before/After Reviews
synapse canvas post-raw '{"type":"render","agent_id":"cli","title":"Dashboard Cleanup","template":"comparison","template_data":{"layout":"side-by-side","sides":[{"label":"Before","blocks":[0]},{"label":"After","blocks":[1]}]},"content":[{"format":"markdown","body":"Old dashboard with dense multi-column layout."},{"format":"markdown","body":"New dashboard with vertical widgets and clean layout."}]}'Steps for Execution Plans
synapse canvas post-raw '{"type":"render","agent_id":"cli","title":"Release Plan","template":"steps","template_data":{"steps":[{"title":"Write tests","blocks":[0],"done":true},{"title":"Implement fix","blocks":[1],"done":true},{"title":"Run visual QA","blocks":[2],"done":false}]},"content":[{"format":"markdown","body":"Regression tests added."},{"format":"markdown","body":"Canvas bug fixes applied."},{"format":"markdown","body":"Pending final browser review."}]}'Troubleshooting
Agent Not Responding
1. Check status:
synapse list2. If PROCESSING for too long:
synapse send <agent> "Status?" --priority 4 --wait3. Emergency stop:
synapse send <agent> "STOP" --priority 5Agent Not Found
# List available agents
synapse list
# Start missing agent
synapse codex # in new terminalFeatures Reference
Session Save/Restore
Save running team configurations as named JSON snapshots and restore them later.
Captures each agent's profile, name, role, skill set, worktree setting, and session_id (CLI conversation identifier).
Scopes: project (.synapse/sessions/), user (~/.synapse/sessions/), or --workdir DIR (DIR/.synapse/sessions/).
Restore spawns all agents from the snapshot via spawn_agent(). Use --resume to resume each agent's previous CLI session (conversation history); if resume fails within 10 seconds, the agent is retried without resume args (shell-level fallback).
synapse session save <name> [--project|--user|--workdir <dir>]
synapse session list [--project|--user|--workdir <dir>]
synapse session show <name> [--project|--user|--workdir <dir>]
synapse session restore <name> [--project|--user|--workdir <dir>] [--worktree] [--resume] [-- tool_args...]
synapse session delete <name> [--project|--user|--workdir <dir>] [--force]
synapse session sessions # List CLI tool sessions from filesystem
synapse session sessions --profile claude # Filter by profile
synapse session sessions --limit 10 # Limit resultsWorkflow Definitions
Define multi-step agent workflows as YAML files. Each step targets an agent with a message, priority, and response mode.
Target types:
target: self— Execute the step locally on the calling agent (no A2A round-trip)target: <type>(e.g.,claude,gemini) — Send to another agent of that type. If the only match is the calling agent itself, the runner spawns a new agent to avoid deadlock
Storage: .synapse/workflows/ (project) or ~/.synapse/workflows/ (user).
synapse workflow create <name> [--project|--user] [--force] # Create workflow template YAML (+ auto-generate skill)
synapse workflow list [--project|--user] # List saved workflows
synapse workflow show <name> [--project|--user] # Show workflow details
synapse workflow run <name> [--project|--user] [--dry-run] [--continue-on-error] [--auto-spawn] # Execute steps
synapse workflow delete <name> [--project|--user] [--force] # Delete a saved workflow (+ remove auto-generated skill)
synapse workflow sync # Sync all workflows to skill directoriesSupports --dry-run to preview execution without sending messages, --continue-on-error to proceed past step failures, and --auto-spawn to spawn missing agents on the fly.
Execution engine: Steps are sent directly via A2A HTTP (/tasks/send-priority) with built-in resilience. response_mode: wait steps poll the target's task until a terminal state (completed, failed, canceled) or a 10-minute timeout. HTTP 409 (agent busy) responses trigger automatic retry (up to 5 attempts, 2-second interval).
Persistent execution history: Workflow runs are persisted to SQLite (.synapse/workflow_runs.db, WAL mode) so that run history survives process restarts. The in-memory run list is merged with the DB on startup — in-memory entries take precedence over DB entries with the same run ID. A delete_runs_older_than() API is available for manual age-based cleanup, but no automatic DB pruning is performed.
Workflow-to-Skill Bridge
Workflows can be auto-generated as skills so they appear as discoverable slash commands. The trigger YAML field provides keywords for skill matching, and auto_spawn (workflow-level or per-step) enables automatic agent spawning during execution.
synapse workflow createauto-generates a SKILL.md in.claude/skills/<name>/and.agents/skills/<name>/synapse workflow deleteremoves the auto-generated skill directoriessynapse workflow syncregenerates skills for all workflows and removes orphaned auto-generated skills- Auto-generated skills are marked with
<!-- synapse-workflow-autogen -->and are never confused with hand-written skills
Saved Agent Definitions
Persist reusable agent definitions with synapse agents. Stored as .agent files in project or user scope.
Use --agent/-A flag to start from a saved definition (e.g., synapse claude --agent calm-lead), or pass the saved ID/name directly to synapse spawn.
synapse agents list # List saved agent definitions
synapse agents show <id_or_name> # Show details for a saved agent
synapse agents add <id> --name <name> --profile <profile> [--role <role>] [--skill-set <set>] [--scope project|user]
synapse agents delete <id_or_name> # Delete a saved agent by ID or nameStorage: .synapse/agents/ (project scope), ~/.synapse/agents/ (user scope).
Token/Cost Tracking
synapse history stats shows a TOKEN USAGE section when token data exists. Token parsing is implemented via a registry pattern (TokenUsage dataclass + parse_tokens() registry).
synapse history stats # Overall stats with token usage
synapse history stats --agent gemini # Per-agent token statsSkills Management
Central skill store with deploy, import, create, and skill set support. Skill set details (name, description, skills) are included in agent initial instructions when selected.
synapse skills # Interactive TUI skill manager
synapse skills list # List all discovered skills
synapse skills list --scope synapse # List central store skills only
synapse skills show <name> # Show skill details
synapse skills delete <name> [--force] # Delete a skill
synapse skills move <name> --to <scope> # Move skill between scopes
synapse skills deploy <name> --agent claude,codex --scope user # Deploy from central store
synapse skills import <name> # Import to central store (~/.synapse/skills/)
synapse skills add <repo> # Install from repo (npx skills wrapper)
synapse skills create [name] # Create new skill template
synapse skills set list # List skill sets
synapse skills set show <name> # Show skill set details
synapse skills apply <target> <set_name> # Apply skill set to running agent
synapse skills apply <target> <set_name> --dry-run # Preview changes onlyStorage: ~/.synapse/skills/ (central/SYNAPSE scope).
Settings Management
Configure Synapse via settings.json with interactive TUI or direct scope editing.
synapse config # Interactive config editor
synapse config --scope user # Edit user settings directly
synapse config --scope project # Edit project settings directly
synapse config show # Show merged settings (read-only)
synapse config show --scope user # Show user settings only
synapse init # Interactive scope selection
synapse init --scope user # Create ~/.synapse/settings.json
synapse init --scope project # Create ./.synapse/settings.json
synapse reset # Interactive scope selection
synapse reset --scope user # Reset user settings to defaults
synapse reset --scope both -f # Reset both without confirmationSettings include approvalMode for controlling initial instruction approval behavior.
Proactive Mode
Enforces mandatory usage of all Synapse coordination features for every task, regardless of size.
Activation: SYNAPSE_PROACTIVE_MODE_ENABLED=true synapse claude
When enabled, the .synapse/proactive.md instruction file is injected at startup. It requires agents to follow a strict per-task checklist:
Before work: Search shared memory, check available agents. During work: Lock files before editing, save discoveries to memory, post artifacts to canvas, delegate subtasks. After work: Unlock files, mark task complete, broadcast completion, post summary to canvas.
Rules:
- Always lock files before editing in multi-agent setups
- Always save useful findings to shared memory
- Always post significant artifacts to canvas
- For tasks with 2+ phases: delegate at least one phase to another agent
- For tasks touching 3+ files: use file-safety locks on all files
Difference from default behavior: Without proactive mode, the Collaboration Decision Framework in default instructions recommends feature usage but leaves it to agent judgment. With proactive mode, every step is mandatory and must be followed as a checklist.
Configuration: Toggle via synapse config TUI or set the environment variable directly.
MCP Bootstrap Server
Distribute Synapse initial instructions via MCP (Model Context Protocol) resources and tools. MCP-compatible clients (Claude Code, Codex, Gemini CLI, OpenCode) can read instructions as structured resources instead of relying solely on PTY injection.
Phase 1 (current): Instruction resources + bootstrap_agent tool + minimal PTY bootstrap + analyze_task Smart Suggest tool + canvas_post Canvas-write tool. bootstrap_agent returns runtime context and instruction resource URIs for the current agent. canvas_post lets MCP clients write Canvas cards without shelling out (safe for bodies containing quotes/backticks). When a Synapse MCP server config entry is detected for Claude Code, Codex, Gemini CLI, or OpenCode, Synapse sends a minimal PTY bootstrap message (agent ID, port, and pointers to MCP resources) instead of full instructions — approval prompts are kept. Non-Synapse MCP entries do not trigger the switch. Copilot supports MCP tools only (bootstrap_agent, list_agents, analyze_task, canvas_post) and cannot consume MCP resources/prompts.
Resources:
| URI | Description |
|---|---|
synapse://instructions/default | Base Synapse bootstrap instructions |
synapse://instructions/file-safety | File locking rules (if enabled) |
synapse://instructions/shared-memory | Shared memory conventions (if enabled) |
synapse://instructions/learning | Learning mode guidance (if enabled) |
synapse://instructions/proactive | Proactive mode instructions (if enabled) |
Tools:
bootstrap_agentreturns runtime context (agent_id, agent_type, port, working_dir, instruction_resources, available_features).list_agentslists running Synapse agents with status and connection info.analyze_taskanalyzes a user prompt and suggests team/task splits when the work is large enough (Smart Suggest).canvas_postposts a Canvas card directly through the local store, bypassing shell escaping (format,body, optionaltitle/tags).
# Start MCP server (stdio transport; options auto-resolved from $SYNAPSE_AGENT_ID)
# Fallback: if SYNAPSE_AGENT_ID is unset, defaults to agent-id "synapse-mcp"
synapse mcp serveClient configuration: Add to .mcp.json (Claude Code), ~/.codex/config.toml (Codex), ~/.gemini/settings.json (Gemini CLI), or ~/.config/opencode/opencode.json (OpenCode). Use uv run --directory <repo> python -m synapse.mcp as the command to ensure the correct Synapse version is used.
Copilot MCP support: GitHub Copilot's coding agent supports MCP tools only and cannot consume MCP resources/prompts. Copilot agents use bootstrap_agent to retrieve runtime context, analyze_task for smart suggestions, and canvas_post to write Canvas cards; the synapse://instructions/* resources are not available to Copilot.
Settings caching: The MCP server caches SynapseSettings as a lazy singleton for the lifetime of the process, avoiding repeated file reads.
Canvas Board
Shared visual dashboard for agents to post rich content cards rendered in a browser-based SPA.
Views: Hash-routed SPA with seven top-level views — #/ (Canvas spotlight) with #/history as a sub-view (grid + live feed + agent messages; appears as indented sub-item under Canvas in sidebar), #/dashboard (operational overview with expandable summary+detail widgets: Agents, Tasks, File Locks, Worktrees, Memory, Errors), #/admin (Agent Control: clickable agent table for selection, double-click agent row to jump to terminal via POST /api/admin/jump/{agent_id}, textarea input with Cmd+Enter send, reply-based response via synapse reply, IME composition handling, sticky table headers), #/workflow (Workflow view: list saved workflows, inspect steps, trigger runs, monitor run progress with live updates via workflow_update SSE event; failed steps show error details, each step displays execution duration, Mermaid DAG includes message preview and response_mode edge labels, run history shows step progress count and failure details, project directory displayed next to Run button), #/harnesses (Harnesses landing page linking to the Skills and MCP Servers sub-views) with sub-routes #/harnesses/skills (inventory of SKILL.md definitions grouped by scope — User Global, Project, Synapse Central Store, Plugin — scanned per active project root so every running agent's project shows up as its own group; search filter by name) and #/harnesses/mcp (MCP server configs across projects and every supported agent harness: Project .mcp.json (scanned per active project root), Claude Code ~/.claude.json, Codex ~/.codex/config.toml (TOML), Gemini ~/.gemini/settings.json, OpenCode ~/.config/opencode/opencode.json, and Claude Desktop ~/Library/Application Support/Claude/claude_desktop_config.json; surfaces command, args, env key names, cwd, source file), and #/system (configuration panel: tips, saved agents, skills, skill sets, sessions, workflows, environment). Navigation via sidebar (fixed on desktop, hamburger drawer on mobile); Canvas parent link stays active when History sub-route is shown, and Harnesses parent stays active when Skills/MCP sub-routes are shown. View state preserved across SSE reconnects.
25 card formats: mermaid, markdown, html, artifact, table, json, diff, code, chart, image, log, status, metric, checklist, timeline, alert, file-preview, trace, tip, progress, terminal, dependency-graph, cost, link-preview, plan.
Rendering highlights:
- Markdown cards: Enhanced parser supports headings, paragraphs, bold/italic, inline code, code blocks, unordered and ordered lists, tables, blockquotes, horizontal rules, and links. Document content uses Source Sans 3 body font and Source Code Pro monospace font for a polished typographic appearance
- Code cards: Syntax highlighted via highlight.js (set
--langfor best results) - Chart cards: Chart.js supports all chart types (bar, line, pie, doughnut, radar, polarArea, scatter, bubble)
- Diff cards: Side-by-side renderer with left (deletions) / right (additions) columns and line numbers
- HTML cards: Rendered in sandboxed iframe (
allow-scripts) with theme sync viapostMessage(CSS variables--bg,--fg,--border), auto-resize via ResizeObserver, dark mode background, and full document normalization (extracts<head>/<body>from complete HTML documents to avoid CSP/cascade conflicts) - Artifact cards: Interactive HTML/JS/CSS applications (like Claude.ai Artifacts) rendered in sandboxed iframe (
allow-scripts) with theme sync viapostMessage(CSS variables--bg,--fg,--border), auto-resize via ResizeObserver; accepts a full HTML document string - Mermaid cards: Diagrams auto-sync with the Canvas light/dark theme toggle; dark mode uses a Catppuccin-inspired palette, light mode uses an Indigo palette with brand accent
#4051b5 - Image cards: PNG, JPEG, SVG, GIF, WebP via URL or Base64 data URI (up to 2MB). SVG is ideal for agent-generated vector diagrams (architecture, network topology, data flow)
- Link-preview cards: Fetches Open Graph metadata from a URL and renders a rich card with title, description, and thumbnail image
synapse canvas post <format> "<body>" --title "<title>" [--pinned] [--tags "t1,t2"]
synapse canvas link "<url>" --title "<title>" [--pinned]
synapse canvas briefing '<json>' --title "<title>" [--pinned]
synapse canvas briefing --file report.json --title "CI Report"
synapse canvas open # Open in browser (auto-starts server)
synapse canvas list [--agent-id <id>] [--type <format>] [--search "<query>"]Templates (6): briefing, comparison, dashboard, steps, slides, plan. Templates control how composite content blocks are laid out. Use synapse canvas briefing for the briefing template CLI shortcut, synapse canvas plan for plan cards with Mermaid DAG and step tracking, or synapse canvas post-raw with template/template_data fields for any template. See references/commands.md for full schema details.
Plan Cards
Plan cards combine a Mermaid DAG visualization with a step list for tracking multi-step work.
synapse canvas plan '{"plan_id":"plan-auth","status":"proposed","mermaid":"graph TD; A-->B","steps":[{"id":"s1","subject":"Design","status":"pending"}]}' --title "Auth Plan"Card Download
Cards can be downloaded as files via the browser download button or the API endpoint GET /api/cards/{card_id}/download[?format=md|json|csv|html|txt|native]. Each card format maps to an optimal download format automatically (e.g., table → CSV, code → native source file, markdown → .md). The optional format query parameter overrides the default. Supported export groups: Markdown (Group A), native file (Group B), JSON (Group C), CSV (Group D).
Storage: ~/.synapse/canvas.db (user-global, SQLite).
Self-Learning Pipeline (ECC)
The observation layer runs automatically when enabled, and the explicit CLI commands are available: synapse learn extracts instincts, synapse instinct lists or promotes them, and synapse evolve discovers or generates skill candidates.
Observe agent behavior, learn patterns, and evolve reusable skills automatically. The pipeline has four stages:
1. Observation Layer (synapse/observation.py)
ObservationStore persists structured events to .synapse/observations.db (SQLite, WAL mode). ObservationCollector provides typed methods for recording events without manual SQL.
Event types:
task_received— message received with sender and prioritytask_completed— task finished with duration, status, output summaryerror— error with type, message, and recovery actionstatus_change— agent status transition (from/to/trigger)file_operation— file path and operation type
Configuration:
SYNAPSE_OBSERVATION_ENABLED— enable/disable collection (default:true)SYNAPSE_OBSERVATION_DB_PATH— custom database path
Each observation is tagged with a project_hash (derived from git remote.origin.url or cwd) for per-project isolation.
2. Pattern Analyzer (synapse/pattern_analyzer.py)
PatternAnalyzer scans observations and generates instinct candidates using rule-based analysis:
- Repeated errors — errors of the same type appearing 2+ times produce a debugging instinct with the observed recovery action
- Successful senders — senders whose tasks consistently complete are surfaced as collaboration patterns
- Status transitions — frequent from/to status pairs suggest workflow optimization opportunities
Confidence scales with frequency: 2 occurrences = 0.3, 3+ = 0.5, 5+ = 0.7, 10+ = 0.9.
3. Instinct Store (synapse/instinct.py)
InstinctStore persists learned trigger/action pairs to .synapse/instincts.db (SQLite, WAL mode). Each instinct has:
- trigger — condition that activates the instinct
- action — recommended response
- confidence — 0.3–0.9, increases with repeated evidence
- scope —
project(local) orglobal(promoted across projects) - domain — category (debugging, testing, workflow, etc.)
- source_observations — IDs of observations that produced the instinct
Instincts can be promoted from project to global scope via synapse instinct promote.
Configuration: SYNAPSE_INSTINCT_DB_PATH — custom database path.
4. Evolution Engine (synapse/evolve.py)
EvolutionEngine clusters instincts by domain and generates reusable skill candidates:
- Groups instincts by domain, requires 2+ instincts and average confidence >= 0.5
- Generates
SKILL.mdfiles in.synapse/evolved/skills/,.claude/skills/, and.agents/skills/ - Each generated skill includes frontmatter with source instinct IDs, trigger patterns, and action recommendations
Storage: .synapse/observations.db, .synapse/instincts.db, .synapse/evolved/skills/ (all project-local, SQLite).
File Safety Reference
File Safety prevents conflicts when multiple agents edit the same files.
Skip Locking in a Worktree
SYNAPSE_WORKTREE_PATH is the signal that the current agent is running inside an isolated git worktree. For edits inside that worktree tree, skip synapse file-safety lock/unlock/record because the worktree is exclusive to that agent.
[ -n "$SYNAPSE_WORKTREE_PATH" ] && echo "worktree: skip locks" || echo "main repo: lock as usual"This exemption only applies inside the worktree. Still lock shared paths outside the worktree, such as $HOME config, the parent repo's registry, and cross-worktree databases like ~/.synapse/file_safety.db.
MANDATORY: Checklist Before Edit/Write (non-worktree only)
Before using Edit, Write, sed, awk, or ANY file modification:
- [ ] Check locks:
synapse file-safety locks - [ ] Lock file:
synapse file-safety lock <file> <agent_id> --intent "..." - [ ] Verify lock:
synapse file-safety locks
If lock fails (another agent has it): DO NOT edit. Work on something else.
Enable File Safety
# Via environment variable
export SYNAPSE_FILE_SAFETY_ENABLED=true
synapse claude
# Via settings.json
synapse init
# Edit .synapse/settings.jsonQuick Reference
| Action | Command |
|---|---|
| Check locks | synapse file-safety locks |
| Lock file | synapse file-safety lock <file> <agent_id> --intent "..." |
| Unlock file | synapse file-safety unlock <file> <agent_id> |
| Record change | synapse file-safety record <file> <agent_id> <task_id> --type MODIFY |
| File history | synapse file-safety history <file> [--limit N] |
| Recent changes | synapse file-safety recent [--agent <name>] [--limit N] |
| Status | synapse file-safety status |
| Cleanup old | synapse file-safety cleanup --days 30 [--force] |
| Cleanup locks | synapse file-safety cleanup-locks [--force] |
| Debug info | synapse file-safety debug |
Commands
Check Status
# Overall statistics
synapse file-safety status
# List active locks
synapse file-safety locks
synapse file-safety locks --agent claudeLock/Unlock Files
# Acquire lock
synapse file-safety lock /path/to/file.py claude --intent "Refactoring" --duration 300
# Wait for lock if held by another agent
synapse file-safety lock /path/to/file.py claude --wait
# Wait with timeout and custom retry interval
synapse file-safety lock /path/to/file.py claude --wait --wait-timeout 60 --wait-interval 5
# Release lock
synapse file-safety unlock /path/to/file.py claudeView File History
# File modification history
synapse file-safety history /path/to/file.py
synapse file-safety history /path/to/file.py --limit 10
# Recent modifications (all files)
synapse file-safety recent
synapse file-safety recent --agent claude --limit 20Record Modifications
synapse file-safety record /path/to/file.py claude task-123 \
--type MODIFY \
--intent "Bug fix"Cleanup Old Records
# Clean records older than 30 days
synapse file-safety cleanup --days 30
# Force cleanup without confirmation
synapse file-safety cleanup --days 30 --forceCleanup Stale Locks
Remove locks held by dead processes:
# Show and clean stale locks (prompts for confirmation)
synapse file-safety cleanup-locks
# Force cleanup without confirmation
synapse file-safety cleanup-locks --forceDetects locks whose owning process (PID) is no longer running and removes them.
Debug
Show troubleshooting information:
synapse file-safety debugDisplays:
- Environment variables (
SYNAPSE_FILE_SAFETY_ENABLED,SYNAPSE_FILE_SAFETY_RETENTION_DAYS, etc.) - Settings file locations and status
- Database path, enabled status, active locks count, total modifications
- Instruction file locations
- Log file locations
- Debug tips (enable debug logging, file logging)
Complete Workflow
Before Editing
1. Check if file is locked:
synapse file-safety locks2. Acquire lock (REQUIRED):
synapse file-safety lock /path/to/file.py <agent_name> --intent "Description"3. Verify you have the lock:
synapse file-safety locksAfter Editing
1. Record modification:
synapse file-safety record /path/to/file.py <agent_name> <task_id> --type MODIFY2. Release lock:
synapse file-safety unlock /path/to/file.py <agent_name>Error Handling
File Locked by Another Agent
Error: File is locked by gemini (expires: 2026-01-09T12:00:00)Solutions: 1. Wait for lock to expire 2. Work on different files first 3. Coordinate with lock holder: synapse send gemini "What's your progress on src/auth.py?" --wait
Why This Matters
- Without locks, two agents editing the same file = DATA LOSS
- Your changes may be overwritten without warning
- Other agents' work may be destroyed
- EVERY EDIT OUTSIDE A WORKTREE NEEDS A LOCK. See "Skip Locking in a Worktree" above.
Storage
- Default DB:
~/.synapse/file_safety.db(SQLite) - Project-level:
.synapse/file_safety.db - Configure via
SYNAPSE_FILE_SAFETY_DB_PATH
Messaging Reference
Detailed reference for inter-agent messaging in Synapse A2A, covering sending, receiving, priorities, status, and interactive controls.
Sending Messages
synapse send is the recommended way to communicate between agents. It works reliably from any environment, including sandboxed agents.
synapse send gemini "Please review this code" --notify
synapse send claude "What is the status?" --wait
synapse send codex-8120 "Fix this bug" --silent --priority 3Sender Identification
--fromis auto-detected from theSYNAPSE_AGENT_IDenvironment variable (set by Synapse at startup), so you can usually omit it.- If auto-detection fails (e.g., sandboxed environments like Codex), specify explicitly:
--from $SYNAPSE_AGENT_ID. - When using
--from, always use the Runtime ID format (synapse-<type>-<port>). Custom names and agent types are not accepted here because the Runtime ID is the canonical identifier used for routing.
Target Resolution
Targets are matched in priority order:
1. Custom name (highest): my-claude -- exact match, case-sensitive 2. Exact Runtime ID: synapse-claude-8100 3. Type-port shorthand: claude-8100, codex-8120, opencode-8130, copilot-8140 4. Type only: claude, gemini, codex, opencode, copilot -- works only when a single instance of that type is running
When multiple agents of the same type are running, a type-only target (e.g., claude) fails with an ambiguity error and lists runnable synapse send commands for each match. Use a custom name or type-port shorthand instead.
Working Directory Check
synapse send and synapse interrupt verify that the sender's working directory matches the target's. A mismatch likely means the agents are working on different projects, so the command exits with code 1 and prints a warning:
Warning: Target agent "my-claude" is in a different directory:
Sender: /home/user/project-a
Target: /home/user/project-b
Agents in current directory:
gemini (gemini) - READY
Use --force to send anyway.If no agents are running in the sender's directory, the warning suggests synapse spawn instead. To bypass the check intentionally:
synapse send my-claude "Cross-project message" --force
synapse interrupt my-claude "Urgent" --forceResponse Modes
Choose the response mode based on whether you need a result:
| Flag | Behavior | When to use |
|---|---|---|
--notify | Async notification on completion (default) | General task delegation |
--wait | Synchronous blocking until reply | Questions, reviews, analysis -- anything where you need an immediate answer |
--silent | Fire-and-forget, no notification | Informational messages, delegated work where results are checked separately |
# Block until reply arrives
synapse send gemini "What is the best approach?" --wait
# Default async notification
synapse send gemini "Run tests and report" --notify
# No notification needed
synapse send codex "FYI: Build completed" --silentRoundtrip Communication (--wait)
For request-response patterns, the sender blocks with --wait and the receiver replies with synapse reply:
# Sender: blocks until reply received
synapse send gemini "Analyze this data" --wait
# Receiver: auto-routes to the waiting sender
synapse reply "Analysis result: ..."Synapse automatically tracks senders who expect a reply (marked with [REPLY EXPECTED] in the delivered message). synapse reply knows who to respond to without additional configuration.
During outbound A2A send/reply POSTs, the sender may briefly appear as SENDING_REPLY in synapse list or synapse status. This is a transient transport state: Synapse restores the previous status after the POST finishes and does not overwrite terminal/protective states such as DONE, SHUTTING_DOWN, or RATE_LIMITED.
Broadcasting to All Agents
Send a message to every agent sharing the same working directory:
synapse broadcast "Status check"
synapse broadcast "Urgent: stop all work" --priority 4
synapse broadcast "FYI: Build completed" --silentBroadcast only targets agents in the same working directory as the sender, preventing unintended cross-project messages.
Message Files and Attachments
For long messages that exceed shell argument limits, use --message-file or --stdin:
synapse send claude --message-file /tmp/review.txt --silent
echo "long message" | synapse send claude --stdin --silent
synapse send claude --message-file - --silent # '-' reads from stdinMessages over 100 KB are automatically written to temp files (threshold configurable via SYNAPSE_SEND_MESSAGE_THRESHOLD).
To attach files to a message:
synapse send claude "Review this" --attach src/main.py --wait
synapse send claude "Review these" --attach src/a.py --attach src/b.py --waitReceiving and Replying to Messages
Incoming A2A messages appear with the A2A: prefix:
A2A: [From: NAME (SENDER_ID)] [Task: XXXXXXXX] [REPLY EXPECTED] <message content>- From: The sender's display name and Runtime ID.
- REPLY EXPECTED: The sender is blocking, waiting for your response.
Fallback formats when sender info is unavailable:
A2A: [From: SENDER_ID] <message content>A2A: <message content>(backward-compatible)
When [REPLY EXPECTED] is present, reply with synapse reply so the sender can unblock. Do not manually include [REPLY EXPECTED] in outgoing messages -- Synapse adds it automatically when --wait is used.
Replying
# Auto-routes to the last sender expecting a reply
synapse reply "Here is my analysis..."
# Send a failed reply (task could not be completed)
synapse reply --fail "Quota exceeded"
# When multiple senders are pending
synapse reply --list-targets
synapse reply "Here is my analysis..." --to <sender_id>
# In sandboxed environments (like Codex), specify your Runtime ID
synapse reply "Here is my analysis..." --from $SYNAPSE_AGENT_IDExample -- question received (reply expected):
Received: A2A: [From: Claude (synapse-claude-8100)] [REPLY EXPECTED] What is the project structure?
Reply: synapse reply "The project has src/, tests/..."Missing reply detection: If a --wait or --notify task completes without an explicit synapse reply, the task is automatically marked as MISSING_REPLY (failed). Always use synapse reply or synapse reply --fail when [REPLY EXPECTED] is present.
Example -- delegation received (no reply needed):
Received: A2A: [From: Gemini (synapse-gemini-8110)] Run the tests and fix failures
Action: Do the task. No reply needed unless you have questions.Priority Levels
| Priority | Description | Use Case |
|---|---|---|
| 1-2 | Low | Background tasks |
| 3 | Normal | Standard tasks |
| 4 | Urgent | Follow-ups, status checks |
| 5 | Interrupt | Emergency -- sends SIGINT first, bypasses Readiness Gate |
Default priority: send = 3 (normal), broadcast = 1 (low). Broadcast defaults to low priority because it fans out to all agents, and most broadcast messages are informational rather than urgent.
# Normal priority (default 3)
synapse send gemini "Analyze this" --wait
# Urgent request
synapse send claude "Urgent review needed" --wait --priority 4
# Soft interrupt (shorthand for send -p 4 --silent)
synapse interrupt gemini "Stop and review"
# Emergency interrupt
synapse send codex "STOP" --priority 5Local-only Resolution (--local-only)
--local-only restricts target resolution to agents whose working_dir matches the caller's current directory. Without it, bare-type targets like codex or claude can fall back to an agent in a completely different repository, which is almost never what you want when a workflow is coordinating siblings inside one project.
# Only resolve to a codex in the caller's WD (or worktree pair).
# Fails with "No agent found" if none is local, letting --auto-spawn create one.
synapse send codex "run tests" --local-only --notifyWorkflow runner uses this automatically. Every step in synapse workflow run is dispatched with --local-only so that target: codex in a YAML never leaks to an unrelated codex agent in another directory. When combined with --auto-spawn, a missing same-WD target is spawned fresh in the caller's working directory instead of silently reusing an elsewhere-running instance.
Handling input_required
When a child task stops in input_required, the child is blocked on parent input — typically a permission approval, but also clarifying questions (e.g. /release patch|minor|major?) or any interactive prompt the child cannot answer by itself. Synapse surfaces this to the parent in two complementary ways:
1. The child agent proactively notifies its parent via A2A when it transitions into input_required (see _on_status_change in the server). The parent receives both the legacy text artifact and a structured permission_escalation block containing the child endpoint, task id, agent type, and permission metadata. The parent-side Approval Gate can consume that block and automatically decide approve, deny, or escalate.
2. `synapse send --wait` no longer treats `input_required` as terminal. The CLI prints the task_id, endpoint, pty_context preview, and the exact curl / synapse send commands the parent can use to unblock the child, then keeps polling until the task reaches a terminal state. If no parent intervention arrives before SYNAPSE_PARENT_INTERVENTION_TIMEOUT (default 1800s), it exits non-zero (exit code 2).
As the parent, when you see either signal, inspect the context and do one of:
# Approve a permission prompt
curl -X POST "<endpoint>/tasks/<task_id>/permission/approve"
# Deny a permission prompt
curl -X POST "<endpoint>/tasks/<task_id>/permission/deny"
# Send a clarification reply (child resumes once its PTY gets the text)
synapse send <child> "<clarifying answer>" --local-only --notifyNever treat input_required as "done" — that is how workflow runners previously drifted into 409 cascades when a child was quietly waiting for the parent to answer.
Agent Status
| Status | Meaning | Color |
|---|---|---|
| READY | Idle, waiting for input | Green |
| WAITING | Awaiting user input (selection, confirmation, permission prompt); maps to A2A input_required task state; auto-expires after waiting_expiry seconds (default 10s) | Cyan |
| PROCESSING | Busy handling a task | Yellow |
| DONE | Task completed (auto-clears after 10s) | Blue |
| SHUTTING_DOWN | Graceful shutdown in progress | Red |
Compound Signal Detection
Status transitions rely on multiple signals beyond PTY output patterns, reducing false transitions:
- task_active flag: Reference-counted; incremented on A2A task receipt, decremented on task finalization (completion or failure) and on send error. READY transitions are allowed only when the count reaches 0. If the count is not cleared,
task_protection_timeout(default 30s, configurable per profile) expires the protection automatically. - File locks: Agents holding file locks remain in PROCESSING even if PTY output looks idle, because releasing file locks prematurely could cause conflicts.
- WAITING auto-expiry: WAITING status auto-clears after
waiting_expiryseconds (default 10s) to prevent stale states from blocking other transitions. - Rendered-screen waiting_detection:
waiting_detectionregexes are evaluated against a pyte-backed virtual terminal rather than raw PTY bytes, so cursor-motion overlays (ratatui-style redraws, alt-screen prompts) are resolved before matching. Inspect the rendered screen viaGET /debug/ptywhen tuning profile regexes.
Checking Status Before Sending
For human operators, run synapse list and confirm the target shows READY. For AI/scripts, use synapse list --json or synapse status <target> --json. Also check WORKING_DIR to avoid the working directory mismatch warning:
synapse list --json
# NAME TYPE STATUS PORT CURRENT WORKING_DIR
# my-claude claude READY 8100 - my-project
# gemini gemini PROCESSING 8110 Review code (1m 5s) my-project
# codex codex PROCESSING 8120 Fix tests (30s) other-projectThe CURRENT column shows the active task preview with elapsed time (e.g., Review code (2m 15s)).
For a comprehensive view of a single agent (uptime, current task, recent messages, file locks):
synapse status my-claude # Human-readable
synapse status my-claude --json # Machine-readableWhat Each Status Means for Senders
- READY: Safe to send messages.
- WAITING: Agent needs user input (permission prompt, selection, confirmation). Spawned agents automatically notify their caller when entering WAITING. Callers can approve/deny via
POST /tasks/{id}/permission/approveor/deny. Auto-clears afterwaiting_expiry. - PROCESSING: Busy. Wait, or use
--priority 5for emergency interrupt. - DONE: Recently completed. Will return to READY shortly.
Readiness Gate
Messages sent to an agent that has not yet reached READY for the first time are held for up to 30 seconds (AGENT_READY_TIMEOUT). This prevents messages from being lost during initialization. If the agent does not become ready in time, the API returns HTTP 503 with Retry-After: 5. Priority 5 and reply messages bypass this gate entirely.
Interactive Controls
For humans, synapse list provides keyboard-driven agent management:
| Key | Action |
|---|---|
1-9 | Select agent row directly |
| Up/Down | Navigate agent rows |
Enter or j | Jump to selected agent's terminal |
k | Kill selected agent (with confirmation) |
/ | Filter by TYPE, NAME, or WORKING_DIR |
ESC | Clear filter first, then clear selection |
q | Quit |
Supported Terminals
- iTerm2 (macOS) -- switches to the correct tab/pane
- Terminal.app (macOS) -- switches to the correct tab
- Ghostty (macOS) -- activates the application. Targets the focused tab, so avoid switching tabs during spawn.
- VS Code integrated terminal -- brings the application/window to the front; does not switch the integrated terminal or change WORKING_DIR
- tmux -- switches to the agent's session
- Zellij -- activates the terminal app (direct pane focus not supported via CLI)
Terminal jump is especially useful when an agent shows WAITING status -- jump to its terminal to respond to the selection prompt.
Spawning Reference
Spawning is sub-agent delegation. The parent spawns child agents to offload subtasks, preserving its own context window for the main task. The parent always owns the full lifecycle: spawn, send task, evaluate result, kill.
Why Spawn
- Context preservation -- offloading a subtask keeps the parent's context window focused on the primary goal.
- Parallel execution -- independent subtasks run simultaneously, cutting total wall-clock time.
- Specialist precision -- a dedicated role (e.g., "test writer") produces higher-quality results than a generalist handling everything.
When to Spawn vs. Subagent vs. Self
Call analyze_task first — it returns a delegation_strategy recommendation.
| Situation | Action | Why |
|---|---|---|
| ≤3 files, ≤100 lines, 1 directory | Do it yourself (strategy: "self") | No overhead, fastest path |
| 4-8 files, ≤2 dirs, Claude/Codex agent | Use built-in subagent (strategy: "subagent") | Same-process, context shared, no startup cost |
| Another agent is already running and READY | `synapse send` to existing agent | Reusing avoids startup cost, instruction injection, and readiness wait |
| 9+ files, 3+ dirs, or different model needed | `synapse spawn` a new agent (strategy: "spawn") | Offloads work, different model perspective, rate-limit distribution |
| Task has independent parallel subtasks | `synapse team start` N agents | Proper tile layout; each agent focuses on one subtask |
Subagent vs. Synapse spawn:
- Subagent (Claude Code Agent tool / Codex subprocess): same process, same model, shared context, low cost. Use for medium-scope work that doesn't need a different perspective.
- Synapse spawn: separate process, different model possible, file isolation via --worktree. Use for large scope, cross-model review, or rate-limit distribution.
- Only Claude Code and Codex have subagent capability. Gemini, OpenCode, Copilot always use Synapse spawn.
Rule of thumb: Spawn when delegating would be faster, more precise, or prevent your context from being consumed by a large subtask.
How Many Agents
1. User-specified count -- follow it exactly (top priority). 2. No user specification -- the parent analyzes the task and decides:
- Single focused subtask: 1 agent.
- Independent parallel subtasks: N specialists (one per subtask).
- The parent assigns a name and role to each spawned agent.
Spawn Lifecycle
Parent receives task
|
+-- User-specified agent count? --> Use that count ----+
| |
+-- No specification? --> Parent decides count & roles-+
|
v
spawn child(ren)
|
v
send task <-----------+
| |
v |
evaluate result |
| |
+- Sufficient? -> kill |
| |
+- Insufficient? ------+Basic Example — use `--task-file` for the first task
⚠️ Reality check: synapse spawn takes several minutes to reach READY for most profiles (CLI init + MCP bootstrap + PTY stabilization). Polling every second for 30 seconds is too short and will almost always time out. Let synapse spawn handle the readiness wait for you instead — it has a built-in --task / --task-file / --task-timeout combo that spawns the agent, waits for READY, and sends the first task in one command.
✅ Recommended pattern (use this):
# 1. Spawn and send the first task in one command.
# --task-timeout gives spawn up to 600s (10 min) to wait for the agent
# to register before sending the initial task. --notify returns control
# immediately and delivers the completion via an async A2A message.
synapse spawn gemini \
--name Tester \
--role "test writer" \
--task-file /tmp/tester-spec.md \
--task-timeout 600 \
--notify
# 2. Do other work. When Tester finishes, you receive an A2A notification
# with the result. No polling needed.
# 3. Refine if the first reply is insufficient (agent retains its session
# context, so just send a follow-up message — do NOT kill and re-spawn).
synapse send Tester "Add edge-case tests for expired tokens" --notify
# 4. Kill when done -- frees ports, memory, PTY sessions, and prevents orphaned agents
synapse kill Tester -fWhy `--task-file` instead of inline `--task`: the spec / first-task prompt is often long, contains backticks or $ that the shell would expand, or has newlines. Put the prompt in a file and pass --task-file — it avoids every shell-expansion trap.
Send mode cheat sheet:
| Flag | When to use |
|---|---|
--notify (default) | Most cases. Parent returns immediately, gets an async A2A notification when the agent finishes. Parent can do other work in the meantime. |
--wait | Only when the parent cannot make progress without the reply (e.g., the agent's answer is the next function argument). Blocks the parent until the agent replies. |
--silent | Fire-and-forget. No completion notification. Use for side-effect-only instructions and one-way announcements. |
$SYNAPSE_AGENT_ID is set automatically by Synapse at startup (e.g., synapse-claude-8100). The --from flag is auto-detected from this env var, so you can usually omit it. In headless sessions, startup/setup logs are routed to the per-agent log file before PTY handoff, so a quiet terminal during spawn is expected.
Legacy pattern (avoid — kept for reference)
If you cannot use --task (e.g., you need to send multiple messages sequentially with very different readiness requirements), the old two-step pattern still works, but give it enough time:
# 1. Spawn (returns immediately with agent_id)
synapse spawn gemini --name Tester --role "test writer"
# 2. Poll for readiness -- allow several MINUTES, not seconds.
# Agents commonly take 60-300 seconds to reach READY.
elapsed=0
while ! synapse status Tester --json 2>/dev/null | grep -Eq '"status"[[:space:]]*:[[:space:]]*"READY"'; do
sleep 5; elapsed=$((elapsed + 5))
[ "$elapsed" -ge 600 ] && echo "ERROR: Tester not READY after ${elapsed}s" >&2 && exit 1
done
# 3. Send the task
synapse send Tester "Write unit tests for src/auth.py" --notifyCommon pitfall: sending to an agent that is still initializing will either hang at the /tasks/send HTTP call (PTY write blocks while the CLI is starting up) or get blocked behind the internal "wait until READY" logic. Always confirm READY before synapse send, or use --task-file on synapse spawn which handles this for you.
Evaluating Results
After receiving a --wait reply from a spawned agent:
1. Read the reply content -- does it address what you asked? 2. Verify artifacts if needed -- run git diff, pytest, or read modified files to confirm the work. 3. Decide next step:
- Result is sufficient:
synapse kill <child> -f - Result is insufficient: re-send with refined instructions (do NOT kill and re-spawn; the agent retains context from the previous attempt)
Mandatory Cleanup
Killing spawned agents after completion frees ports, memory, and PTY sessions, and prevents orphaned agents from accidentally accepting future tasks.
synapse kill <spawned-agent-name> -f
synapse list --json # Verify the agent is goneAuto-Approve (Automatic)
Since v0.17.16, synapse spawn and synapse team start automatically inject the appropriate CLI permission bypass flag for each agent profile. You no longer need to pass -- <flags> manually.
| CLI | Auto-injected Flag | Notes |
|---|---|---|
| Claude Code | --permission-mode=auto | Anthropic's documented successor to the deprecated --dangerously-skip-permissions. Safety classifier active. Requires Max/Team/Enterprise/API plan + Sonnet 4.6 / Opus 4.6+. |
| Gemini CLI | --approval-mode=yolo | Unified --approval-mode form preferred over the legacy --yolo / -y. |
| Codex CLI | -cdefault_permissions=":workspace" | Selects the built-in :workspace permission profile (workspace-write equivalent of the legacy --full-auto). Codex 0.128+ removed --full-auto; the legacy flag is still recognised by Synapse as a skip-injection trigger. |
| Copilot CLI | --allow-all | --yolo is an alias and still recognized. |
| OpenCode | env OPENCODE_DANGEROUSLY_SKIP_PERMISSIONS=true | OpenCode has no CLI flag; uses env var. |
To disable auto-approve: synapse spawn claude --no-auto-approve
Runtime safety: if an agent hits a permission prompt despite the CLI flag, the controller detects WAITING status and auto-sends the approval response.
For full details, see docs/agent-permission-modes.md.
CLI and API
CLI
# Single agent (auto-approve flags injected automatically)
synapse spawn claude # Spawn in new pane
synapse spawn gemini --port 8115 # Explicit port
synapse spawn claude --name Reviewer --role "code review" --skill-set dev-set
synapse spawn claude --worktree # Spawn in isolated worktree
synapse spawn claude -w my-feature # Named worktree
synapse spawn claude --no-auto-approve # Disable auto-approve
synapse spawn sharp-checker # Spawn by saved Agent ID
# Spawn + send first task in ONE command (preferred for delegation)
synapse spawn codex \
--name Fixer \
--role "bug fixer" \
--task-file /tmp/bug-spec.md \
--task-timeout 600 \
--notify
# Spawn + inline task (only for short prompts; prefer --task-file)
synapse spawn gemini --name Searcher --task "Search for TODO comments in src/"
# Spawn + task + worktree isolation (common for code-generation work)
synapse spawn codex \
--name Feature \
--worktree feature-auth \
--branch main \
--task-file /tmp/feature-spec.md \
--task-timeout 900 \
--notify
# Multiple agents — use team start for proper tile layout
synapse team start claude gemini codex # Mixed team (each gets its own auto-approve flag)
synapse team start claude:Reviewer gemini:Searcher # With names
synapse team start claude gemini --worktree # Each in isolated worktree
synapse team start claude gemini --no-auto-approve # Disable auto-approve for allKey options for the spawn + task combo:
| Option | Purpose |
|---|---|
--task TASK | Inline first-task prompt. Use for short one-liners. |
--task-file PATH | Read the first-task prompt from a file. Preferred for long prompts, multi-line specs, or anything containing shell-special characters (` `, $, "`). |
--task-timeout N | Seconds to wait for the agent to reach READY before giving up on the initial task. Default is 30s which is almost always too short. Set 300-900 for real-world agents. |
--wait / --notify / --silent | Same meaning as synapse send. --notify is default and correct for most delegation. |
Spawn via API
Agents can spawn other agents programmatically via POST /spawn:
// Basic spawn
{"profile": "gemini", "name": "Helper", "skill_set": "dev-set", "tool_args": ["--approval-mode=yolo"]}
// With worktree isolation
{"profile": "gemini", "name": "Worker", "worktree": true}
{"profile": "claude", "name": "Worker", "worktree": "my-feature"}
// Claude with auto permission mode (was --dangerously-skip-permissions)
{"profile": "claude", "name": "Worker", "tool_args": ["--permission-mode=auto"]}
// Codex with auto-approve (Codex 0.128+ replaced --full-auto with the :workspace permission profile)
{"profile": "codex", "name": "Coder", "tool_args": ["-cdefault_permissions=\":workspace\""]}
// On failure: {"status": "failed", "reason": "..."}
// On success: {agent_id, port, terminal_used, status, worktree_path, worktree_branch, worktree_base_branch}Team Start
synapse team start claude gemini # claude=current terminal, gemini=new pane
synapse team start claude gemini codex --layout horizontal
synapse team start claude gemini --all-new # All agents in new panes
synapse team start claude gemini --worktree # Each agent in its own worktree
synapse team start claude gemini codex -w my-feature # Named prefix: my-feature-claude-0, etc.
synapse team start claude gemini --no-auto-approve # Disable auto-approveTeam Start via API (POST /team/start):
{"agents": ["gemini", "codex"], "layout": "split"}Worktree Isolation
--worktree / -w is a Synapse-level flag that creates an isolated git worktree for each agent. It works for all agent types and is placed before -- (not as a tool arg). Each worktree is created under .synapse/worktrees/<name>/ with a branch named worktree-<name>.
When to Use Worktrees
| Situation | Action |
|---|---|
| Multiple agents may edit the same files | Use --worktree to avoid conflicts |
| Coordinator + Worker pattern (Worker edits code) | Worker gets --worktree |
| Read-only tasks (investigation, analysis, review) | Worktree not needed |
| Single agent working alone | Worktree not needed |
Usage
# Auto-generated worktree name
synapse spawn claude --name Impl --role "implementer" --worktree
synapse spawn gemini --name Analyst --role "analyzer" -w
# Named worktree (creates .synapse/worktrees/feat-auth/ with branch worktree-feat-auth)
synapse spawn claude --name Impl --role "implementer" --worktree feat-auth
# Team start with worktree per agent
synapse team start claude gemini --worktree
synapse team start claude gemini codex -w my-featureIndicators and Environment
Agents running in worktrees show a [WT] prefix in the WORKING_DIR column of synapse list.
Environment variables set automatically for worktree agents:
| Variable | Description |
|---|---|
SYNAPSE_WORKTREE_PATH | Absolute path to the worktree directory |
SYNAPSE_WORKTREE_BRANCH | Branch name of the worktree |
SYNAPSE_WORKTREE_BASE_BRANCH | Base branch the worktree was created from (e.g., origin/main). Used for change detection during cleanup. Determined via 3-step fallback: git symbolic-ref -> origin/main -> HEAD. |
Caveats
--worktreeis a Synapse flag -- place it before--. Placing it after--triggers a warning because it would be passed to the underlying CLI as a tool arg instead..gitignore-listed files (.env,.venv/,node_modules/) are not copied to the worktree. Runuv sync,npm install, or copy.envmanually if needed.- On exit: worktrees with no uncommitted changes and no new commits (vs. the base branch) are auto-deleted; worktrees with changes prompt to keep or remove.
synapse killalso handles worktree cleanup for killed agents.- Consider adding
.synapse/worktrees/to your.gitignoreto prevent untracked worktree files from clutteringgit status.
Spawn Zone Tiling (tmux)
synapse spawn uses layout="auto" by default. In tmux this enables spawn zone tiling — spawned panes are tracked and subsequent splits target the largest pane in the zone, producing balanced layouts automatically.
How it works:
1. First spawn (no existing spawn zone): splits the current pane horizontally (-h), creating a side-by-side layout. 2. Subsequent spawns: Synapse queries all panes in the spawn zone, finds the largest one (by area = width x height), and splits it. The split direction is chosen automatically (horizontal if the pane is wider than tall, vertical otherwise). 3. Tracking: Spawned pane IDs are stored in SYNAPSE_SPAWN_PANES (comma-separated) in the tmux session environment (tmux set-environment / tmux show-environment). This persists across CLI invocations within the same tmux session.
Result: Spawning 1, 2, or 4 agents produces evenly tiled layouts without manual --layout flags.
Other terminals (iTerm2, Ghostty, zellij) have their own auto-alternation logic but do not use the spawn zone mechanism.
Technical Notes
- Headless mode:
synapse spawnandsynapse team startalways add--no-setup --headless, skipping interactive setup while keeping the A2A server and initial instructions active. - Readiness: After spawning, Synapse waits for the agent to register and warns with concrete
synapse sendexamples if not yet ready. At the HTTP level, a Readiness Gate blocks/tasks/senduntil the agent finishes initialization (returns HTTP 503 +Retry-After: 5if not ready within 30s). - Pane titles (tmux): Each spawned tmux pane is labelled with
synapse(<profile>)orsynapse(<profile>:<name>)viatmux select-pane -T. This makes it easy to identify agents when pane border status is enabled (tmux set -g pane-border-status top). - Pane auto-close: Spawned panes close automatically when the agent process terminates (tmux, zellij, iTerm2, Terminal.app, Ghostty).
- Known limitation ([#237](https://github.com/s-hiraoku/synapse-a2a/issues/237)): Spawned agents cannot use
synapse reply(PTY injection does not register sender info). Usesynapse send <target> "message"for bidirectional communication (--fromis auto-detected).
Related skills
How it compares
Pick synapse-a2a when multiple CLI agents must collaborate on one codebase with locks and messaging; use single-agent skills for solo edits.
FAQ
What is synapse-a2a used for?
synapse-a2a teaches Synapse A2A inter-agent communication: synapse send and reply, spawning workers with synapse spawn, shared synapse memory, wiki pages, and synapse file-safety locks during multi-agent development.
Which agents does synapse-a2a support?
synapse-a2a documents spawn and team commands for Claude Code, Codex CLI, Gemini CLI, OpenCode, and GitHub Copilot CLI, each with runtime-specific automation flags like --dangerously-skip-permissions or --full-auto.
How should agents read synapse-a2a status programmatically?
synapse-a2a recommends synapse list --json, synapse status <target> --json, or the MCP list_agents tool instead of interactive synapse list when coding agents automate orchestration workflows.