Skip to content

feat(detect): add muse agent with generic Pick blocked detection - #2489

Open
ohk wants to merge 5 commits into
herdrdev:masterfrom
ohk:feat/muse-pick-generic-blocked-2
Open

feat(detect): add muse agent with generic Pick blocked detection#2489
ohk wants to merge 5 commits into
herdrdev:masterfrom
ohk:feat/muse-pick-generic-blocked-2

Conversation

@ohk

@ohk ohk commented Aug 7, 2026

Copy link
Copy Markdown

Add Muse agent detection.

  • manifests: src/detect/manifests/muse.toml + website/agent-detection/muse.toml (id muse v2026.08.06.1)
  • runtime: src/detect/mod.rs Agent::Muse (ALL 22, SCREEN 20), lookup for muse/muse-bin/muse-code, label/executable, sound override (sidebar unchanged)
  • fix waiting answer miss: Pick footer is generic 'Enter to select · ↑/↓ to move · Tab for an optional note · Esc to interrupt' – title/message can be anything. Previous rule required AND combos; now blocked pick is single generic gate 'Enter to select' (bottom_non_empty_lines(5), priority 950, visible_blocker) with working not Enter, so any Pick triggers blocked regardless of question text.

Evidence: herdr pane read --source detection (muse-spark-1.2-contributor 0.1.0) – idle YOLO/⟩, working esc to interrupt.

Replaces #2456 (closed by bot) with sidebar revert (6 files).

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Muse as a supported agent. The change defines Muse aliases and executable mappings, adds bundled and website detection manifests for terminal states, and adds Muse sound override configuration.

Changes

Muse detection integration

Layer / File(s) Summary
Define the Muse agent
src/detect/mod.rs
Adds Agent::Muse to agent collections, labels, executable mappings, aliases, and identification tests.
Add Muse detection rules
src/detect/manifest.rs, src/detect/manifests/muse.toml, website/agent-detection/index.toml, website/agent-detection/muse.toml
Registers Muse manifests and defines rules for workspace trust, pickers, menus, approvals, working activity, and idle states.
Configure Muse sound overrides
src/config/sound.rs
Adds Muse sound override storage, lookup handling, and default initialization.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DetectionEngine
  participant MuseManifest
  participant TerminalPane
  DetectionEngine->>MuseManifest: evaluate Muse detection rules
  MuseManifest->>TerminalPane: inspect terminal evidence
  TerminalPane-->>MuseManifest: provide blocked, working, or idle evidence
  MuseManifest-->>DetectionEngine: return Muse state
Loading

Possibly related PRs

  • herdrdev/herdr#2301: Adds agent-specific idle-state detection rules with exclusions for active and blocked states in bundled and website manifests.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main changes: Muse agent detection and generic Pick blocked detection.
Description check ✅ Passed The description directly explains the Muse detection support, manifest updates, runtime changes, and blocked Pick detection improvements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@kangal-bot

Copy link
Copy Markdown
Collaborator

Hi @ohk, thanks for your interest in contributing.

Herdr does not accept unsolicited implementation pull requests from contributors who are not listed in .github/APPROVED_CONTRIBUTORS.

The pull request author is not an approved contributor.

If you encountered a reproducible bug, report the observed behavior through the bug issue template. A report does not reserve the work or authorize a pull request; accepted fixes are normally implemented by Herdr’s maintainer-controlled agents.

Feature requests, behavior changes, and other proposals belong in GitHub Discussions. Do not open an issue merely to justify an implementation that was already written.

If a maintainer explicitly wants this implementation, they can reopen the pull request. Reopening by anyone else will be closed again automatically.

See https://github.com/herdrdev/herdr/blob/master/CONTRIBUTING.md for the contribution policy.

@kangal-bot kangal-bot closed this Aug 7, 2026
@ogulcancelik ogulcancelik reopened this Aug 7, 2026
@kangal-bot kangal-bot added the ai-review Trigger automated AI reviews for pull requests admitted by the PR gate label Aug 7, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 79b2bc5b-5e09-4326-8058-6f7f02062b92

