mirror of
https://github.com/mattpocock/skills.git
synced 2026-07-29 02:52:42 +07:00
feat(spawn): default to the running agent; herdr-first management, no nohup
Six agents (claude, codex, pi, cursor, opencode, copilot). claude keeps its native --bg/agents management. Everything else spawns interactively inside herdr when its server is up (list/read/send/attach); otherwise a transient systemd --user unit gives status/logs/stop. Research confirmed none of the five non-claude CLIs has a native background job manager. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
fc73c04a34
commit
085d886fca
@@ -1,19 +1,19 @@
|
||||
---
|
||||
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?"
|
||||
description: Hand the current conversation off to a fresh background agent that picks up the work immediately.
|
||||
argument-hint: "[agent] 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'
|
||||
bash <this skill's base directory>/spawn.sh <agent> "<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.
|
||||
`<agent>` is one of `claude | codex | pi | cursor | opencode | copilot`. Spawn the agent you are running as, unless the user named another. The agent starts in the current working directory; the script prints how the user monitors and manages the session — relay that.
|
||||
|
||||
The handoff summary:
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# spawn.sh <claude|codex> <name> [prompt|-]
|
||||
# spawn.sh <agent> <name> [prompt|-]
|
||||
# Launches a background agent session seeded with the prompt.
|
||||
# Prompt is read from stdin when the third argument is omitted or '-'.
|
||||
#
|
||||
# claude has native managed background jobs (claude --bg / claude agents).
|
||||
# Every other agent is spawned interactively inside herdr when its server is
|
||||
# running (list/read/send/attach management); otherwise as a supervised
|
||||
# one-shot under the user's systemd session (status/logs/stop management).
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
echo "usage: spawn.sh <claude|codex> <name> [prompt|-] (prompt read from stdin when omitted or '-')" >&2
|
||||
echo "usage: spawn.sh <claude|codex|pi|cursor|opencode|copilot> <name> [prompt|-]" >&2
|
||||
echo " prompt is read from stdin when omitted or '-'" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
@@ -19,24 +25,67 @@ if [ "$prompt" = "-" ]; then
|
||||
fi
|
||||
[ -n "$prompt" ] || { echo "spawn.sh: empty prompt" >&2; exit 2; }
|
||||
|
||||
case "$agent" in
|
||||
claude)
|
||||
if [ "$agent" = "claude" ]; then
|
||||
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
|
||||
;;
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Interactive invocation, seeded with the prompt — used inside herdr panes.
|
||||
case "$agent" in
|
||||
codex) interactive=(codex "$prompt") ;;
|
||||
pi) interactive=(pi "$prompt") ;;
|
||||
cursor) interactive=(cursor-agent "$prompt") ;;
|
||||
opencode) interactive=(opencode --prompt "$prompt") ;;
|
||||
copilot) interactive=(copilot -i "$prompt") ;;
|
||||
*) usage ;;
|
||||
esac
|
||||
|
||||
if herdr agent list >/dev/null 2>&1; then
|
||||
herdr agent start "$name" --cwd "$PWD" --no-focus -- "${interactive[@]}"
|
||||
echo "Spawned $agent session '$name' in herdr."
|
||||
echo " list: herdr agent list"
|
||||
echo " read: herdr agent read '$name'"
|
||||
echo " steer: herdr agent send '$name' '<text>'"
|
||||
echo " attach: herdr agent attach '$name'"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
command -v systemd-run >/dev/null 2>&1 || {
|
||||
echo "spawn.sh: no herdr server running and systemd-run unavailable — launch herdr and retry" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Non-interactive one-shot — flags keep the run from blocking on approvals.
|
||||
case "$agent" in
|
||||
codex) oneshot=(codex exec --sandbox workspace-write --skip-git-repo-check "$prompt") ;;
|
||||
pi) oneshot=(pi -p "$prompt") ;;
|
||||
cursor) oneshot=(cursor-agent -p --force --output-format text "$prompt") ;;
|
||||
opencode) oneshot=(opencode run --title "$name" "$prompt") ;;
|
||||
copilot) oneshot=(copilot -p "$prompt" --allow-all-tools) ;;
|
||||
esac
|
||||
|
||||
# The systemd user manager doesn't inherit this shell's PATH; resolve the
|
||||
# binary now and pass PATH through for any children it spawns.
|
||||
bin="$(command -v "${oneshot[0]}")" || {
|
||||
echo "spawn.sh: ${oneshot[0]} is not installed" >&2
|
||||
exit 1
|
||||
}
|
||||
oneshot[0]="$bin"
|
||||
|
||||
slug="$(printf '%s' "$name" | tr '[:upper:] ' '[:lower:]-' | tr -cd 'a-z0-9-')"
|
||||
unit="spawn-${slug:-session}-$(date +%H%M%S)"
|
||||
systemd-run --user --unit "$unit" --working-directory="$PWD" \
|
||||
--setenv=PATH="$PATH" --setenv=HOME="$HOME" "${oneshot[@]}" >/dev/null 2>&1
|
||||
|
||||
echo "Spawned $agent session '$name' as user unit $unit (no herdr server running)."
|
||||
echo " status: systemctl --user status $unit"
|
||||
echo " logs: journalctl --user -u $unit -f"
|
||||
echo " stop: systemctl --user stop $unit"
|
||||
case "$agent" in
|
||||
codex) echo " resume: codex exec resume <session id from logs>" ;;
|
||||
pi) echo " resume: pi -c (from this directory)" ;;
|
||||
cursor) echo " resume: cursor-agent resume" ;;
|
||||
opencode) echo " resume: opencode run -c (or: opencode session list)" ;;
|
||||
copilot) echo " resume: copilot --resume" ;;
|
||||
esac
|
||||
|
||||
Reference in New Issue
Block a user