Add herdr-spawn plugin: spawn a briefed agent in another project #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "add-project-agent-spawn"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Turns "spawn an agent in the Y project to work on X" into one command.
Resolves the project against configured globs, fetches
origin/main, creates an unfocused worktree workspace based on it, starts a Claude agent, and hands off the brief over herdr-mail — so the new agent gets a working reply address for free.What's here
herdr-spawn/bin/spawnbin/mail's idiomherdr-spawn/skill/SKILL.mdherdr-spawn/README.mdherdr-spawn/herdr-plugin.tomlopenspec/specs/agent-spawn-*/herdr-mail is unchanged. Cross-workspace unicast (
--to pane:<id>) already worked — the delivery handler's pane lookup has no workspace filter.Decisions worth reviewing
The source checkout is never mutated. The obvious reading of "switch to main, pull latest" would
git checkout main && git pullin the source repo — which may be dirty, or have another agent actively working in it. Instead freshness comes fromgit fetch origin mainplusworktree create --base origin/main. Accepted trade: your localmainstays stale until you pull it yourself; worktree branches are always current.Ambiguous project names are an error, never a guess. Two collisions exist today (
build-your-own-internet,playwright-msware in both~/devand~/hobby). Spawn lists the candidates and stops.spawn doctorfinds them up front. Silently picking one would eventually create a branch in the wrong repository.The recipient's phone mode is left alone. Pre-setting
interruptwould inject the full brief, but phone mode deliberately belongs to the recipient. Tested instead of assumed: the defaultnotifydoorbell is enough — the spawned agent read it unprompted and started work.Not an
[[actions]]surface. Plugin actions are invoked with no arguments, and this verb is inherently parameterized, so it's a CLI — same shape as herdr-mail'ssend/read/reply. The manifest exists soherdr plugin linkregisters it, which is also howbin/spawnlocatesbin/mailat runtime (neither is on$PATH, and baremailon macOS is BSD mailx).Documented trap
A spawned agent that finishes its turn settles into
done, notidle. This cost 90s during the spike; it's now a requirement in the spec and a table row in the skill.Verification
spawn selftest.git-as-file, non-repo dirspawn doctorstatus --porcelainbyte-identical — and dirty throughoutorigin/mainAlso verified separately that
git fetch origin mainreally does refreshrefs/remotes/origin/main(not justFETCH_HEAD), since--base origin/maindepends on it.v1 limits
worktree removeleaves the branch behind.--kindis not plumbed through yet.originandmain. Other default branches fail at the fetch step rather than guessing.Full rationale, alternatives considered, and spike evidence:
openspec/changes/archive/2026-07-31-add-project-agent-spawn/design.md.🤖 Generated with Claude Code
One command turns a project name, a slug, and a brief into a working agent in its own herdr workspace, on its own branch, off the latest origin/main. spawn new celilo fix-dns "Fix public DNS source IP" "<brief>" Resolves the project against configured globs (default ~/dev/* and ~/hobby/*), fetches origin/main, creates an unfocused worktree workspace based on it, starts a Claude agent, and hands off the brief over herdr-mail so the new agent gets a working reply address for free. Notable decisions: - The source checkout is never mutated. Freshness comes from `git fetch` plus `worktree create --base origin/main`, not checkout/pull, because the source checkout may be dirty or have another agent working in it. Verified: HEAD, branch, index and porcelain status are byte-identical across a spawn. - Ambiguous project names are an error listing candidates, never a guess. `spawn doctor` reports collisions up front (two exist today). - The recipient's herdr-mail phone mode is left alone. The default notify doorbell is enough to start the new agent, and the mode belongs to the recipient. - Not an [[actions]] surface: plugin actions take no arguments, so the verb is a CLI, like herdr-mail's send/read/reply. - herdr-mail is unchanged. Cross-workspace unicast already worked. Documented trap: `herdr agent wait <pane> --until idle` times out on a spawned agent, which settles into `done`. Use bare `herdr agent wait`. Verified end to end: 4.3s from command to briefed agent; it read the doorbell unprompted, did the work, and replied cross-workspace. Torn down clean. Change archived at openspec/changes/archive/2026-07-31-add-project-agent-spawn/ with specs synced to openspec/specs/ (3 capabilities, 15 requirements, 35 scenarios). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>