Skip to content

fix(hooks): 旧 relay 経由の Claude の Stop に transcript_path を載せる - #3454

Merged
Kewton merged 3 commits into
developfrom
feature/3450-relay-transcript-path
Oct 8, 2026
Merged

Kewton merged 3 commits into
developfrom
feature/3450-relay-transcript-path

Conversation

@Kewton

@Kewton Kewton commented Oct 8, 2026

Copy link
Copy Markdown
Owner

Summary

#3430(PR #3448)で、Claude の Stop の時点で未完了のバックグラウンド作業があれば self_resume_pending を付けるようにした。その判定は hook の payload の transcript_path から transcript を読む。旧 relay(scripts/hooks/cmate-agent-event.sh)経由で届く Stop は transcript_path を転送していなかったため、印が付かなかった(#3450)。

旧 relay が今も使われうるかの判断(使われうる):

  • docs/user-guide/agent-event-hooks.md §3(en も同じ)が、Claude の手動 Stop hook を cmate-agent-event.sh --tool claude --stdin-json で設定する手順を今も載せている(CommandMate 以外から起動した Claude、CM_AGENT_HOOKS_INJECT=0 の運用)
  • --settings で注入する hook は利用者の設定に連結されるので、feat(hooks): 構造化イベント受け口 /api/hooks/agent-event と Claude/Codex 配線【Phase 3-2】 #1549 の手動 Stop hook は注入後も発火し続ける(dedup で片方を捨てる)。手動側が先に着くと、transcript_path の無い配送が適用され、印が付かなかった

変更(scripts/hooks/cmate-agent-event.sh): claude の stop のときだけ、payload の transcript_path を同じ名前で POST 本文に載せる。値は /*/.claude/projects/*.jsonl に合う絶対パスのときだけ送る(受け口がそれ以外を捨てるため)。他の項目・本文は送らない。jq は使わず、既存の json_string_field / json_escape で書いた(bash 3.2 互換)。codex の共有 relay はこのスクリプトを複製するが、claude の stop に限ったので codex の本文は変わらない。docs/user-guide/agent-event-hooks.md §3 と英語版に転送の説明を足した。

Refs #3450(develop 向けのため Closes は使わない)

Test plan

  • commandmatedev verify --task: work-evidence / scope / env-clean / lint / typecheck / unit(テスト全体)すべて PASS(exit 0)
  • 新規 tests/unit/scripts/cmate-agent-event-transcript-path-3450.test.ts(偽の curl で送られる本文を読む。サーバー不要): 本文に transcript_path が入り、その本文を claudeStopLeavesBackgroundWork が true と読む/受け口が受けないパス・値が無い・codex・他のイベントでは付かない
  • 既存の cmate-agent-event.test.ts と codex の relay のテストは無変更で通過。develop 取り込み後に npx tsc --noEmit、tests/unit/scripts・tests/unit/hooks・guards・docs(296 ファイル / 4542 件)が合格。既存の it/describe の削除 0 件
  • CI

🤖 Generated with Claude Code

Kewton and others added 3 commits October 8, 2026 21:56
…3450)

scripts/hooks/cmate-agent-event.sh が、claude の stop のときだけ payload の
transcript_path を同じ名前で POST 本文に載せる。他の項目・本文は送らない。値は
`/*/.claude/projects/*.jsonl` に合う絶対パスのときだけ送る(受け口の
claudeStopLeavesBackgroundWork が自分の home の ~/.claude/projects 配下の .jsonl
しか受けないので、それ以外は送っても捨てられる)。jq は使わず既存の
json_string_field / json_escape で書いた(bash 3.2 互換)。

旧 relay が今も使われうるかの判断(使われうる):
- docs/user-guide/agent-event-hooks.md §3(en も同じ)が Claude の手動 Stop hook を
  `cmate-agent-event.sh --tool claude --stdin-json` で設定する手順として今も載せている
  (CommandMate 以外から起動した Claude、CM_AGENT_HOOKS_INJECT=0 の運用)。
- src/lib/hooks/hook-settings-generator.ts の冒頭コメント: --settings の hook は利用者の
  設定に連結されるので #1549 の手動 Stop hook は注入後も発火し続ける(dedup で片方を捨てる)。
  手動側が先に着いて transcript_path が無いと、その配送が適用されて印が付かなかった。
- 受け口は CommandMate 形式の本文もそのまま payload として source.extractDetail に渡す
  (define-source.ts normalizeSpecEvent → buildNormalizedEvent)ので、本文に
  transcript_path があれば #3430 の判定がそのまま効く。session_id は従来どおり sessionId
  として送っているので追加しない。

テスト: tests/unit/scripts/cmate-agent-event-transcript-path-3450.test.ts(新規)。
既存と同じく偽の curl を PATH の先頭に置いて送られる本文を読む(サーバ不要)。
本文に transcript_path が入ること、その本文を claudeStopLeavesBackgroundWork(一時 HOME の
未通知のバックグラウンド Bash を 1 本持つ transcript)が true と読むこと、受け口が受けない
パス・無いとき・codex・他イベントでは付かないことを確かめた。修正前のスクリプトでは
本文に transcript_path が無いことを手で確認した。既存テストは変えずに通過
(cmate-agent-event.test.ts の Stop の toEqual は /tmp/t.jsonl なので本文は変わらない)。

対になる場所の探索と判断:
- docs/user-guide/agent-event-hooks.md §3 と docs/en/... §3: 両方に転送の説明を追加。
- codex の共有 relay($CODEX_HOME/commandmate/cmate-agent-event.sh、relay-install.ts が
  このスクリプトを複製): claude の stop だけに限ったので codex の本文は不変。
  codex-hooks-relay-install-2315 のテストも通過。
- hook-settings-generator.ts の SessionStart の relay: stop ではないので対象外。
- claude/self-resume.ts の CLAUDE_TRANSCRIPT_PATH_FIELD: 同じ名前で送るので変更不要。
- 同じスクリプトの別条件(#2955 の model、#3330 の queuedNotice): 同じ形(ツール・
  イベントで限定、無ければ付けない)に合わせた。
- 古い動きを固定したテスト: 見つからず(transcript_path を含む既存入力は /tmp/t.jsonl の 1 件)。

隔離: tmux・サーバ・バックグラウンドプロセスは起動していない。一時ファイルは os.tmpdir()
と scratchpad のみ(後始末済み)。~/.commandmate・~/.local/state・service.json(存在しない)
の ls -la を前後で比較。差分は ~/.commandmate/locks/cpu.heavy.lock(owner pid 80093)と
$HOME の .commandmate-demo-vitest-91198 の 2 つで、どちらも別 worktree
(commandmate-issue-3449)の vitest のもの。この作業によるものではない。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Kewton Kewton added the bug Something isn't working label Oct 8, 2026
@Kewton
Kewton merged commit 7b9923d into develop Oct 8, 2026
3 of 15 checks passed
@Kewton
Kewton deleted the feature/3450-relay-transcript-path branch October 8, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant