Add Manager glyph (◉) to the main-repo herdr tab#38
Merged
Conversation
Extend herdr-tab-glyph.sh's refresh sweep with a second exact-cwd match branch: a tab sitting at the main repo root is the "Manager" hub among the ○ ● ◇ ◆ ✓ task satellites and gets a leading ◉. - Stateless and non-exclusive: ◉ marks the location, so every tab at the main root carries it (documented in the script header) - No new trigger — the existing refresh callers (/status, /list, /close, pr-flow's PR-lifecycle skills) stamp both kinds in one sweep - Prefix only, never replace; ◉ joins the idempotency strip so hub↔task moves swap glyphs cleanly and re-refreshes never stack - The extractor's TSV gains a `kind` column; `key` carries the task name or the repo dir name and is never empty — `IFS=$'\t' read` collapses runs of tabs (tab is IFS whitespace), so an empty middle field would shift every later field left (caught in test: `◉ Manager` became `◉ claude-plugins`) Verified against a stubbed and a live herdr agent list: exact-cwd matching, no-churn guard, subdir/foreign-repo tabs untouched, flag-shaped pane ids rejected. Bump work-system 1.8.0 → 1.8.1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The sidebar renders a herdr tab's LABEL. `refresh` rewrote the agent registry's separate `name` field instead, so every re-stamp since 1.8.0 was invisible: a tab kept its launch-time glyph forever (remove-swarm-composer sat at ● with its PR long in review). Caught by testing the ◉ end-to-end against a live herdr rather than trusting `agent list`. - refresh now joins `herdr agent list` (carries cwd — the match) with `herdr tab list` (carries label — what we prefix and diff), keyed on tab_id, and issues `herdr tab rename` - One tab is stamped once: first matching agent wins, so a multi-pane tab with mixed cwds cannot flip-flop between refreshes - herdr-launch.sh passes the glyph only to `--label`; `agent start` and `claude -n` keep the plain label. Agent and session names are stable identities — nothing refreshes them, so a glyph there freezes at its launch value. Also lifts the ◆ omission in the header's mapping. - The id-shape/injection guard moves from pane_id to tab_id Verified live: the six task tabs plus the ◉ Manager tab now carry current glyphs (● → ◇ where the PR moved), a second refresh reports updated=0, and tabs of other repos are untouched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Local mixture-of-agents review (5 fix rounds) surfaced a chain of silent- failure modes in the refresh path plus doc drift. Fixes applied: - Symlink-consistent match: realpath the whole `.claude/worktrees` path, not just the repo root — cwd is resolved, so a symlinked worktrees dir would otherwise never match and task tabs would freeze at their launch glyph. - ARG_MAX: pass the `herdr tab list` JSON by file, not as a python argv element. On a big server it is hundreds of KB and would blow ARG_MAX (E2BIG); the `|| true` masked that as a `checked=0` success. Agent list stays on stdin. - UTF-8: run the extractor under PYTHONUTF8=1 so stdin, the tab-list file, and stdout are UTF-8 regardless of locale — under LC_ALL=C the glyph bytes in labels (◉ ● …) raised UnicodeDecodeError and the bare except swallowed it. - Temp-file cleanup: an EXIT trap (not just a trailing rm) so a Ctrl-C/SIGTERM between mktemp and cleanup can't orphan the tab-list temp file. Behavior change (user decision): the main-root ◉ is now truly stateless — it stamps even with an empty backlog, instead of inheriting the task-glyph path's empty-`states` early-return. This matches the documented "◉ marks the location" contract that README/CHANGELOG already promised. Docs realigned to the tab-label-only, stateless-◉ model: script header, README, the knowledge entry (+ index bullet trimmed to a pointer), and the kickoff / continue / list / status skill docs (glyph set, ◆, agent-name namespace, the empty-backlog no-op wording). Accepted residuals (declined with rationale): a git repo rooted at `/` (pathological); a bare-shell main-root tab with no herdr agent (cwd has no source but agent list); a mixed-cwd multi-pane tab's first-wins glyph (rare, cosmetic, herdr agent order is stable); a partial tab-list race (best-effort, self-heals next refresh). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
○ ● ◇ ◆ ✓) gain a hub: a tab sitting exactly at the main repo root is now prefixed with◉— the "Manager" among its task satellites. Stateless and non-exclusive (it marks the location), stamped by the existingrefreshsweep with no new trigger.◉live: state-glyph refreshes never reached the sidebar. herdr keeps two names per tab — the tab label (rendered) and the agent registry's own name — and 1.8.0'srefreshrewrote the wrong one, so a tab kept its launch-time glyph forever (a task sat at●while its PR was long in review).Changes
herdr-tab-glyph.sh—refreshnow writes the tab label viaherdr tab rename, joiningherdr agent list(carriescwd, the match) withherdr tab list(carrieslabel, what we prefix) ontab_id. A second exact-cwd branch matches the main repo root →◉;◉joins the idempotency strip. One tab stamped once (first matching agent wins, so a mixed-cwd multi-pane tab can't flip-flop). The injection guard moves frompane_idtotab_id.herdr-launch.sh— the glyph goes only to the tab--label;agent startandclaude -nkeep the plain label, so agent/session names stay stable identities instead of freezing a launch-time glyph.plugins/work-system/README.md, knowledge entryfeatures/herdr-tab-glyphs.md(+ index): add◉, document the tab-label-vs-agent-name namespace and the no-empty-TSV-field trap.Readiness
main(Remove the dead grok composer backend from swarm #37) without conflictsTest plan
refreshagainst a live herdr renames the main-root tab to◉ <label>and each task tab to its current state glyphrefreshreportsupdated=0(idempotent, no churn)/kickoffopens a tab whose label carries the glyph while the agent name stays plain🤖 Generated with Claude Code