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) <noreply@anthropic.com>
This commit is contained in:
Matt Pocock
2026-07-23 10:37:53 +01:00
co-authored by Claude Opus 4.8
parent 9c32629965
commit fc73c04a34
5 changed files with 70 additions and 23 deletions
@@ -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 "<descriptive name>" "<handoff summary>"`. 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.
@@ -1,5 +0,0 @@
interface:
display_name: "Claude Handoff"
short_description: "Hand off to a background agent"
policy:
allow_implicit_invocation: false
+23
View File
@@ -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 <this skill's base directory>/spawn.sh <claude|codex> "<descriptive session name>" - <<'PROMPT'
<handoff summary>
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.
@@ -0,0 +1,5 @@
interface:
display_name: "Spawn"
short_description: "Hand off to a background agent (claude or codex)"
policy:
allow_implicit_invocation: false
+42
View File
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# spawn.sh <claude|codex> <name> [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 <claude|codex> <name> [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