feat(backends): add Herdr crew pane workspaces - #1
Conversation
A home that writes `crew` (or `crew:<n>`) into config/herdr-presentation-spaces keeps the Firstmate agent alone in its workspace and places every crewmate or scout as a split pane in one durable per-home crew workspace, created on first use right after the home's workspace. The default cap of six panes forms an even 3x2 grid, filled top row first; a full tab overflows to a new tab in the same crew workspace. Split ratios are evened out with layout.set_split_ratio after every placement and crew pane cleanup, never layout.apply. Placement runs under the session presentation lock with focus preserved, reuses a recorded crew workspace only while its id and label both still match, refuses a live same-labeled pane, and replaces an exited husk only after its successor exists. Cleanup closes the exact pane through the existing focus-safe kill path, so the workspace goes with its last pane. list-live and bare-selector resolution find crew panes, and a reclaim of a gone endpoint follows the same setting. Secondmates keep their placement.
…kspace A crew workspace now holds at most the pane cap (6 by default) in its single tab. When every recorded crew workspace is full, the next task becomes the first pane of a new crew workspace ordered right after the last one, instead of a new tab inside the full workspace. A freed slot in an earlier crew workspace is still refilled before another one opens, and each crew workspace disappears with its last pane. The per-session record now lists every crew workspace id, each still re-verified by exact id and crew label before reuse, and list-live scans every crew-labeled workspace.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b8d1cad192
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| done < <(fm_backend_herdr_cli "$session" workspace list 2>/dev/null | jq -r --arg want "$(fm_backend_herdr_crew_workspace_label)" \ | ||
| '.result.workspaces[]? | select(.label == $want) | .workspace_id' 2>/dev/null) |
There was a problem hiding this comment.
Restrict list-live to recorded crew workspace IDs
When two Firstmate homes share a Herdr session, both can legitimately have workspaces labeled firstmate-crew, but this scan selects every workspace with that label rather than intersecting with the current home's state/.herdr-crew-workspace-<session> record. Consequently, one home's recovery/list-live output includes another home's task panes; use the recorded, live-verified workspace IDs here to preserve home isolation.
Useful? React with 👍 / 👎.
| count=$(printf '%s' "$panes" | jq -r '.result.panes | length' 2>/dev/null) | ||
| if [ -z "$wsid" ] && [ "${count:-0}" -gt 0 ] && [ "$count" -lt "$cap" ]; then | ||
| wsid=$ws |
There was a problem hiding this comment.
Reuse the husk's slot before creating an overflow workspace
When a same-labeled agent-free husk is in a crew workspace already at the pane cap, this count includes the husk and rejects that workspace as full. The function then creates a new overflow workspace before closing the husk, leaving the original workspace under capacity and the replacement isolated in a new workspace; repeated full-grid reclaims fragment the crew layout. Treat a workspace containing the replaceable husk as having a replacement slot while preserving the create-before-close guarantee.
Useful? React with 👍 / 👎.
Intent
The requester's words (2026-09-24): "Is it possible to open new mates in panes instead of new workspaces in herdr? I'd kinda like to have one workspace with just you and then a workspace with all the mates their worktrees in panes. Is that possible? It's hard to track everything when there are like 6 or 7 mates spread out". Then: "wait for the fork. The tab version is just another version of the same problem imo". Then: "I'd rather fork firstmate then send Kun Chen an unsolicited PR... I like the idea of spinning it up in a fork and trying it out. If it works well I could toss it at the upstream as an issue or discussion note." Then: "you've convinced me. Make it happen". Then (2026-09-24): "get the mate working on the fork to max it out at 6 panes. I'm running and ultrawide monitor. I've got space" Then: "stack them in a 3x3 grid", corrected to "sorry I meant 2x3" (3 across, 2 high, 6 panes).
Context: Firstmate's Herdr adapter currently supports two layouts (docs/herdr-backend.md). One is presentation spaces, on by default at Herdr >= 0.8.0: each task gets its own disposable workspace, which gives the requester 6-7 workspaces. The other is
config/herdr-presentation-spaces=off: each task becomes a tab in the launcher's own workspace. The requester rejected tabs as the same problem. The requester wants the firstmate agent alone in its workspace, and ONE separate crew workspace in which every live crewmate/scout is a split PANE, so all mates are visible side by side. The running Herdr is 0.9.1. This work lives in the requester's fork Profreshor/firstmate (this project clone;upstream= kunchenguid/firstmate is fetch-only). Nothing goes to upstream. Then (2026-09-24): "a 7th mate can open a new workspace".What Changed
crewHerdr layout, placing tasks in shared split-pane crew workspaces with a six-pane cap before opening another workspace.Risk Assessment
🚨 High, reviewed and accepted: crew mode is intentionally prospective-only (see Review decisions).
Review decisions
crew:<n>stays as a simple pane-cap setting. The defaultcrewgives six panes in a 3-across, 2-high grid, which matches the request.Testing
Ran the guarded isolated Herdr lab E2E twice against Herdr 0.9.1/protocol 22: standard crew placement and a scout-route variant. Both exercised live pane geometry, overflow, cleanup, real spawn/teardown, and lab teardown; CLI transcripts are attached. The headless terminal lab has no reviewer-visible rendered terminal surface, so live Herdr layout and lifecycle output is the evidence. Worktree remained clean.
Evidence: Real Herdr crew workspace E2E transcript
Source: Real Herdr crew workspace E2E transcript
Evidence: Real Herdr scout-route crew E2E transcript
Source: Real Herdr scout-route crew E2E transcript
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
bin/fm-spawn.sh:3616- The intent requires “ONE separate crew workspace in which every live crewmate/scout is a split PANE,” but this new crew branch only places newly spawned tasks; an already-live task remains in its prior workspace after enablingcrew(the docs likewise limit it to new tasks/reclaims). Decide whether crew mode is intentionally prospective-only or must migrate/restart existing live mates; the latter needs new lifecycle behavior.✅ **Test** - passed
✅ No issues found.
bash tests/fm-backend-herdr-crew-workspace-e2e.test.shsed … tests/fm-backend-herdr-crew-workspace-e2e.test.sh | bash(same guarded E2E with one real--scoutspawn; no worktree changes)git status --short✅ **Document** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.