📥 Commits

Reviewing files that changed from the base of the PR and between 7d77e92 and 773b4b6.

📒 Files selected for processing (6)
  • src/config/sound.rs
  • src/detect/manifest.rs
  • src/detect/manifests/muse.toml
  • src/detect/mod.rs
  • website/agent-detection/index.toml
  • website/agent-detection/muse.toml

Comment thread src/detect/manifests/muse.toml
Comment thread src/detect/manifests/muse.toml Outdated
Comment thread src/detect/mod.rs Outdated
@greptile-apps

greptile-apps Bot commented Aug 9, 2026

Copy link
Copy Markdown

Greptile Summary

The PR adds Muse as a recognized agent, supplies bundled and published screen-state detection rules, and exposes per-agent sound configuration.

  • Recognizes Muse aliases and versioned muse-bin-* executables, including path-qualified process names.
  • Detects Muse idle, working, picker, menu, approval, and workspace-trust states.
  • Registers synchronized bundled and website manifests and adds Muse sound overrides.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
src/detect/mod.rs Adds Muse identity, aliases, executable metadata, and constrained matching for versioned Muse binaries while addressing prior basename and overbroad-prefix findings.
src/detect/manifests/muse.toml Adds prioritized Muse screen-state rules and aligns picker and working regions to resolve the previously reported stale-picker suppression.
website/agent-detection/muse.toml Publishes a synchronized copy of the bundled Muse detection manifest.
src/config/sound.rs Adds a defaulted Muse-specific sound setting and maps it from Agent::Muse.
src/detect/manifest.rs Registers the Muse manifest in the bundled manifest catalog.
website/agent-detection/index.toml Adds Muse to the published agent-detection index.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  PROC[Foreground process name or argv0] --> NORMALIZE[Normalize suffix and basename]
  NORMALIZE --> IDENTIFY[Identify Agent::Muse]
  SCREEN[Rendered pane text] --> RULES[Muse manifest rules]
  IDENTIFY --> RULES
  RULES --> STATE[Idle / Working / Blocked / Unknown]
  STATE --> UI[Pane state and Muse sound override]
Loading

Reviews (6): Last reviewed commit: "fix(detect): add enter save to muse menu..." | Re-trigger Greptile

Comment thread src/detect/mod.rs
Comment thread src/detect/manifests/muse.toml Outdated
ohk pushed a commit to ohk/herdr that referenced this pull request Aug 9, 2026
- manifests: change working_esc_interrupt and blocked_approval
  from whole_recent to bottom_non_empty_lines(8) to use captured
  bottom-buffer controls instead of incidental whole-pane text
- manifests: anchor idle_prompt line_regex to ^\s*⟩\s*$ so working
  chrome "⟩ ..." does not match idle
- runtime: restrict muse lookup to explicit aliases
  (muse|muse-bin|muse-code|muse-cli), remove starts_with("muse")
  fallback that misclassified museum/muse-helper/muser; add
  positive/negative identification tests
- keep website mirror identical; verified with agent_detection
  manifest check --require-website

refs herdrdev#2489
refs herdrdev#2456
@ohk
ohk force-pushed the feat/muse-pick-generic-blocked-2 branch from ef121fd to 4320fe1 Compare August 9, 2026 07:09
@mjdouglas

Copy link
Copy Markdown

Muse Code team member here — glad to see this. I've been validating Muse detection against the live UI from the vendor side (herdr agent read --source detection + herdr agent explain through full idle → working → blocked → idle cycles), and three findings from those captures are worth folding in before this merges:

1. pick_request_blocked's 5-line region misses the picker footer on narrow panes.
The Pick footer wraps: at narrower widths it renders as two lines (Enter to select · ↑/↓ to move · Tab for an optional / note · Esc to interrupt), and the persistent prompt chrome (── Voice input …, , rule line, status line) fills the bottom four non-empty lines. In my capture, "Enter to select" sat on the 6th non-empty line from the bottom, so bottom_non_empty_lines(5) never sees it — blocked reads as idle exactly when the agent is waiting. Widening the region (or whole_recent) fixes it; that also resolves the region mismatch Greptile flagged between this rule (5 lines) and the working rule's not-gate (8 lines).

