Skip to main content

sessions

Understand the Synapse Claude Code plugin hooks, session lifecycle, and multi-agent parallel execution. Covers what each hook does, where plugin state lives, and how to run multiple experiments in parallel via Task sub-agents.

ソース情報

リポジトリ
Vincentwei1021/Synapse
ソースの最終更新活動
2026年5月21日 09:55
検出された SKILL.md の言語
英語
スター
40
フォーク
4

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
sessions
description
Understand the Synapse Claude Code plugin hooks, session lifecycle, and multi-agent parallel execution. Covers what each hook does, where plugin state lives, and how to run multiple experiments in parallel via Task sub-agents.
license
AGPL-3.0
metadata
{"author":"Vincentwei1021","version":"0.6.1","category":"research","mcp_server":"synapse"}
# Sessions Skill Use this skill when the task is about how the Synapse plugin itself behaves inside Claude Code: which hooks fire, what they inject into context, how sub-agent sessions are managed, and how to dispatch multiple experiments in parallel to Task sub-agents. ## Prompt Boundary Stay inside this skill when the work is about: - understanding why Synapse context appeared in the session (which hook injected it) - debugging a sub-agent that is not behaving as expected (session, heartbeat, or teardown issue) - deciding how a main agent should dispatch parallel experiment work across sub-agents - deciding when to call `synapse_create_session` / `synapse_close_session` directly instead of relying on hooks Hand off to: - **[experiments](../experiments/SKILL.md)** for the actual work inside one experiment - **[autonomy](../autonomy/SKILL.md)** for the CC-client autonomous loop ## Core Rule For sub-agents spawned through the Task tool, sessions are fully automatic. Do not manually call `synapse_create_session` or `synapse_close_session` for a sub-agent unless you are debugging the lifecycle itself. The `SubagentStart` and `SubagentStop` hooks already do it. ## Plugin Hooks At A Glance The plugin ships ten hooks wired up in `hooks/hooks.json`. Each reads/writes local state under `.synapse/` in the project and, when needed, calls Synapse MCP tools via the bundled `synapse-api.sh` wrapper. | Hook script | Claude Code event | What it does | State touched | MCP calls | |---|---|---|---|---| | `on-session-start.sh` | `SessionStart` (`startup` \| `resume` \| `compact`) | Calls `synapse_checkin`, caches owner / roles / project UUID into `state.json`, scans for pre-assigned sub-agent session files, and builds the rich `additionalContext` block that orients the agent on assignments, projects, and workflow. | `state.json`, reads `sessions/*.json` | `synapse_checkin`, optional `synapse_session_heartbeat` | | `on-user-prompt.sh` | `UserPromptSubmit` | Fast local-only check on every user turn. Scans `.synapse/sessions/` and injects a brief reminder that sub-agent sessions are auto-managed. No network calls (stays under 100 ms). | reads `sessions/` | none | | `on-pre-enter-plan.sh` | `PreToolUse` (`EnterPlanMode`) | Injects planning-mode guidance: prefer the current Experiment pipeline (`draft → pending_review → pending_start → in_progress → completed`), plan one independent run per experiment card, do not plan to create sessions manually. | none | none | | `on-pre-exit-plan.sh` | `PreToolUse` (`ExitPlanMode`) | Reminds the agent to verify that the plan is expressed as Experiment records before executing. | none | none | | `on-pre-spawn-agent.sh` | `PreToolUse` (`Task`) | Before a sub-agent is spawned, atomically writes `.synapse/pending/{name}` with the agent name and type so the `SubagentStart` hook can claim it. Skips read-only sub-agent types. | writes `pending/{name}` | none | | `on-subagent-start.sh` | `SubagentStart` | Atomically claims the pending file via `mv`, then either reuses an active session, reopens a closed one, or creates a new one via `synapse_list_sessions` / `synapse_reopen_session` / `synapse_create_session`. Writes `sessions/{name}.json`, stores the mapping in `state.json`, and injects the session UUID plus the execution workflow directly into the sub-agent's context. | `state.json`, `sessions/{name}.json`, `claimed/{agent_id}` | `synapse_list_sessions`, `synapse_create_session`, `synapse_reopen_session`, `synapse_session_heartbeat` | | `on-teammate-idle.sh` | `TeammateIdle` | When a teammate sub-agent idles between turns, sends a heartbeat so its Synapse session does not auto-time-out after 1 hour. Output suppressed — this fires too often to notify the user. | reads `state.json` | `synapse_session_heartbeat` | | `on-subagent-stop.sh` | `SubagentStop` | Looks up the session UUID, calls `synapse_close_session`, and cleans up `state.json`, `sessions/{name}.json`, and `claimed/{agent_id}`. | deletes state entries, `sessions/{name}.json`, `claimed/{agent_id}` | `synapse_close_session` | | `on-task-completed.sh` | `TaskCompleted` | Scans the completed task description/subject for a `synapse:experiment:<uuid>` marker. If found, injects a reminder to finalize the experiment with `synapse_submit_experiment_results` (or report progress if still running). | reads task metadata only | none | | `on-session-end.sh` | `SessionEnd` | Safety-checked cleanup. Removes `.synapse/` only when all sub-agent sessions are closed and `state.json` has no meaningful content left. | deletes `.synapse/` if safe | none | ## Local State Layout The plugin keeps per-project state under `.synapse/` in the project working directory: - `state.json` — flock-guarded key/value store. Holds owner info cached from `synapse_checkin`, agent roles, the primary project UUID, and the `session_{…}` / `agent_for_session_{…}` / `name_for_agent_{…}` mappings used by the start/stop hooks. - `pending/{name}` — written by `on-pre-spawn-agent.sh`, atomically claimed by `on-subagent-start.sh` via `mv`. - `claimed/{agent_id}` — marker file showing which pending entry was claimed. - `sessions/{name}.json` — per-sub-agent session metadata: `sessionUuid`, `agentId`, `agentName`, `agentType`, `sessionAction`, `createdAt`. Other hooks (idle, stop, user-prompt) read from here to locate the session. `on-session-end.sh` removes `.synapse/` only when it is safe; otherwise state is preserved across sessions so resumed work reconnects to the same Synapse sessions. ## MCP Connection Session vs Synapse Agent Session These are two different things — do not confuse them. - **MCP connection session** — the HTTP-streamable session on `/api/mcp`. Identified by the `mcp-session-id` header, auto-renewed on every request, expires after 30 minutes of inactivity. The plugin handles this transparently. - **Synapse agent session** — a durable record in Synapse of which agent is working on what (the green / yellow / grey indicators on the Settings page). Created/closed by the plugin hooks above, or explicitly by `synapse_create_session` / `synapse_close_session`. ## Session Status Lifecycle ``` active ——(no heartbeat 1h)——> inactive ——(heartbeat)——> active \ \ \—— close ——> closed ——(reopen)——> active ``` | Status | Meaning | |---|---| | `active` | Agent is working. Green indicator. | | `inactive` | No heartbeat in over an hour. Yellow indicator. | | `closed` | Session ended. Grey indicator. Can be reopened. | ## Session Tools | Tool | Purpose | |---|---| | `synapse_list_sessions` | List sessions for the current agent. | | `synapse_get_session` | Read one session's details. | | `synapse_create_session` | Create a named session — usually only needed for direct (non-sub-agent) work. | | `synapse_close_session` | Close a session. | | `synapse_reopen_session` | Reopen a closed session instead of creating a duplicate with the same name. | | `synapse_session_heartbeat` | Keep a session active. Hooks already send heartbeats automatically. | | `synapse_session_checkin_experiment` | Bind a session to a current Experiment. Usually handled by `synapse_start_experiment({ sessionUuid })`. | | `synapse_session_checkout_experiment` | Unbind a session from a current Experiment. Usually handled by `synapse_submit_experiment_results({ sessionUuid })`. | ## Running Multiple Experiments In Parallel When the main agent needs to execute several `pending_start` experiments concurrently, it should **orchestrate, not execute**. The plugin does the heavy lifting for session bookkeeping; the main agent only needs to spawn sub-agents and monitor. ### Main agent: dispatch ```text # 1. Refresh and list what needs to run synapse_checkin() synapse_get_assigned_experiments({ researchProjectUuid, statuses: ["pending_start"] }) # 2. Inspect each candidate synapse_get_experiment({ experimentUuid }) # 3. For each experiment, spawn a Task sub-agent with the experiment UUID in the prompt. # The SubagentStart hook auto-creates/reuses a Synapse session and injects the # execution workflow. The main agent does not need to call synapse_create_session. Task({ subagent_type: "general-purpose", name: "training-worker-<short>", prompt: "Your Synapse experiment UUID: <experiment-uuid>. Run the experiment end to end." }) ``` ### Sub-agent: execute Each sub-agent follows the full execution checklist in **[experiments](../experiments/SKILL.md)**: `synapse_start_experiment({ sessionUuid })` → `synapse_list_compute_nodes` / `synapse_reserve_gpus` → `synapse_get_node_access_bundle` → run remotely (tmux + unbuffered) → `synapse_report_experiment_progress` at milestones → `synapse_submit_experiment_results({ sessionUuid })` → optional `synapse_save_experiment_report`. ### Main agent: monitor The main agent does not block on any one sub-agent. After dispatching all sub-agents, it schedules a single Claude Code `CronCreate` heartbeat that polls Synapse on a cadence — see "Monitoring Long Runs With CronCreate" in the [experiments](../experiments/SKILL.md) skill for the full pattern. The heartbeat prompt should look like: ```text CronCreate({ cron: "*/10 * * * *", prompt: "Check Synapse for project <projectUuid>: synapse_get_assigned_experiments({ researchProjectUuid: '<projectUuid>', statuses: ['in_progress', 'completed'] }). For each still-in-progress experiment, synapse_get_experiment + synapse_report_experiment_progress with the latest tmux/log line. Once all have completed, CronDelete this job.", recurring: true, durable: true, }) ``` Within each fire of the heartbeat, the iteration looks like: ```text synapse_get_assigned_experiments({ researchProjectUuid, statuses: ["in_progress", "completed"] }) # For any experiment still in_progress, read its latest state synapse_get_experiment({ experimentUuid }) # Once all have completed, synthesize. If this is the assigned autonomous-loop # agent, propose follow-ups; otherwise use synapse_create_experiment for # user-directed terminal work. synapse_propose_experiment({ researchProjectUuid, title, description }) ``` `durable: true` keeps the heartbeat alive across CC restarts so cards do not go stale just because the user closed their laptop. Always `CronDelete` once every experiment is `completed` and synthesis has been written. ### Sequential multi-experiment sub-agent A single sub-agent can also handle multiple experiments in order when dependencies matter: ```text Task({ subagent_type: "general-purpose", name: "sequential-worker", prompt: """ Synapse experiments, in order (each depends on the previous): 1. <experiment-uuid-1> — baseline evaluation 2. <experiment-uuid-2> — ablation built on #1's results For each: start_experiment → run → report_progress → submit_results. """ }) ``` ## Project-Level MCP For Sub-Agents Sub-agents only inherit Synapse MCP access if the MCP server is configured at the project level. Put the config in `.mcp.json` at the project root (the plugin bundle ships the template at `public/synapse-plugin/.mcp.json`). User-level-only MCP configs will not reach sub-agents. ## Troubleshooting | Symptom | Likely cause / fix | |---|---| | Sub-agent cannot see Synapse tools | MCP is user-level only. Move `.mcp.json` to the project root. | | Sub-agent session shown as `inactive` | Heartbeat has not fired for 1 h. Usually the sub-agent crashed; respawn with the same name — `SubagentStart` will reopen the existing session instead of making a duplicate. | | Duplicate sessions appear with similar names | A previous sub-agent stopped without the `SubagentStop` hook firing (hard crash). Close stale sessions with `synapse_close_session`, then respawn. | | Main agent did not receive checkin context | `SessionStart` hook failed (check `SYNAPSE_URL`, `SYNAPSE_API_KEY`). Call `synapse_checkin()` manually to recover. | | Experiment stuck in `in_progress` | The sub-agent died before `synapse_submit_experiment_results`. Either resume by respawning the sub-agent with the same experiment UUID, or the main agent calls `synapse_report_experiment_progress` and then `synapse_submit_experiment_results({ outcome: "failure", experimentResults: { error: "..." } })` to close it out. | ## Reference - **[Session and sub-agent reference](../synapse/references/05-session-sub-agent.md)** - **[Experiments skill](../experiments/SKILL.md)** - **[Autonomy skill](../autonomy/SKILL.md)** - **[Common tools](../synapse/references/00-common-tools.md)**
GitHubで見る