claude-spotter 1.4.12 → 1.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.4.14
4
+
5
+ **README 等の公開資産から内部コードネーム "Bell" を撤去**。Spotter の内部設計議論で使われている
6
+ "Bell" (主役の Claude を指す呼称) は private な codename であり、README や OG banner で
7
+ 公開すべきものではないという運用判断を反映。コード・内部ドキュメント (CLAUDE.md / docs/) には
8
+ 影響なし。npm tarball 同梱の README を新版で配るため patch bump。
9
+
10
+ ### 変更点
11
+
12
+ - **編集 [README.md](README.md) / [README.ja.md](README.ja.md)**:
13
+ "Bell" を文脈に応じて `Claude` / `your primary Claude` / `the primary Claude` に置換、
14
+ `(Bell)` 括弧書きは削除。日本語版の `主体 (Bell) に` は `主体に` に整形。
15
+ - **編集 [.github/og.svg](.github/og.svg) と再生成された [.github/og.png](.github/og.png)**:
16
+ OG banner の bullet text 2 件を Claude 表記に。`svgexport` で 1280×640 PNG を再レンダリング。
17
+ - **編集 [.github/concept.svg](.github/concept.svg)**:
18
+ 内部 HTML コメント `Bell side` を `Primary Claude side` に。
19
+
20
+ ### 検証
21
+
22
+ - `grep -rn "Bell" README.md README.ja.md .github/` で公開資産に Bell 残存なしを確認。
23
+ - `node --test` 334 tests / 333 pass / 1 skip 緑 (README / asset 変更のみで test には影響しない)。
24
+
25
+ ## 1.4.13
26
+
27
+ **Spotter 監査文面の末尾「監査役を明示してください」念押し行を削除**。
28
+ `additionalContext` / pending text の末尾に入っていた 2 行 (UserPromptSubmit:
29
+ 「使う場合は『Spotter の推奨に従い〜』のように監査役の指摘を明示してください。」、
30
+ Stop deferred delivery:「応答には『Spotter からの指摘を受けて〜』のように
31
+ 監査役の介入を明示してください。」) が、毎ターン主役 AI の文脈に積もって邪魔になる
32
+ という運用上のフィードバックを反映。ヘッダー `[Spotter からの推奨ツール]` /
33
+ `[Spotter からの指摘]` 自体が出典明示を担っているため、§12.2 / §12.3 の透明化原則は
34
+ ヘッダーで維持し、念押し行のみを落とす。Claude / Codex 両 host が同じ
35
+ `formatTransparentContext` / `formatTransparentBlockReason` を共有しているので
36
+ hook parity は自動的に維持される。
37
+
38
+ ### 変更点
39
+
40
+ - **編集 [src/hooks/lib.mjs](src/hooks/lib.mjs)**:
41
+ `formatTransparentContext` / `formatTransparentBlockReason` から末尾の空行 +
42
+ 念押し行を削除。コメントを「header 自体が出典明示を担う」旨に書き換え。
43
+ - **編集 [test/hooks.test.mjs](test/hooks.test.mjs)**:
44
+ 逐語アサート 2 件を本体に追従。
45
+
46
+ ### 検証
47
+
48
+ - `node --test` 334 tests / 333 pass / 1 skip 緑。
49
+ - Codex hook 側の expected (`test/codex-hook-cmd.test.mjs`) はヘッダー文字列
50
+ `Spotter からの指摘` だけを正規表現マッチしているため無変更で pass。
51
+
3
52
  ## 1.4.12
4
53
 
5
54
  **macOS/Homebrew install verification docs**。npm registry からの clean global install 後に
package/README.ja.md CHANGED
@@ -11,17 +11,25 @@
11
11
 
12
12
  **[English](README.md) · 日本語**
13
13
 
