From fc73c04a341e4f2e58870b1671c25ed81a2ac9ed Mon Sep 17 00:00:00 2001 From: Matt Pocock Date: Thu, 23 Jul 2026 10:37:53 +0100 Subject: [PATCH] feat(spawn): generalise claude-handoff into agent-agnostic spawn skill SKILL.md now only defines the handoff; per-agent launch mechanics (claude --bg vs backgrounded codex exec) live in a bundled spawn.sh the agent runs but never reads. Prompt arrives via heredoc/stdin so long summaries with quotes survive. Co-Authored-By: Claude Opus 4.8 (1M context) --- skills/in-progress/claude-handoff/SKILL.md | 18 -------- .../claude-handoff/agents/openai.yaml | 5 --- skills/in-progress/spawn/SKILL.md | 23 ++++++++++ skills/in-progress/spawn/agents/openai.yaml | 5 +++ skills/in-progress/spawn/spawn.sh | 42 +++++++++++++++++++ 5 files changed, 70 insertions(+), 23 deletions(-) delete mode 100644 skills/in-progress/claude-handoff/SKILL.md delete mode 100644 skills/in-progress/claude-handoff/agents/openai.yaml create mode 100644 skills/in-progress/spawn/SKILL.md create mode 100644 skills/in-progress/spawn/agents/openai.yaml create mode 100755 skills/in-progress/spawn/spawn.sh diff --git a/skills/in-progress/claude-handoff/SKILL.md b/skills/in-progress/claude-handoff/SKILL.md deleted file mode 100644 index 88ce8be..0000000 --- a/skills/in-progress/claude-handoff/SKILL.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -name: claude-handoff -description: Hand the current conversation off to a fresh background agent that picks up the work immediately. -argument-hint: "What will the next session be used for?" -disable-model-invocation: true ---- - -Write a handoff summary of the current conversation so a fresh agent can continue the work. Instead of saving it, launch a background agent seeded with the summary as its prompt: `claude --bg --name "" ""`. It starts in the current working directory and returns immediately; the user manages it with `claude agents`. - -Always pass `-n`/`--name` with a descriptive name (e.g. `--name "Fix login bug"`) — it sets the display name shown in the job list, session picker, and terminal title. - -Include a "suggested skills" section in the summary, which suggests skills that the agent should invoke. - -Do not duplicate content already captured in other artifacts (PRDs, plans, ADRs, issues, commits, diffs). Reference them by path or URL instead. - -Redact any sensitive information, such as API keys, passwords, or personally identifiable information — the summary becomes the agent's prompt. - -If the user passed arguments, treat them as a description of what the next session will focus on and tailor the summary accordingly. diff --git a/skills/in-progress/claude-handoff/agents/openai.yaml b/skills/in-progress/claude-handoff/agents/openai.yaml deleted file mode 100644 index 0a7aa5d..0000000 --- a/skills/in-progress/claude-handoff/agents/openai.yaml +++ /dev/null @@ -1,5 +0,0 @@ -interface: - display_name: "Claude Handoff" - short_description: "Hand off to a background agent" -policy: - allow_implicit_invocation: false diff --git a/skills/in-progress/spawn/SKILL.md b/skills/in-progress/spawn/SKILL.md new file mode 100644 index 0000000..7e97adc --- /dev/null +++ b/skills/in-progress/spawn/SKILL.md @@ -0,0 +1,23 @@ +--- +name: spawn +description: Hand the current conversation off to a fresh background agent — claude or codex — that picks up the work immediately. +argument-hint: "[claude|codex] What will the next session be used for?" +disable-model-invocation: true +--- + +Write a handoff summary of the current conversation so a fresh agent can continue the work, then spawn the agent with it via the bundled [spawn.sh](spawn.sh) — run it, never read it: + +```bash +bash /spawn.sh "" - <<'PROMPT' + +PROMPT +``` + +Spawn `claude` unless the user named `codex`. The agent starts in the current working directory; the script prints how the user monitors the session — relay that. + +The handoff summary: + +- Include a "suggested skills" section naming skills the agent should invoke. +- Reference artifacts (PRDs, plans, ADRs, issues, commits, diffs) by path or URL instead of duplicating them. +- Redact sensitive information (API keys, passwords, PII) — the summary becomes the agent's prompt. +- If the user passed arguments beyond the agent choice, treat them as what the next session will focus on and tailor the summary accordingly. diff --git a/skills/in-progress/spawn/agents/openai.yaml b/skills/in-progress/spawn/agents/openai.yaml new file mode 100644 index 0000000..34f8fa7 --- /dev/null +++ b/skills/in-progress/spawn/agents/openai.yaml @@ -0,0 +1,5 @@ +interface: + display_name: "Spawn" + short_description: "Hand off to a background agent (claude or codex)" +policy: + allow_implicit_invocation: false diff --git a/skills/in-progress/spawn/spawn.sh b/skills/in-progress/spawn/spawn.sh new file mode 100755 index 0000000..93aad32 --- /dev/null +++ b/skills/in-progress/spawn/spawn.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# spawn.sh [prompt|-] +# Launches a background agent session seeded with the prompt. +# Prompt is read from stdin when the third argument is omitted or '-'. +set -euo pipefail + +usage() { + echo "usage: spawn.sh [prompt|-] (prompt read from stdin when omitted or '-')" >&2 + exit 2 +} + +agent="${1:-}" +name="${2:-}" +prompt="${3:--}" +[ -n "$agent" ] && [ -n "$name" ] || usage + +if [ "$prompt" = "-" ]; then + prompt="$(cat)" +fi +[ -n "$prompt" ] || { echo "spawn.sh: empty prompt" >&2; exit 2; } + +case "$agent" in +claude) + claude --bg --name "$name" "$prompt" + echo "Spawned claude session '$name'. Manage it with: claude agents" + ;; +codex) + slug="$(printf '%s' "$name" | tr '[:upper:] ' '[:lower:]-' | tr -cd 'a-z0-9-')" + dir="${TMPDIR:-/tmp}/codex-spawns" + mkdir -p "$dir" + base="$dir/${slug:-session}-$(date +%Y%m%d-%H%M%S)" + nohup codex exec --sandbox workspace-write --cd "$PWD" \ + -o "$base.last.md" - <<<"$prompt" >"$base.log" 2>&1 & + echo "Spawned codex session '$name' (pid $!)." + echo " log: $base.log" + echo " final answer: $base.last.md" + echo " follow with: tail -f $base.log" + ;; +*) + usage + ;; +esac