2. idle_status_fallback on "YOLO" only works in --yolo mode.
Without the flag there's no YOLO token, and the model segment of the status line varies by build/config (it isn't always muse-spark-*), so neither is a stable anchor. The invariant is the footer's shape: model · effort · cwd — a line regex like ^\s*[A-Za-z0-9._-]+ · [a-z]+ · [~/] matched every variant I captured (including absolute cwds outside $HOME, where a ~/ token also fails).

3. The startup workspace-trust dialog reads as idle.
First launch in an untrusted directory shows Do you trust this workspace? with > 1 Trust and continue / 2 Quit — no rule matches, so it falls to the known-agent idle fallback while the agent is actually blocked. A rule on "Do you trust this workspace?" + any of "Trust and continue" / "Use Up/Down" catches it.

One smaller note: idle_prompt's '^\s*⟩\s*$' only matches an empty prompt; a second pattern for with typed text keeps idle stable while composing (they need to be OR'd via an any gate — multiple top-level line_regex entries AND together).

Happy to share the raw captures for any of these. Separately, #2588 proposes the session-identity + resume half (muse resume <id>) as a follow-up to this — I can support that from the Muse side.

@mjdouglas

Copy link
Copy Markdown

@ohk following up on the edge-case question — a few more, all from live captures on the vendor side, roughly by impact:

  1. User-opened pickers have a different footer than agent-initiated ones. /model shows ↑↓ move · enter confirm · esc go back — lowercase "enter confirm", no "Enter to select", and ↑↓ without the slash — so the generic Pick gate doesn't match it and the pane reads idle while a menu is up. Worth deciding deliberately whether user-opened menus should be blocked (they do need input, but the agent isn't waiting on an answer); if yes, that footer needs its own rule.

  2. The picker selection marker is the same glyph as the prompt. The highlighted row renders as ⟩ <model name>, so a typed-text idle pattern (^\s*⟩\s+) can match a picker row. Any such pattern should stay in a tight bottom region and be not-gated on the picker footers.

  3. Typed-but-unsubmitted text breaks the empty-prompt idle rule. While composing, the prompt renders ⟩ <draft text> (wrapping to continuation lines), so '^\s*⟩\s*$' stops matching and idle falls through to the fallback. Related: submitted prompts get echoed into scrollback as ⟩ <text> lines, which is why the typed-text variant needs a small bottom region.

  4. blocked_approval's prose-like words can false-positive. Muse's own replies and tool output land in the bottom-8 region right after a turn (it will happily quote "Do you want to proceed?" or "Allow" back at you in prose). Anchoring blocked on footer chrome rather than sentence words is safer.

  5. Working has more shapes than Thinking: ◇/◆ Finishing up (Ns · esc to interrupt) after answering a question, and tool lines like ◆ Ran command · … · ✓ · 0.1s · ctrl+o / └ (ctrl+b to send to background). The spinner alternates /. Your generic esc to interrupt gate covers all of these — keep it generic.

  6. Startup transients: a Muse Code 0.1.0 banner and, sometimes, Your selected model is no longer available; switched to … appear above the first idle chrome. Nothing should key on them.

  7. Case-sensitivity gotcha in herdr: contains matches case-insensitively but regex/line_regex don't. Muse mixes cases — the picker footer says Esc to interrupt, the thinking line says esc to interrupt — so this bites if any rule migrates from contains to regex.

  8. One non-issue, verified: ctrl+o expands output inline rather than opening an alternate-screen viewer, so the prompt chrome stays at the bottom and no skip-state viewer rule is needed for it.

Raw captures available for any of these.

