Skip to content

fix(statusline): non-blocking Herdr launch, full disclosure, risk-based default (#563) - #564

Merged
lis186 merged 3 commits into
mainfrom
fix/563-statusline-prompt
Aug 18, 2026
Merged

fix(statusline): non-blocking Herdr launch, full disclosure, risk-based default (#563)#564
lis186 merged 3 commits into
mainfrom
fix/563-statusline-prompt

Conversation

@lis186

@lis186 lis186 commented Aug 18, 2026

Copy link
Copy Markdown
Owner

摘要

#563:statusline 同意提問的時機、內容、預設值三件事一起收。

  1. Herdr launch 不再被擋CCXRAY_AGENT_ID=herdr:* 的 pane 跳過互動提問,改印一行 ccxray setup-statusline 提示;不寫拒絕標記,之後直接在 TTY 啟動仍會被問。
  2. 提問補齊三項揭露:用途(Usage 頁的訂閱額度追蹤)、影響(寫 adapter 進 settings.json;既有 statusline 經委派照常渲染)、可逆性(移除時自動還原)。
  3. 預設值跟風險走:沒有既有 statusline(純新增)→ [Y/n],Enter 即裝;要包既有 statusline 或 settings.json 存在但 parse 失敗(覆寫風險)→ 維持 [y/N],同意必須是有意識的 y

差異檢查證據(fail-on-old)

test/statusline-prompt.test.js — 5 個 pty 驅動的 e2e(真實 ccxray --port N claude boot + script(1) pty,#556 的平台分支寫法)。前 3 個複製到 origin/main 拋棄式 worktree:0/3 pass(herdr 情境永久卡在提問、純新增按 Enter 被拒絕、舊提問缺所有揭露文字)。新碼 5/5。

全套(隔離 CCXRAY_HOME、scrub 被監控 session 的 client env):2224/2224 pass

乾淨機器驗證(DO droplet,Ubuntu 22.04)

把修過的 server/index.js 部署到 droplet 的 plugin checkout、移除先前手動建立的拒絕標記(還原成會觸發 bug 的狀態)、從 Herdr plugin 重新 launch:pane 直接進入 Claude Code 畫面,無提問.statusline-declined 不存在(skip 未偽造 decline);~/.claude/settings.jsonstatusLine 鍵(未偷裝)。這正是發現此 bug 的同一台機器、同一條路徑。

Review gate (grok stand-in — codex out of quota until 2026-08-20)

Verdict: SHIP, no P1. Findings & disposition:

# Sev Finding Disposition
1 P2 An existing-but-unparseable settings.json was classified as "nothing configured" — Enter would overwrite unknown content under a [Y/n] default Fixed — parse failure ⇒ wrap-risk ⇒ [y/N]; e2e locks the file byte-identical after Enter
2 P2 Test env inherited ambient CCXRAY_AGENT_ID — a suite run from a Herdr pane would silently skip the prompt in the non-Herdr scenarios (docs/testing.md §1b class) FixedCCXRAY_AGENT_ID: '' pinned in the base env; Herdr test overrides
3 P3 answer.trim() throws on readline EOF (swallowed by spawnAgent's catch — harmless but re-asks) FixedString(answer ?? '')
4 P3 Answer-string / marker coverage gaps Partially added — explicit y on wrap (delegation preserved) + unparseable-file scenario; the rest (YES, whitespace, pre-existing marker, unset CLAUDE_CONFIG_DIR) judged not worth a server boot each
5 P3 Test hygiene: temp dirs never removed; pkill prefix-match Fixed — after() cleanup, exact pattern

Consent-safety check (grok): nothing on any path installs without the TTY prompt; the Herdr skip only withholds the question and can neither install nor forge a decline; the skip cannot fire outside the plugin's herdr: id prefix.

Detail

  • server/index.js promptClaudeStatusline(): herdr-launch guard (falls to the existing hint path), three-line disclosure prompt, hasExisting detection with unparseable-file conservatism, risk-based default, EOF-safe answer handling. Install/uninstall/delegation mechanics untouched.
  • test/statusline-prompt.test.js (new): 5 pty e2e scenarios, isolated per docs/testing.md.

Closes #563

🤖 Generated with Claude Code

Justin Lee and others added 3 commits August 18, 2026 15:53
…ed default (#563)

Herdr 首次 launch 被 statusline 提問卡住(乾淨機器驗證發現);提問本身
缺少用途/影響/可逆性揭露;預設一律 N 對純新增情境過度保守。

- A Herdr-launched pane (CCXRAY_AGENT_ID=herdr:*) skips the interactive
  gate: the one-line 'ccxray setup-statusline' hint replaces the question
  and the declined marker is NOT written, so a later direct TTY launch
  still gets to answer.
- The prompt now discloses purpose (subscription limits on the Usage
  page), impact (writes a statusline adapter into settings.json; an
  existing statusline keeps rendering via delegation), and reversibility
  (auto-restored on removal).
- Default follows risk: [Y/n] when no statusline is configured (pure
  addition), [y/N] when wrapping an existing one (consent must be a
  conscious act).
- test/statusline-prompt.test.js: 3 pty-driven e2e scenarios (fail-on-old:
  0/3 on origin/main — the herdr case blocks forever, Enter declines the
  pure addition, and the old prompt lacks every disclosure).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…test env pinning

- settings.json that exists but fails to parse defaults to [y/N] and Enter
  declines (installing would overwrite unknown content); missing file stays
  the pure-addition [Y/n] path
- answer handling survives readline EOF (String(answer ?? ''))
- tests: pin CCXRAY_AGENT_ID='' in the base env (ambient herdr:* id from a
  monitored pane would silently skip the prompt — docs/testing.md §1b class),
  scenario-dir cleanup, exact pkill pattern, +2 scenarios (explicit y with
  delegation preserved; unparseable file untouched)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…-2 P3)

The wrap line claimed 'delegated, not replaced', but with an unparseable
settings.json an explicit y rewrites the file from {} — say so. Test locks
the copy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@lis186

lis186 commented Aug 18, 2026

Copy link
Copy Markdown
Owner Author

Round-2 grok verdict on the final diff: SHIP — all five round-1 dispositions verified present. One remaining P3 (the unparseable-settings prompt borrowed the wrap copy 'delegated, not replaced' while an explicit y actually rewrites the file from {}) fixed in the latest commit: dedicated impact line ('could not be parsed — installing would REWRITE it') + test locks it. 6/6 e2e green.

@lis186
lis186 merged commit f0d6d5b into main Aug 18, 2026
3 checks passed
@lis186
lis186 deleted the fix/563-statusline-prompt branch August 18, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

First agent launch from the Herdr menu is gated by the statusline TTY prompt

1 participant