14
- > **気づく役と実行する役を分離する。** Claude Code の横で並走し、Bell (主役の Claude) が**ツールを呼び忘れたとき**だけ静かに指摘する監査役。
14
+ > **気づく役と実行する役を分離する。** Claude Code の横で並走し、主役の Claude が**ツールを呼び忘れたとき**だけ静かに指摘する監査役。
15
15
 
16
16
  Claude には「使えるツールがあるのに、使うべきタイミングで使わない」という構造的な弱点があります。記録すべき決定を memory / caveat MCP に残さない、docs lookup MCP を呼ばずに古い知識で応答する、ブラウザ自動化 MCP で確認せず UI 状態を推測する — **「分からないと自覚できない」から、ツールを取りに行けない**。
17
17
 
18
- Spotter はツールカタログを完全に把握した別エージェント (Claude Haiku 4.5) をセッション毎に常駐させ、Bell の発話予定と応答を並走監査します。見落としを検出すると透明化された指摘として Bell に届け、補正応答を促します。**Bell が自覚して呼ぶ**設計は本プロダクトの存在意義を破壊するため、Bell から呼ぶのではなく hook 経由で Bell の意思と独立に検出する構造を取っています。
18
+ Spotter はツールカタログを完全に把握した別エージェント (Claude Haiku 4.5) をセッション毎に常駐させ、Claude の発話予定と応答を並走監査します。見落としを検出すると透明化された指摘として Claude に届け、補正応答を促します。**Claude が自覚して呼ぶ**設計は本プロダクトの存在意義を破壊するため、Claude から呼ぶのではなく hook 経由で Claude の意思と独立に検出する構造を取っています。
19
+
20
+ <p align="center">
21
+ <img src=".github/concept.svg" alt="Claude が答え、Spotter が見ている" width="80%">
22
+ </p>
23
+
24
+ <p align="center">
25
+ <sub><b>Claude</b> が答える(実行する役) &nbsp;·&nbsp; <b>Spotter</b> が見ている(気づく役・沈黙監査)</sub>
26
+ </p>
19
27
 
20
28
  ## 30 秒で見るポイント
21
29
 
22
30
  Spotter が拾うのは、たとえばこういう瞬間です。
23
31
 
24
- | 状況 | Bell の応答 | Spotter の指摘 |
32
+ | 状況 | Claude の応答 | Spotter の指摘 |
25
33
  |---|---|---|
26
34
  | 「この OAuth の落とし穴を覚えて」 | 了解だけして進める | memory / caveat MCP の使用機会 |
27
35
  | 「このパッケージの最新版 API は?」 | 学習時点の知識で答える | docs lookup MCP の照会機会 |
@@ -33,7 +41,7 @@ Spotter が拾うのは、たとえばこういう瞬間です。
33
41
  判定軸は 2 段階:
34
42
 
35
43
  - **入力時 (`stage=user_input`)**: ユーザー要請に対し、ローカルカタログの description から用途が明確に該当するツールを列挙する **要請充足チェック**
36
- - **応答後 (`stage=turn_end`)**: Bell の最終応答に対し、事実の断定 / 記録すべき新情報 / 既知情報の参照それぞれに、カタログ上のツール (検証 / 登録 / 照会) を差し込める余地がないかを問う **ツール適用機会の監査**
44
+ - **応答後 (`stage=turn_end`)**: Claude の最終応答に対し、事実の断定 / 記録すべき新情報 / 既知情報の参照それぞれに、カタログ上のツール (検証 / 登録 / 照会) を差し込める余地がないかを問う **ツール適用機会の監査**
37
45
 
38
46
  ## インストール
39
47
 