ohk pushed a commit to ohk/herdr that referenced this pull request Aug 11, 2026
- manifests: widen pick_request_blocked to bottom_non_empty_lines(8) and add
  Enter to toggle for multi-select; add menu_request_blocked for user-opened
  pickers (enter confirm/esc go back/esc close/space toggle); add
  workspace_trust_blocked for Do you trust dialog; tighten blocked_approval
  to footer chrome Allow once/Always allow/Yes proceed; split idle_prompt
  into any gate for empty and typed draft and not-gate pick/menu anchors;
  change idle_status_fallback from YOLO to model \u00b7 effort \u00b7 cwd shape
- runtime: replace bare muse-bin alias with muse-bin-<version> digit check
  to match versioned launcher binary and avoid museum/muse-binary false
  positives
- cross-checked with vendor-side captures reported on PR herdrdev#2489 against
  strings in shipped muse-bin binary

refs herdrdev#2489
@ohk

ohk commented Aug 11, 2026

Copy link
Copy Markdown
Author

@mjdouglas Thanks for the detailed vendor-side captures — cross-checked against strings in the shipped muse-bin binary and folded in as 9da6a45a on this branch (pushed to feat/muse-pick-generic-blocked-2):

Your 3 findings (2026-08-10 17:08):

  1. Pick 5→6th line miss — widened pick_request_blocked to bottom_non_empty_lines(8) and added Enter to toggle for multi-select (any OR). Also widens working_esc_interrupt not-gate to same 8 so Esc to interrupt in pick footer doesn't misclassify as working (contains is case-insensitive). Fixes Greptile 5 vs 8.

  2. YOLO only --yolo — changed idle_status_fallback from contains YOLO to line_regex '^\s*\S+ · (none|minimal|low|medium|high|xhigh|ultra) · ' (model · effort · cwd shape, · U+00B7). Covers absolute /tmp/... cwds as well; vendor's · [~/] variant also handled (current · is slightly more permissive, same effect).

  3. Trust dialog Do you trust this workspace? — added workspace_trust_blocked prio 970 bottom(12) contains "Do you trust..."+ any Trust and continue / Use Up/Down.

  4. Idle typed ⟩ <draft> — split idle_prompt into any [{line_regex ^\s*⟩\s*$},{line_regex ^\s*⟩\s+\S}] (multiple top-level line_regex AND, so OR via any as noted).

Your 8 edge cases (20:54):

  1. User menus /model enter confirm · esc go back — added menu_request_blocked prio 940 bottom(8) any {enter confirm, esc go back, esc close, space toggle} — generic on footer chrome, blocked by convention.

  2. picker row vs prompt — kept idle_prompt tight bottom(5) + not on both pick footers + 4 menu anchors; menu's higher prio (940>700) also wins.

  3. Typed draft wrapping — second ⟩\s+\S pattern in tight 5-line region, handles ⟩ draft wrapping.

  4. blocked_approval prose — narrowed from Do you want.../Allow to footer chrome Allow once/Allow for this session/Always allow in this workspace/Yes, proceed (network approval via Yes, proceed, not title at 10th line).

  5. Working Finishing up — kept generic contains esc to interrupt (covers ◇/◆ Running / Finishing up / ◆ Ran command), no spinner-specific regex.

  6. Banner transients — no rule keys on Muse Code 0.1.0 / switched model; idle fallback no longer uses YOLO/model literal.

  7. Case-sensitivity — notes contains insensitive vs regex not; remained on contains for Esc/esc.

  8. ctrl+o inline — verified no alternate-screen viewer, no skip_state_update needed.

Also: lookup_agent now matches muse-bin-<version> digit check (real launcher execs muse-bin-0.1.0-R708.1) to avoid museum/muse-binary false positives, and website/agent-detection/muse.toml mirrored.

Verified: cargo test -- detect 169 passed, scripts/agent_detection_manifest_check.py --require-website ok.

#2588 muse resume <id> left as follow-up per your note.

Raw captures appreciated — happy to adjust if you see more menu verbs.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4cae02a1-d896-4afc-a3af-164bad20ed45

📥 Commits

Reviewing files that changed from the base of the PR and between 4320fe1 and 9da6a45.

📒 Files selected for processing (3)
  • src/detect/manifests/muse.toml
  • src/detect/mod.rs
  • website/agent-detection/muse.toml
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/detect/mod.rs

Comment thread src/detect/manifests/muse.toml
Comment thread src/detect/mod.rs
ohk pushed a commit to ohk/herdr that referenced this pull request Aug 11, 2026
lookup_agent now uses path_basename before matching so a launcher
exec with absolute argv0 like /usr/local/lib/muse/muse-bin-0.1.0-R708.1
is correctly identified. is_muse_versioned_binary also checks basename
so direct path-qualified names succeed without relying on the
argv0_argv fallback path. Prevents missed Muse detection when screen
state and sound overrides are not applied.

refs herdrdev#2489
ohk pushed a commit to ohk/herdr that referenced this pull request Aug 11, 2026
Evidence documents /theme with enter save footer which was not
matched. Add enter save to menu_request_blocked any list and to
idle_prompt not-gate (highlighted row ⟩ <choice> shares glyph) and
keep website mirror in sync. Update evidence comment counts from
four to five.

refs herdrdev#2489
Omer Hamid Kamisli added 5 commits August 10, 2026 20:36
Add Muse agent manifests and runtime detection for idle/working/blocked
states. Blocked Pick is generic on footer 'Enter to select' so any
question title/message triggers, fixing missed waiting answer where
previous AND-gated rule required specific hint combos. Cover process
names muse, muse-bin, muse-code variants and YOLO footer.

refs #herdr
- manifests: change working_esc_interrupt and blocked_approval
  from whole_recent to bottom_non_empty_lines(8) to use captured
  bottom-buffer controls instead of incidental whole-pane text
- manifests: anchor idle_prompt line_regex to ^\s*⟩\s*$ so working
  chrome "⟩ ..." does not match idle
- runtime: restrict muse lookup to explicit aliases
  (muse|muse-bin|muse-code|muse-cli), remove starts_with("muse")
  fallback that misclassified museum/muse-helper/muser; add
  positive/negative identification tests
- keep website mirror identical; verified with agent_detection
  manifest check --require-website

refs herdrdev#2489
refs herdrdev#2456
- manifests: widen pick_request_blocked to bottom_non_empty_lines(8) and add
  Enter to toggle for multi-select; add menu_request_blocked for user-opened
  pickers (enter confirm/esc go back/esc close/space toggle); add
  workspace_trust_blocked for Do you trust dialog; tighten blocked_approval
  to footer chrome Allow once/Always allow/Yes proceed; split idle_prompt
  into any gate for empty and typed draft and not-gate pick/menu anchors;
  change idle_status_fallback from YOLO to model \u00b7 effort \u00b7 cwd shape
- runtime: replace bare muse-bin alias with muse-bin-<version> digit check
  to match versioned launcher binary and avoid museum/muse-binary false
  positives
- cross-checked with vendor-side captures reported on PR herdrdev#2489 against
  strings in shipped muse-bin binary

refs herdrdev#2489
lookup_agent now uses path_basename before matching so a launcher
exec with absolute argv0 like /usr/local/lib/muse/muse-bin-0.1.0-R708.1
is correctly identified. is_muse_versioned_binary also checks basename
so direct path-qualified names succeed without relying on the
argv0_argv fallback path. Prevents missed Muse detection when screen
state and sound overrides are not applied.

refs herdrdev#2489
Evidence documents /theme with enter save footer which was not
matched. Add enter save to menu_request_blocked any list and to
idle_prompt not-gate (highlighted row ⟩ <choice> shares glyph) and
keep website mirror in sync. Update evidence comment counts from
four to five.

refs herdrdev#2489
@ohk
ohk force-pushed the feat/muse-pick-generic-blocked-2 branch from c79c502 to 6240e1b Compare August 11, 2026 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review Trigger automated AI reviews for pull requests admitted by the PR gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants