happyweek7
v0.3.0
Published
HAPPYWEEK7: deterministic Claude Code hook guard for raw tool-call leaks.
Maintainers
Readme
HAPPYWEEK7
I'd be happy to work seven days a week!
HAPPYWEEK7 は、Claude Code の会話文に raw tool-call markup が漏れたときに、ローカル hook で検知して言い直しを要求するための小さなCLIです。
コマンド名は week7 です。
要件定義
目的:
- Claude Code が内部ツール呼び出し用の raw markup を会話文に漏らしたことを検知する
- 漏れた事実は Claude Code のログ上で見えるようにする
- デフォルトでは1回だけ言い直しを要求し、無限ループを避ける
- 判定はAIに依存せず、ローカルの deterministic な正規表現とSHA256ハッシュだけで行う
- Windows と macOS の両方で動く
非目的:
- Claude の挙動を100%修正すること
- Claude Code のストリーミング表示を途中で改変すること
- ネットワーク通信や外部AI判定を使うこと
動作モード
week7 install --mode warn検知してログに残すだけです。Claude への差し戻しはしません。
week7 install --mode rewrite-onceデフォルトです。同じセッションの同じ漏れハッシュにつき、1回だけ差し戻します。
week7 install --mode strict漏れがある限り差し戻します。ループしやすいので通常は非推奨です。
ループ遮断(v0.3)
raw tool-call leak の正体は、Claude Code 側の既知バグ(issue #68354、通称 "call"/"court" バグ)です。ツール呼び出しが構造化された tool_use にシリアライズされ損ね、生のタグが本文に漏れてそのまま実行されません。モデル側の出力フォーマット不具合なので、言い直しでは直りません。/goal などの長時間・ツール多用セッションで踏みやすくなります。
そのため差し戻しを繰り返すと無限ループになります。HAPPYWEEK7 は 1つの漏れバーストにつき最大3回まで差し戻し、それ以降は通します(MAX_SESSION_BLOCKS)。漏れの無いクリーンなターンが来るとカウンタはリセットされ、次のバーストにまた備えます。
根本的には新しい会話で再開するのが回避策です。
ブロック時の表示
Claude Code の Stop hook 上では、以下のような理由が表示されます。
週七出勤喜んで!
HAPPYWEEK7 detected a raw tool-call leak (Claude Code issue #68354).
The tool call was printed as text instead of running, so it did not execute.
This is a model-side serialization bug; rewriting the same turn will not fix it.
新しい会話で再開を推奨します。残業代はいりません!
This is a deterministic local hook, not an AI check.
Mode: rewrite-once. Leak hash: ...使い方
npm からインストール
公開後は Windows/macOS どちらも同じコマンドで使えます。
npm install -g happyweek7
week7 install --mode rewrite-once
week7 status必要環境:
- Node.js 18 以上
- Claude Code が
~/.claude/settings.jsonを使っていること
GitHub からインストール
まだnpm公開前なら、GitHub repo から直接インストールできます。
npm install -g github:monokuroailink-lab/HAPPYWEEK7
week7 install --mode rewrite-once開発フォルダから実行
開発フォルダから直接実行:
node ./bin/week7.js test
node ./bin/week7.js install --mode rewrite-once
node ./bin/week7.js status
node ./bin/week7.js logs --tail 50
node ./bin/week7.js uninstallnpm link する場合:
npm link
week7 install --mode rewrite-once
week7 status配布手順
npm公開
npm login
npm test
npm run pack:dry-run
npm publish公開後の利用者向けコマンド:
npm install -g happyweek7
week7 install --mode rewrite-onceGitHub Releases
Node.js依存のCLIとして配る場合、GitHub repo にこのフォルダをpushするだけでも使えます。
npm install -g github:monokuroailink-lab/HAPPYWEEK7完全な単体バイナリ配布にしたい場合は、将来的に pkg や nexe で week7.exe / week7-macos を作れます。ただし今の最小構成では、npm配布の方が安全で更新もしやすいです。
Windows/macOS 対応
HAPPYWEEK7 は Node.js の標準ライブラリだけで動きます。
- Windows:
C:\Users\<name>\.claude\settings.json - macOS:
/Users/<name>/.claude/settings.json
内部では os.homedir() と path.join() を使っているため、OSごとの差分は吸収されます。
Claude Code hook に登録するコマンドも、インストール時に使っている Node 実行ファイルと week7.js の絶対パスから生成します。
Claude Code hooks
week7 install は ~/.claude/settings.json に以下の hook を追加します。
StopSubagentStopUserPromptSubmit
MessageDisplay は触りません。漏れた本文がログ上に見えることを優先し、返答終了後に差し戻します。
保存場所
~/.claude/week7/config.json
~/.claude/week7/state.json
~/.claude/week7/week7.log
~/.claude/week7/backups/install / uninstall 時には ~/.claude/settings.json のバックアップを保存します。
判定
以下のような unnamespaced な invoke / parameter タグを検知します。
call
<invoke name="Bash">
<parameter name="command">echo ok</parameter>
</invoke>誤検知を避ける仕組み(v0.2)
ツール自身の解説など、正規の文章でタグ例を書いても誤発火しないように、判定前に2段の絞り込みをかけます。
- コードブロック除外:
```フェンスとインラインコード(`...`)の中身は判定対象から外します。ドキュメントやサンプルは安全です。 - name属性の要求: 開始タグが
name="..."属性を持つときだけ漏れと判定します。「invoke という単語」や属性なしの裸タグは通します。
本物の漏れは raw streaming で出るためフェンスに包まれず、必ず name="..." を伴います。この性質差を使って、AIに頼らず決定論のまま分離します。
なお antml: namespaced markup は通します。
<antml:invoke name="Bash">
<antml:parameter name="command">echo ok</antml:parameter>
</antml:invoke>設計メモ
rewrite-once は同じ eventName/sessionId/messageHash を一度だけ差し戻します。
これにより、Claude が1回目の差し戻し後も同じ内容を繰り返した場合、無限ループを避けるために2回目は通します。新しい漏れ、つまり本文ハッシュが変わった漏れは再び検知されます。