@@ -86,8 +94,8 @@ Codex native `Stop` は遅延配送で、不足ツールの指摘を queue し
86
94
  ```mermaid
87
95
  flowchart TD
88
96
  U([User 発話]) --> UPH[UserPromptSubmit hook<br/>Spotter が発話とカタログから一次判定]
89
- UPH --> BT[Bell Thinking<br/>Spotter の推奨を<br/>additionalContext で受信]
90
- BT --> BA([Bell の最初の応答])
97
+ UPH --> BT[Claude Thinking<br/>Spotter の推奨を<br/>additionalContext で受信]
98
+ BT --> BA([Claude の最初の応答])
91
99
  BA --> SH[Stop hook<br/>応答と使用済みツールから最終チェック]
92
100
  SH --> DEC{見落とし<br/>あり?}
93
101
  DEC -->|なし| DONE([完了])
@@ -135,7 +143,7 @@ flowchart LR
135
143
  | 対象 | コンテキスト肥大化 | ツール取りこぼし |
136
144
  | 仕組み | hook で記憶退避 | hook でサブエージェント並走 |
137
145
 
138
- 両者に共通するのは **「主体 (Bell) に頼らない仕組み」**。併用できます。
146
+ 両者に共通するのは **「主体に頼らない仕組み」**。併用できます。
139
147
 
140
148
  ## よく使うコマンド
141
149
 
@@ -196,16 +204,16 @@ Codex CLI auditor の子プロセスは、hook 判定を安く速く保つため
196
204
 
197
205
  - v1.4.8 以降、Claude / Codex 両 host で `Stop` hook は **遅延配送 (deferred delivery)** に統一されました。`Stop` で見落としツールを検出した場合、Spotter は `<projectRoot>/.spotter/pending/<sessionId>.json` に指摘を積み、次の same-session `UserPromptSubmit` で `additionalContext` として配信します。当ターンの最初の応答は transcript にそのまま残るため、`decision:"block"` で補正サイクルを回す方式の「最終応答が補正中心になって元の文脈が迷子」問題が解消します (Codex 側は `Stop Blocked` / exit code 1 回避も兼ねる)
198
206
  - pending ファイルは Claude / Codex が同じパス (`.spotter/pending/`) を共有します。host-neutral 設計です
199
- - **JSON スキーマ違反は v0.5.0 以降「想定済み異常」として silent pass + session renew で回復**します (role collapse 検知パス、daemon ログに `role_collapse_reset` を残す)。一方 **Haiku timeout は引き続き throw** され、UserPromptSubmit がブロックされてユーザー入力が Bell に届かない症状として顕在化します (timeout は v0.5.0 で 30s、v0.13.1 で 45s に拡張)。timeout の fail-open 化 (pass 扱い) は §0 改訂とセットで今後検討
207
+ - **JSON スキーマ違反は v0.5.0 以降「想定済み異常」として silent pass + session renew で回復**します (role collapse 検知パス、daemon ログに `role_collapse_reset` を残す)。一方 **Haiku timeout は引き続き throw** され、UserPromptSubmit がブロックされてユーザー入力が Claude に届かない症状として顕在化します (timeout は v0.5.0 で 30s、v0.13.1 で 45s に拡張)。timeout の fail-open 化 (pass 扱い) は §0 改訂とセットで今後検討
200
208
 
201
209
  <details>
202
210
  <summary><strong>📋 最近のハイライト</strong></summary>
203
211
 
204
- - **プラグイン形式の MCP サーバー対応** — `plugin:everything-claude-code:context7` のように名前に内部コロンを含むサーバーを正しくパースし、配下のツールをカタログに取り込めるようになった (旧版はこの形式のサーバーをすべて単一の `"plugin"` に潰して、Bell の監査から silent に脱落させていた)
212
+ - **プラグイン形式の MCP サーバー対応** — `plugin:everything-claude-code:context7` のように名前に内部コロンを含むサーバーを正しくパースし、配下のツールをカタログに取り込めるようになった (旧版はこの形式のサーバーをすべて単一の `"plugin"` に潰して、Claude の監査から silent に脱落させていた)
205
213
  - **プロジェクト単位の監査隔離** — daemon が監査に使うのはローカル DB のみ。グローバル DB は description 再利用キャッシュに役割限定。**他プロジェクト**でインストールしたツールが現プロジェクトの監査に混入することはない
206
214
  - **手放しでカタログ維持** — `spotter install` が Claude DB を自動 seed、Claude / Codex それぞれの SessionStart が host-local DB を bg refresh する。手書き管理は一切不要
207
215
  - **Codex native hooks** — Codex host は primary auditor backend として Codex CLI を使い、`.spotter/tool-db.codex.json` を Claude DB と分離し、backend failure は Haiku fallback ではなく明示 error として扱う
208
- - **監査対象** — ユーザー追加分 (MCP / スキル / サブエージェント) のみ。Claude Code 本体側のツールは意図的に対象外 (Bell は元から自発率が高いため)
216
+ - **監査対象** — ユーザー追加分 (MCP / スキル / サブエージェント) のみ。Claude Code 本体側のツールは意図的に対象外 (Claude は元から自発率が高いため)
209
217
  - **実装規範** — フォールバック禁止 / silent fallback 禁止 / 暫定コード禁止 ([CLAUDE.md §0](CLAUDE.md))
210
218
 
211
219
  リリース履歴の全文は [CHANGELOG](CHANGELOG.md) を参照。
package/README.md CHANGED
@@ -11,17 +11,25 @@
11
11
 
12
12
  **English · [日本語](README.ja.md)**
13
13
 
14
- > **Separate the spotter from the doer.** Spotter runs alongside Claude Code and quietly flags the moments when Bell (your primary Claude) **forgets to use a tool it has access to**.
14
+ > **Separate the spotter from the doer.** Spotter runs alongside Claude Code and quietly flags the moments when your primary Claude **forgets to use a tool it has access to**.
15
15
 
16
16
  Claude has a structural blind spot: **it can't reach for a tool it doesn't realize it needs**. It may skip a project memory MCP when a decision should be recorded, answer from stale memory instead of a docs-lookup MCP, or reason about UI state without a browser-automation MCP. The model can't always tell when it doesn't know — so the tool stays unused.
17
17
 
18
- Spotter pins a second agent (Claude Haiku 4.5) next to Bell. The second agent has the full tool catalog memorized and audits both the user's prompt and Bell's reply in parallel. When it spots a missed tool, it injects a transparent recommendation into Bell's context and, if needed, asks Bell to amend its answer. **Bell is never asked to self-audit** — that would defeat the entire premise. Detection happens through hooks, independent of Bell's intent.
18
+ Spotter pins a second agent (Claude Haiku 4.5) next to Claude. The second agent has the full tool catalog memorized and audits both the user's prompt and Claude's reply in parallel. When it spots a missed tool, it injects a transparent recommendation into Claude's context and, if needed, asks Claude to amend its answer. **Claude is never asked to self-audit** — that would defeat the entire premise. Detection happens through hooks, independent of Claude's intent.
19
+
20
+ <p align="center">
21
+ <img src=".github/concept.svg" alt="Claude answers · Spotter watches" width="80%">
22
+ </p>
23
+
24
+ <p align="center">
25
+ <sub><b>Claude</b> answers (the doer) &nbsp;·&nbsp; <b>Spotter</b> watches (the auditor, silent)</sub>
26
+ </p>
19
27
 
20
28
  ## See it in 30 seconds
21
29
 
22
30
  Examples of what Spotter catches:
23
31
 
24
- | Situation | What Bell would do | What Spotter flags |
32
+ | Situation | What Claude would do | What Spotter flags |
25
33
  |---|---|---|
26
34
  | "Please remember this OAuth gotcha" | Acknowledge and move on | Missed call to a memory / caveat MCP |
27
35
  | "How does this package API work in the latest version?" | Answer from training-time knowledge | Missed call to a docs-lookup MCP |
@@ -33,7 +41,7 @@ Examples of what Spotter catches:
33
41
  Spotter audits in two stages:
34
42
 
35
43
  - **`stage=user_input`** — given the user's prompt, list any local catalog tools whose description clearly applies. A *prompt-fulfillment* check
36
- - **`stage=turn_end`** — given Bell's final reply, look for places where a catalog tool (verification / recording / lookup) could plug in. A *missed-opportunity* audit. Zero findings is fine; tools already used in this turn are not re-flagged
44
+ - **`stage=turn_end`** — given Claude's final reply, look for places where a catalog tool (verification / recording / lookup) could plug in. A *missed-opportunity* audit. Zero findings is fine; tools already used in this turn are not re-flagged
37
45
 
38
46
  ## Install
39
47
 
@@ -86,8 +94,8 @@ the next same-session `UserPromptSubmit`.
86
94
  ```mermaid
87
95
  flowchart TD
88
96
  U([User prompt]) --> UPH[UserPromptSubmit hook<br/>Spotter audits prompt against catalog]
89
- UPH --> BT[Bell thinking<br/>receives Spotter's recommendations<br/>as additionalContext]
90
- BT --> BA([Bell's first answer])
97
+ UPH --> BT[Claude thinking<br/>receives Spotter's recommendations<br/>as additionalContext]
98
+ BT --> BA([Claude's first answer])
91
99
  BA --> SH[Stop hook<br/>Spotter re-audits answer + tools used]
92
100
  SH --> DEC{Missed<br/>tool?}
93
101
  DEC -->|No| DONE([Done])
@@ -135,7 +143,7 @@ The audited catalog is host-local: Claude uses `<project>/.spotter/tool-db.json`
135
143
  | Target | Context bloat | Missed tool calls |
136
144
  | Mechanism | Hook-driven memory eviction | Hook-driven sub-agent in parallel |
137
145
 
138
- Both share the principle of **"don't rely on the primary agent (Bell) to do it itself."** They compose well — you can run them together.
146
+ Both share the principle of **"don't rely on the primary agent to do it itself."** They compose well — you can run them together.
139
147
 
140
148
  ## Common commands
141
149
 
@@ -197,18 +205,18 @@ those values for smoke tests or controlled experiments.
197
205
 
198
206
  ## Known limitations
199
207
 
200
- - The `Stop` hook fires **after** Bell's first answer has already been streamed to the user. When Spotter sends Bell back, the user sees both the original answer and the corrected one. Detection accuracy in `UserPromptSubmit` (the *pre-response* stage) is therefore Spotter's primary axis of quality
208
+ - The `Stop` hook fires **after** Claude's first answer has already been streamed to the user. When Spotter sends Claude back, the user sees both the original answer and the corrected one. Detection accuracy in `UserPromptSubmit` (the *pre-response* stage) is therefore Spotter's primary axis of quality
201
209
  - `Stop` hook is **deferred** for both Claude and Codex hosts as of v1.4.8. When Spotter finds a missed tool at `Stop`, it appends the finding to `<projectRoot>/.spotter/pending/<sessionId>.json` and surfaces it on the next same-session `UserPromptSubmit` as `additionalContext`. The original assistant message stays as the turn's final transcript entry — no `decision:"block"` re-generation cycle. The same pending file is shared by Claude and Codex (host-neutral path)
202
- - **Since v0.5.0, JSON schema violations from Haiku are treated as expected-anomalies** (silent pass + session renew, logged as `role_collapse_reset`) — this is the role-collapse recovery path. **Haiku timeouts still throw**, which surfaces as `UserPromptSubmit` blocking the user's prompt from reaching Bell. Timeouts have been raised twice (30s in v0.5.0, 45s in v0.13.1); making timeouts fail-open is deferred until §0 is revisited
210
+ - **Since v0.5.0, JSON schema violations from Haiku are treated as expected-anomalies** (silent pass + session renew, logged as `role_collapse_reset`) — this is the role-collapse recovery path. **Haiku timeouts still throw**, which surfaces as `UserPromptSubmit` blocking the user's prompt from reaching Claude. Timeouts have been raised twice (30s in v0.5.0, 45s in v0.13.1); making timeouts fail-open is deferred until §0 is revisited
203
211
 
204
212
  <details>
205
213
  <summary><strong>📋 Recent highlights</strong></summary>
206
214
 
207
- - **Plugin-scoped MCP servers** — names like `plugin:everything-claude-code:context7` (with internal colons) are now parsed correctly and their tools enter the catalog. Earlier versions silently collapsed all plugin MCP servers into a single literal `"plugin"`, dropping their tools from Bell's audit
215
+ - **Plugin-scoped MCP servers** — names like `plugin:everything-claude-code:context7` (with internal colons) are now parsed correctly and their tools enter the catalog. Earlier versions silently collapsed all plugin MCP servers into a single literal `"plugin"`, dropping their tools from Claude's audit
208
216
  - **Per-project / per-host audit isolation** — the daemon audits against the local DB only; global DBs are host-specific description caches. Tools discovered in *other* projects or another host can never bleed into this project's audit set
209
217
  - **Zero-touch catalog** — `spotter install` seeds the Claude DB automatically; Claude and Codex SessionStart hooks keep their host-local DBs fresh in the background. You never have to maintain the tool list by hand
210
218
  - **Codex native hooks** — Codex host uses Codex CLI as the primary auditor backend, keeps a separate `.spotter/tool-db.codex.json`, and surfaces backend failures explicitly instead of falling back to Haiku
211
- - **Audit scope** — only user-added surface (MCP servers / skills / sub-agents). Claude Code's built-in tools are intentionally out of scope; Bell already uses those reliably
219
+ - **Audit scope** — only user-added surface (MCP servers / skills / sub-agents). Claude Code's built-in tools are intentionally out of scope; Claude already uses those reliably
212
220
  - **Implementation invariants** — no fallbacks, no silent failures, no provisional code (see [§0 in CLAUDE.md](CLAUDE.md))
213
221
 
214
222
  Full release history: [CHANGELOG](CHANGELOG.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-spotter",
3
- "version": "1.4.12",
3
+ "version": "1.4.14",
4
4
  "description": "Audit agent running alongside Claude Code that catches missed tool calls — 気づく役と実行する役の分離",
5
5
  "type": "module",
6
6
  "bin": {
package/src/hooks/lib.mjs CHANGED
@@ -129,14 +129,12 @@ export function die(message, exitCode = 2) {
129
129
  }
130
130
 
131
131
  export function formatTransparentContext(missingTools) {
132
- // §12.2: transparent phrasing — Bell should reference Spotter explicitly.
132
+ // §12.2: transparent phrasing — header `[Spotter からの推奨ツール]` 自体が出典明示を担う。
133
133
  const lines = missingTools.map((m) => `- \`${m.name}\`: ${m.reason}`);
134
134
  return [
135
135
  '[Spotter からの推奨ツール]',
136
136
  'このプロンプトに応答する前に、以下のツールを使うべきか検討してください。',
137
137
  ...lines,
138
- '',
139
- '使う場合は「Spotter の推奨に従い〜」のように監査役の指摘を明示してください。',
140
138
  ].join('\n');
141
139
  }
142
140
 
@@ -156,13 +154,11 @@ export async function recordClaudeHookEvent({ projectRoot, event, writeError } =
156
154
  }
157
155
 
158
156
  export function formatTransparentBlockReason(missingTools) {
159
- // §12.3: transparent phrasing for Stop hook block.
157
+ // §12.3: transparent phrasing — header `[Spotter からの指摘]` 自体が出典明示を担う。
160
158
  const lines = missingTools.map((m) => `- \`${m.name}\`: ${m.reason}`);
161
159
  return [
162
160
  '[Spotter からの指摘]',
163
161
  '上記応答ではツールが不足している可能性があります。以下を検討し、必要なら呼び出した上で応答を補正してください。',
164
162
  ...lines,
165
- '',
166
- '応答には「Spotter からの指摘を受けて〜」のように監査役の介入を明示してください。',
167
163
  ].join('\n');
168
164
  }