claude-spotter 1.4.14 → 1.4.17
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 +123 -13
- package/README.ja.md +16 -11
- package/README.md +16 -12
- package/package.json +1 -1
- package/src/cli/codex-hook-cmd.mjs +158 -54
- package/src/cli/doctor.mjs +16 -6
- package/src/cli/install.mjs +14 -2
- package/src/core/codex-cli-backend.mjs +40 -1
- package/src/core/codex-transcript.mjs +179 -4
- package/src/daemon/daemon.mjs +8 -1
- package/src/daemon/transport.mjs +21 -1
- package/src/hooks/lib.mjs +42 -13
- package/src/hooks/pre-tool-use.mjs +9 -6
- package/src/hooks/stop.mjs +83 -33
- package/src/hooks/user-prompt.mjs +33 -50
- package/src/index.mjs +1 -0
- package/src/tool-db/lookup.mjs +1 -1
- package/src/tool-db/refresh.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,115 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.4.17
|
|
4
|
+
|
|
5
|
+
v1.4.16 で実装済みだった stale Unix socket recovery を、v1.4.16 tag を改変せずこの patch の実配布候補に含める。
|
|
6
|
+
daemon 異常死後の orphan socket を次回起動前に安全に除去する回復経路が、初めて配布物へ入る。
|
|
7
|
+
|
|
8
|
+
### 変更点
|
|
9
|
+
|
|
10
|
+
- **Codex SessionStart hook**: unsupported な `async:true` を除去し、現行 schema
|
|
11
|
+
`{type, command, timeout}` に合わせた。upgrade 時は旧 field を正規化し、他製品・他 hook の定義を保持する。
|
|
12
|
+
- **diagnostics / guidance**: readiness、registered、compatible、canonical、observed を分けて表示する。
|
|
13
|
+
信頼状態が未知なら `/hooks` での確認を案内し、doctor / install の次手も明示する。
|
|
14
|
+
- **Claude Stop の失敗通知**: backend / transport failure を stage-aware な warning として same-session
|
|
15
|
+
pending に永続化し、次の prompt で配信する。finding / warning の永続化に失敗した場合は stderr と
|
|
16
|
+
`degraded` event を記録して non-blocking を維持する。最終 turn で次 prompt がない場合には配信できない
|
|
17
|
+
限界は残る。
|
|
18
|
+
- **Codex used-tools**: 現行 `custom_tool_call`、legacy `function_call`、MCP、agents を current turn の
|
|
19
|
+
bounded tail から認識する。schema / missing / oversize の anomaly を記録して false skip を防ぎ、既存の
|
|
20
|
+
public API は維持する。
|
|
21
|
+
- **auditor model**: この release の production default は引き続き `gpt-5.4-mini × low`。GPT-5.6 の
|
|
22
|
+
policy / evaluation は次 patch で扱い、この patch での自動昇格はしない。
|
|
23
|
+
|
|
24
|
+
### 検証
|
|
25
|
+
|
|
26
|
+
`1c67698` の clean worktree から npm pack / temp prefix install / CLI version / Hook install・reinstall を
|
|
27
|
+
smoke し、`node --test` は 383 / 381 pass / 0 fail / 2 skip。targeted test と adversarial review も
|
|
28
|
+
blocker 0。OS CI matrix は macOS / Linux / Windows × Node 22.5.0 / 22.x の全6件が green。
|
|
29
|
+
publish 後の npm / GitHub Release / fresh global install 三者一致確認は残る。
|
|
30
|
+
|
|
31
|
+
## 1.4.16
|
|
32
|
+
|
|
33
|
+
**daemon が異常死した後、残った Unix socket で二度と起動できなくなり、そのセッションが永久に未監査になる
|
|
34
|
+
回復経路バグを根治**。daemon が graceful shutdown を経ずに死ぬ (SIGKILL / crash / マシンスリープで
|
|
35
|
+
SessionEnd 未発火) と、`stop()` の socket unlink が走らず `~/.spotter/runtime/session-<id>.sock` が orphan
|
|
36
|
+
として残る。以後の auto-resurrect (v0.12.0) / SessionStart は `assertNoLiveDaemon` (PID 死亡を確認) を通過
|
|
37
|
+
して `server.listen(path)` に進むが、stale socket が残っているため `EADDRINUSE` で reject され、
|
|
38
|
+
`daemon listening` ログに到達する前に die。auto-resurrect は同じ socket パスへの再 bind を試みて毎回同じ
|
|
39
|
+
`EADDRINUSE` で crash-loop するため、そのセッションは会話を続けても永久に復活せず「Spotter 監査は一時無効
|
|
40
|
+
のまま」になっていた。実セッション (Kikoeru `83d7aa04`) の daemon ログで根本原因を確定: 16:26 正常起動 →
|
|
41
|
+
graceful shutdown ログなしの異常死 → 18:43–19:14 の 5 回 restart が全部 `tool-db loaded` /
|
|
42
|
+
`auditor backend selected` 直後で停止 (listen 未到達)、hook-events は毎ターン `E_UNREACHABLE` /
|
|
43
|
+
`E_RESURRECT_FAILED` の degraded。
|
|
44
|
+
|
|
45
|
+
### 変更点
|
|
46
|
+
|
|
47
|
+
- **編集 [src/daemon/transport.mjs](src/daemon/transport.mjs)**: `removeStaleSocketFile(path)` を新設・
|
|
48
|
+
export。Unix domain socket の orphan ファイルを unlink する。ENOENT (stale ファイルなし = 通常の初回起動)
|
|
49
|
+
は no-op、それ以外のエラーは rethrow (§0: silent swallow 禁止)。Windows は Named Pipe が owner プロセス
|
|
50
|
+
終了で自動消滅するため no-op。
|
|
51
|
+
- **編集 [src/daemon/daemon.mjs](src/daemon/daemon.mjs)**: `startDaemon` が `assertNoLiveDaemon`
|
|
52
|
+
(no-live 確認) 通過後・`server.listen(path)` 前に `removeStaleSocketFile(path)` を呼ぶ。liveness 確認後
|
|
53
|
+
なので socket は確実に orphan であり安全に消せる。
|
|
54
|
+
- **テスト 3 件追加 [test/transport.test.mjs](test/transport.test.mjs)**: (1) stale socket で `listen` が
|
|
55
|
+
`EADDRINUSE` で落ちる挙動を実再現 → `removeStaleSocketFile` 後に fresh daemon が bind & round-trip 成功、
|
|
56
|
+
(2) ENOENT は throw せず no-op、(3) Windows Named Pipe path は no-op (CI Windows matrix で実行)。
|
|
57
|
+
- **追記 [docs/open-issues.md](docs/open-issues.md)**: 解決済みテーブルに本バグを記録 + P0「daemon 突然死」
|
|
58
|
+
節に回復経路修正の相互参照を追加。
|
|
59
|
+
- **付随**: `package-lock.json` の version が 1.4.14 のまま drift していたのを 1.4.16 に同期。
|
|
60
|
+
- `node --test` 348 / 346 pass / 0 fail / 2 skip 緑。
|
|
61
|
+
|
|
62
|
+
設計の主旨: 異常死 (スリープ / 強制終了) は構造的に避けられない前提で、「死なせない」ではなく「死んでも次の
|
|
63
|
+
resurrect で確実に復活する」ことを保証する。これで auto-resurrect (v0.12.0) が stale socket に対しても
|
|
64
|
+
初めて機能する。突然死の根因 (なぜ死ぬか) の観測は open-issues.md P0 で引き続き継続。
|
|
65
|
+
|
|
66
|
+
## 1.4.15
|
|
67
|
+
|
|
68
|
+
**codex ログイン失効でサイレントに死に、host の Claude が無反応になる実害バグを根治**。codex auditor の
|
|
69
|
+
ログインが失効 (`token_revoked` / `refresh_token_reused` / `401 Unauthorized`) すると、`spotter install`
|
|
70
|
+
済みプロジェクトで毎ターン入力が消えて「Claude が一切反応しない」状態になっていた。実セッションの daemon
|
|
71
|
+
ログ (`handler error on user_input/turn_end: E_CODEX_CLI_EXIT`) + コード監査 + 公式 hook 仕様の裏取りで
|
|
72
|
+
根本原因を 2 点に特定: (A) codex 異常終了時、stderr/stdout に入っているログイン失効の痕跡を捨てて全部
|
|
73
|
+
`E_CODEX_CLI_EXIT` に潰しており、auth 失敗を区別できていなかった。(B) `UserPromptSubmit` hook が daemon
|
|
74
|
+
エラーを一律 `die(exit 2)` で処理しており、Claude Code は入力時 hook の exit 2 を **ブロッキング扱い =
|
|
75
|
+
プロンプト消去** とするため、失効が永続する限り毎ターン入力が消えていた。
|
|
76
|
+
|
|
77
|
+
### 変更点
|
|
78
|
+
|
|
79
|
+
- **編集 [src/core/codex-cli-backend.mjs](src/core/codex-cli-backend.mjs)**: codex の非ゼロ終了時に
|
|
80
|
+
stdout+stderr をスキャンし、ログイン失効の痕跡があれば新コード `E_CODEX_CLI_AUTH` (対処法
|
|
81
|
+
「`codex login`」を含むメッセージ) を投げる。痕跡が無ければ従来通り `E_CODEX_CLI_EXIT`。新規 export
|
|
82
|
+
`isCodexAuthFailure`。分類は非ゼロ終了経路のみ (auth 失敗は <1s で即終了するため timeout 経路は対象外)。
|
|
83
|
+
- **編集 [src/hooks/lib.mjs](src/hooks/lib.mjs)**: `formatSpotterWarning({code,message})` を新設
|
|
84
|
+
(`[Spotter からの警告]` ブロック、`E_CODEX_CLI_AUTH` は `codex login` を案内、他は理由コード入りの汎用
|
|
85
|
+
文面)。exit-code 契約コメントを「audit 失敗は loud degradation = exit 0 + additionalContext、exit 2 は
|
|
86
|
+
malformed envelope 専用」に更新。
|
|
87
|
+
- **編集 [src/hooks/user-prompt.mjs](src/hooks/user-prompt.mjs)**: daemon/transport/resurrect 失敗で
|
|
88
|
+
`die(exit 2)` する代わりに `degrade()` — 警告を `additionalContext` (drain 済み pending と merge) で出して
|
|
89
|
+
**exit 0 でプロンプトを通す**。失効に限らずあらゆる監査失敗で host が固まらない。throw 値の `.message`
|
|
90
|
+
アクセスを optional chaining 化し、非 Error throw が top-level catch (exit 2) に抜ける穴も塞いだ。
|
|
91
|
+
- **編集 [src/hooks/stop.mjs](src/hooks/stop.mjs)**: backend/transport エラーと marker 消失 (TOCTOU) で
|
|
92
|
+
`die(exit 2 = 継続強制)` をやめ、`status:"degraded"` 記録 + exit 0。pending は積まない (verdict 未生成)。
|
|
93
|
+
loud な警告は次の `UserPromptSubmit` が配信。
|
|
94
|
+
- **編集 [src/hooks/pre-tool-use.mjs](src/hooks/pre-tool-use.mjs)**: daemon/transport エラーで
|
|
95
|
+
`die(exit 2 = ツール拒否)` をやめ、`status:"degraded"` 記録 + exit 0 (ツール許可)。記録は best-effort
|
|
96
|
+
telemetry でありツールを止める理由にならない。
|
|
97
|
+
- **更新 [docs/02_spotter-claude-contract.md](docs/02_spotter-claude-contract.md)**: `UserPromptSubmit` /
|
|
98
|
+
`PreToolUse` / `Stop` の失敗時 exit-code 契約を新挙動に追従。
|
|
99
|
+
- **追記 [docs/open-issues.md](docs/open-issues.md)**: auth-freeze バグの解決を記録。`Stop` 失敗が
|
|
100
|
+
セッション最終ターンだと deferred-delivery の性質上サイレントになる残課題を P2 に追記。
|
|
101
|
+
- **テスト 11 件追加** ([test/hooks.test.mjs](test/hooks.test.mjs) /
|
|
102
|
+
[test/codex-cli-backend.test.mjs](test/codex-cli-backend.test.mjs)): auth 分類 / `formatSpotterWarning` /
|
|
103
|
+
UserPromptSubmit の loud degrade (auth/汎用/pending merge/resurrect 失敗/非 Error throw) / Stop degrade /
|
|
104
|
+
PreToolUse degrade。`node --test` 344 pass / 1 skip 緑。
|
|
105
|
+
|
|
106
|
+
### 検証
|
|
107
|
+
|
|
108
|
+
実プロジェクトの監査経路 (`createCodexCliAuditorBackend.judge` を実コードで起動) で、再ログイン後に
|
|
109
|
+
`pass` verdict が返ること、および fake spawn でログイン失効 stderr → `E_CODEX_CLI_AUTH` 分類 → hook が
|
|
110
|
+
`[Spotter からの警告]` を additionalContext に出して exit 0 することを確認。多エージェントの敵対的レビュー
|
|
111
|
+
(host-freeze 完全性 / §0 silent-fallback / 分類器精度+docs) で HIGH 2 / MEDIUM 3 を検出し全て反映。
|
|
112
|
+
|
|
3
113
|
## 1.4.14
|
|
4
114
|
|
|
5
115
|
**README 等の公開資産から内部コードネーム "Bell" を撤去**。Spotter の内部設計議論で使われている
|
|
@@ -273,7 +383,7 @@ v1.4.6 までは `SPOTTER_AUDITOR_BACKEND_POLICY=next` を Claude host で立て
|
|
|
273
383
|
test、Claude+`next` で `SPOTTER_AUDITOR_BACKEND=haiku` 明示が依然として Haiku を選ぶ
|
|
274
384
|
互換 test、`createAuditorBackend` factory が `auto` + Claude + `next` で Codex CLI backend を
|
|
275
385
|
返す factory-level test を追加。
|
|
276
|
-
- **編集 [docs/
|
|
386
|
+
- **編集 [docs/02_spotter-claude-contract.md](docs/02_spotter-claude-contract.md)** /
|
|
277
387
|
[docs/archive/SPOTTER_PRIMARY_BACKEND_TODO.md](docs/archive/SPOTTER_PRIMARY_BACKEND_TODO.md) /
|
|
278
388
|
[docs/open-issues.md](docs/open-issues.md):
|
|
279
389
|
Claude host の `current` / `next` policy 表と Phase 5 ゲート、Haiku compatibility が
|
|
@@ -793,11 +903,11 @@ v0.8.0 で claude.ai OAuth 系 MCP (Gmail / Calendar / Drive) を手書き basel
|
|
|
793
903
|
- コマンド表の `spotter db refresh` コメント更新 (「組込み 遅延ツール」削除、v1.1.0 以降は通常不要な旨追記)、`spotter db rebuild` の挙動を local+global wipe に訂正
|
|
794
904
|
- 設計ドキュメント節を 4 本立て (catalog-design / open-issues / CLAUDE.md §0 / spotter-plan 歴史記録) に再編
|
|
795
905
|
- Haiku timeout 表記を v0.5.0 (30s) → v0.13.1 (45s) に訂正
|
|
796
|
-
- **編集 [docs/
|
|
906
|
+
- **編集 [docs/01_catalog-design.md](docs/01_catalog-design.md)**:
|
|
797
907
|
- 新節「収集タイミング (v1.1.0 以降)」追加 — install 同期 seed / SessionStart bg refresh / db refresh / db rebuild の 4 経路を整理
|
|
798
908
|
- 歴史節に v1.1.x の「収集タイミング自動化」を追記
|
|
799
909
|
- **編集 [docs/archive/spotter-plan.md](docs/archive/spotter-plan.md)**:
|
|
800
|
-
- 冒頭に「v0.1 時点の設計議事録」である旨のブリッジ追加、現行設計の真実源 (
|
|
910
|
+
- 冒頭に「v0.1 時点の設計議事録」である旨のブリッジ追加、現行設計の真実源 (01_catalog-design.md / open-issues.md / CLAUDE.md) へのリンクを明示
|
|
801
911
|
|
|
802
912
|
## 1.1.2
|
|
803
913
|
|
|
@@ -868,14 +978,14 @@ Spotter の役割は「Bell にとって**言われないと思い出さない**
|
|
|
868
978
|
|
|
869
979
|
### 変更点
|
|
870
980
|
|
|
871
|
-
- **削除
|
|
981
|
+
- **削除 `src/tool-db/deferred-baseline.mjs`**: 手書き 17 件の baseline を撤去。`DEFERRED_TOOL_BASELINE` / `getDeferredDescription` / `listDeferredNames` の export も削除 (破壊変更)
|
|
872
982
|
- **新規 [src/tool-db/frontmatter.mjs](src/tool-db/frontmatter.mjs)**: SKILL.md / agent .md の YAML frontmatter から `name` + `description` を抽出する最小パーサー (ゼロ依存)
|
|
873
983
|
- **新規 [src/tool-db/investigate-skills.mjs](src/tool-db/investigate-skills.mjs)**: スキルを 3 scope (user / project / 有効化プラグイン) から収集。プラグイン由来は `<plugin>:<skill>` に名前空間化、ユーザー / プロジェクト由来は素の名前。`enabledPlugins` の有効化判定は user scope + project scope の union、`~/.claude/plugins/installed_plugins.json` の `installPath` から実体にアクセス
|
|
874
984
|
- **新規 [src/tool-db/investigate-agents.mjs](src/tool-db/investigate-agents.mjs)**: サブエージェントを同じく 3 scope から収集。名前は素の名前、衝突は project > user > plugin の優先順で解決
|
|
875
985
|
- **編集 [src/tool-db/refresh.mjs](src/tool-db/refresh.mjs)**: `buildInvestigationSnapshot` から deferred 経路を削除、スキル / サブエージェント経路を追加。MCP live fetch + `claude.ai` baseline (Gmail / Calendar / Drive) は維持
|
|
876
986
|
- **編集 [src/cli/db-cmd.mjs](src/cli/db-cmd.mjs)**: `spotter db rebuild` が local DB に加えて **global DB も wipe** するように仕様変更。旧バージョンから上がってきたユーザーが古い deferred エントリを抱えたままにならないため
|
|
877
987
|
- **編集 [src/index.mjs](src/index.mjs)**: `listSkillsAll` / `listActivePlugins` / `listAgentsAll` の export 追加
|
|
878
|
-
- **リネーム [docs/catalog-design-deferred-mcp.md](docs/
|
|
988
|
+
- **リネーム [docs/catalog-design-deferred-mcp.md](docs/01_catalog-design.md) → [docs/01_catalog-design.md](docs/01_catalog-design.md)**: 大幅書き直し。対象範囲・分類軸・収集経路を v1.0.0 仕様で更新
|
|
879
989
|
- **テスト更新 [test/tool-db.test.mjs](test/tool-db.test.mjs)**: deferred baseline テスト 3 件削除、frontmatter テスト 3 件 + skill テスト 2 件 + agent テスト 2 件を追加。計 32 件全通過
|
|
880
990
|
|
|
881
991
|
### 結果
|
|
@@ -903,7 +1013,7 @@ preamble 初回送信サイズ推定 15-25K tokens (Haiku 4.5 の 200K コンテ
|
|
|
903
1013
|
|
|
904
1014
|
## 0.13.3
|
|
905
1015
|
|
|
906
|
-
**カタログ外ツール名の推奨を遮断 (prompt 明示 + 事後 filter の二重防御)**。v0.13.2 リリース直後の実セッション (
|
|
1016
|
+
**カタログ外ツール名の推奨を遮断 (prompt 明示 + 事後 filter の二重防御)**。v0.13.2 リリース直後の実セッション (`daemon-f047521c.log` line 9) で `turn_end: pass=false, missing=Skill(tl)` を観測。**`Skill(tl)` はカタログ (tool-db.json 57 件) に存在しない**。Haiku が training 記憶 or few-shot の `current_time` / `Skill` 表記から cargo-cult してカタログ外名を提案していた。これが恒常化するとユーザーが無効な推奨に混乱する + /tl など description を直しても Haiku は参照していないため修正が届かない、という構造問題になる。
|
|
907
1017
|
|
|
908
1018
|
### 変更点
|
|
909
1019
|
|
|
@@ -925,7 +1035,7 @@ preamble 初回送信サイズ推定 15-25K tokens (Haiku 4.5 の 200K コンテ
|
|
|
925
1035
|
|
|
926
1036
|
## 0.13.2
|
|
927
1037
|
|
|
928
|
-
**Daemon の死因を必ずログに残す診断インフラ + Haiku 子プロセス stdio の防御的 error listener**。v0.13.1 までは daemon が `uncaughtException` / `unhandledRejection` で死ぬと痕跡ゼロで消えていた (
|
|
1038
|
+
**Daemon の死因を必ずログに残す診断インフラ + Haiku 子プロセス stdio の防御的 error listener**。v0.13.1 までは daemon が `uncaughtException` / `unhandledRejection` で死ぬと痕跡ゼロで消えていた (`daemon-80b5c0af.log` line 15 → line 16 で shutdown ログなしに再起動)。次に同じことが起きた時に真因を必ず捕まえられるよう、診断 handler を導入。
|
|
929
1039
|
|
|
930
1040
|
### 監査の経過と結論
|
|
931
1041
|
|
|
@@ -941,11 +1051,11 @@ preamble 初回送信サイズ推定 15-25K tokens (Haiku 4.5 の 200K コンテ
|
|
|
941
1051
|
### 残課題
|
|
942
1052
|
|
|
943
1053
|
- daemon 突然死の真因特定: **次回再現を待つ**。診断 handler が入ったので、次に死亡した時はログに必ず痕跡が残る。それを見て対処する
|
|
944
|
-
- v0.13.1 で 30s → 45s 緩和した Haiku timeout の効果観測は継続: 現セッション
|
|
1054
|
+
- v0.13.1 で 30s → 45s 緩和した Haiku timeout の効果観測は継続: 現セッション `daemon-69bd2b93.log` line 5 で `mode=first, duration_ms=32703` を観測 (30s 設定なら timeout していた値が 45s で生存)。サンプル 1 件で結論はまだ早い
|
|
945
1055
|
|
|
946
1056
|
## 0.13.1
|
|
947
1057
|
|
|
948
|
-
**Haiku timeout 30s → 45s 緩和 + hook 側 IPC timeout を整合**。v0.13.0 以前の実セッション (
|
|
1058
|
+
**Haiku timeout 30s → 45s 緩和 + hook 側 IPC timeout を整合**。v0.13.0 以前の実セッション (`daemon-80b5c0af.log` line 15) で `E_HAIKU_TIMEOUT: haiku did not respond within 30000ms` を観測。同ログ line 20 でも `mode=first, duration_ms=20948` と 30s の 70% 域まで達しており、timeout が実測レイテンシに対して狭すぎた。合わせて [src/hooks/stop.mjs](src/hooks/stop.mjs) の IPC timeout が元々 15s で Haiku 側 30s と整合していなかった既存バグ (turn_end で Haiku が 16s 超かかると hook 側が先に諦めていた) も同時解消。
|
|
949
1059
|
|
|
950
1060
|
### 調査で判明した Haiku 4.5 の高速化ダイヤル不在
|
|
951
1061
|
|
|
@@ -1066,7 +1176,7 @@ Haiku 突然死 (shutdown ログなしで daemon 再起動する事象、v0.12.0
|
|
|
1066
1176
|
|
|
1067
1177
|
### 事の発端
|
|
1068
1178
|
|
|
1069
|
-
v0.8.0 の `spotter db refresh` 実測で x-api (HTTP MCP) が 401 Unauthorized で落ちていた。`claude mcp list` では `x-api: https://kitepon.
|
|
1179
|
+
v0.8.0 の `spotter db refresh` 実測で x-api (HTTP MCP) が 401 Unauthorized で落ちていた。`claude mcp list` では `x-api: https://kitepon.dev/mcp (HTTP)` と表示され URL は拾えるが、Spotter の refresh プロセスから叩くと認証情報がないため拒否。ユーザーの指摘で `.mcp.json` を直接 cat したところ、実態は **stdio** で `env: {X_BEARER_TOKEN: "..."}` を持つ設定だった。CLI 表示と actual config が食い違っていた (CLI の cache の古さと思われる)。
|
|
1070
1180
|
|
|
1071
1181
|
判明した設計上の転換点:
|
|
1072
1182
|
|
|
@@ -1134,7 +1244,7 @@ v0.7.0 リリース直後、新規セッションで `spotter db refresh` を打
|
|
|
1134
1244
|
|
|
1135
1245
|
Haiku が「Bell が呼び忘れているツール」を判定するには、Bell が今のセッションで実際に呼べるツールを知っている必要がある。v0.6.x までのカタログは `current_time` / `web_search` / `read_file` のような **抽象的な汎用ツール 5 件** を手書きしていただけで、Caveat や Gmail のような MCP ツール、TodoWrite や WebSearch のような Claude Code 組込みの遅延ツールは Haiku の視野に入っていなかった。結果、ユーザーが「過去に解決したナレッジを残したい」と言っても Spotter は Caveat を推奨できないという的外れな状態だった。
|
|
1136
1246
|
|
|
1137
|
-
|
|
1247
|
+
設計思想は現行の [docs/01_catalog-design.md](docs/01_catalog-design.md) に引き継ぎ。要点:
|
|
1138
1248
|
|
|
1139
1249
|
- **Haiku に渡すのは name + description のペアだけ**。schema は不要 — どう呼ぶかは Bell が ToolSearch で解決する責任 (役割分業)
|
|
1140
1250
|
- **MCP ツールの description は MCP サーバーから直接取得**。Spotter は中継者に徹し、手書きで言い換えない (single source of truth = MCP server)
|
|
@@ -1147,7 +1257,7 @@ Haiku が「Bell が呼び忘れているツール」を判定するには、Bel
|
|
|
1147
1257
|
- **新規 [src/tool-db/loader.mjs](src/tool-db/loader.mjs)**: JSON DB の atomic 読み書き、`{version, tools: {name → description}}` スキーマ検証
|
|
1148
1258
|
- **新規 [src/tool-db/lookup.mjs](src/tool-db/lookup.mjs)**: 3 段階 lookup + write-through + drift 補正
|
|
1149
1259
|
- **新規 [src/tool-db/investigate-mcp.mjs](src/tool-db/investigate-mcp.mjs)**: `claude mcp list` / `claude mcp get` で MCP サーバー列挙、stdio サーバーに JSON-RPC で `initialize` + `tools/list` を実行して description 取得
|
|
1150
|
-
- **新規
|
|
1260
|
+
- **新規 `src/tool-db/deferred-baseline.mjs`**: Claude Code 組込み 遅延ツール (WebSearch / TodoWrite / 等 17 件) の手書き description ベースライン (Claude Code 自体は MCP 経由で query できないため)
|
|
1151
1261
|
- **新規 [src/tool-db/refresh.mjs](src/tool-db/refresh.mjs)**: 投資 = 利用可能ツール一覧取得 + 各ツールを 3 段階解決 + DB 書き戻し
|
|
1152
1262
|
- **新規 [src/cli/db-cmd.mjs](src/cli/db-cmd.mjs)**: `spotter db list` / `refresh` / `rebuild`
|
|
1153
1263
|
- **編集 [src/daemon/daemon.mjs](src/daemon/daemon.mjs)**: `loadCatalog` 廃止、`startDaemon({ projectRoot })` で tool-db を読み込み (テスト用に `tools` 直接指定も可)
|
|
@@ -1156,7 +1266,7 @@ Haiku が「Bell が呼び忘れているツール」を判定するには、Bel
|
|
|
1156
1266
|
- **編集 [src/cli/install.mjs](src/cli/install.mjs)**: `tool-catalog/` 作成と template コピー削除、install 完了時に `spotter db refresh` 実行を案内
|
|
1157
1267
|
- **編集 [src/cli/doctor.mjs](src/cli/doctor.mjs)**: catalog チェック → tool-db (global + local) のチェック
|
|
1158
1268
|
- **編集 [bin/spotter.mjs](bin/spotter.mjs)**: `spotter catalog edit/lint` を `spotter db list/refresh/rebuild` に置換
|
|
1159
|
-
- **削除**:
|
|
1269
|
+
- **削除**: `src/catalog/`, `src/cli/catalog.mjs`, `templates/tools.yaml`, `test/catalog.test.mjs`, `test/loader.test.mjs`
|
|
1160
1270
|
- **新規 [test/tool-db.test.mjs](test/tool-db.test.mjs)**: 21 件 (loader/lookup/investigate-mcp/deferred-baseline)
|
|
1161
1271
|
|
|
1162
1272
|
### Breaking
|
package/README.ja.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
Claude には「使えるツールがあるのに、使うべきタイミングで使わない」という構造的な弱点があります。記録すべき決定を memory / caveat MCP に残さない、docs lookup MCP を呼ばずに古い知識で応答する、ブラウザ自動化 MCP で確認せず UI 状態を推測する — **「分からないと自覚できない」から、ツールを取りに行けない**。
|
|
17
17
|
|
|
18
|
-
Spotter
|
|
18
|
+
Spotter はツールカタログを完全に把握した別の監査エージェントで、ユーザー入力と主役 AI の応答を並走監査します。自動選択では Claude host は Codex CLI があればそれを、なければ session-scoped Haiku を選び、Codex host は Codex CLI を既定にします。明示 backend override は host より優先しますが、runtime failure で別 backend へ黙って切り替えません。見落としは透明化された指摘として次に利用できる文脈へ届けます。**主役 AI が自覚して自己監査する**設計は本プロダクトの存在意義を破壊するため、hook 経由でその意思と独立に検出します。
|
|
19
19
|
|
|
20
20
|
<p align="center">
|
|
21
21
|
<img src=".github/concept.svg" alt="Claude が答え、Spotter が見ている" width="80%">
|
|
@@ -59,6 +59,7 @@ Homebrew で Node が更新されても Codex hook が古い Node パスに取
|
|
|
59
59
|
`v0.3.0` 以降は**プロジェクト単位の明示的 install** を採用しています (v0.2 までの `postinstall` 自動登録はデーモン増殖の主因だったため撤回)。各プロジェクトの `.claude/settings.json` に hook を登録し、そのプロジェクトでの Claude Code セッションのみで有効になります。
|
|
60
60
|
Codex CLI が使える環境では、同じ `spotter install` が user-level の Codex native hooks も登録します。実際に動くプロジェクトは `spotter install` が作る `.spotter/marker.json` で制限されるため、無関係な Codex セッションでは Spotter は起動しません。
|
|
61
61
|
Codex 側では現行の `[features].hooks = true` を有効化し、互換のため旧 `codex_hooks` diagnostics output も認識します。
|
|
62
|
+
Spotter が所有する Codex handler は現行の同期 command schema で生成します。install / upgrade 後は `/hooks` で review して新しい Codex session を開いてください。`spotter codex-hook diagnostics` は登録と readiness を診断しますが、trust を内部状態から推測しません。
|
|
62
63
|
|
|
63
64
|
Spotter を upgrade した後、release note で hook 設定変更が案内されている場合は、各 install 済みプロジェクトで `spotter install` を再実行してください。global package update でコード経路は変わりますが、既存 `.claude/settings.json` の timeout 値は自動では書き換わりません。
|
|
64
65
|
|
|
@@ -80,8 +81,8 @@ spotter codex-hook install
|
|
|
80
81
|
|
|
81
82
|
- **Node.js 22.5 以上**
|
|
82
83
|
- **Claude Code 2.0 以上**
|
|
83
|
-
-
|
|
84
|
-
- **
|
|
84
|
+
- **Codex CLI**。Codex native hooks の既定 backend と Claude host の優先 auditor path で使います。自動選択後の runtime failure で Haiku へ fallback しません
|
|
85
|
+
- **Claude Max プラン**は Claude host が Haiku path を選ぶ場合だけ必要です(Codex CLI 不在、または `SPOTTER_AUDITOR_BACKEND=haiku` 明示時)
|
|
85
86
|
|
|
86
87
|
## アーキテクチャ
|
|
87
88
|
|
|
@@ -126,7 +127,7 @@ flowchart LR
|
|
|
126
127
|
SK --> DB
|
|
127
128
|
AG --> DB
|
|
128
129
|
BL --> DB
|
|
129
|
-
DB --> H[
|
|
130
|
+
DB --> H[独立 auditor<br/>Codex CLI があれば優先<br/>なければ session-scoped Haiku]
|
|
130
131
|
```
|
|
131
132
|
|
|
132
133
|
監査対象のツール (name + description) は host-local に分離されます。Claude は `<project>/.spotter/tool-db.json`、Codex は `<project>/.spotter/tool-db.codex.json` を使います。**daemon が監査に使うのは Claude local DB のみ**で、Codex native hooks は Codex local DB を読みます。グローバル description cache も host ごとに分離され、Claude は `~/.spotter/tool-db.json`、Codex は `~/.spotter/tool-db.codex.json` を使います。これらは同じ host の他プロジェクト間でだけ再利用され、監査入力には混ぜません。各 host-local DB は **その host の現時点の discovery 結果と一致** (refresh 時に prune される) するため、別プロジェクトや別 host のツールリストで上書きされることはありません。
|
|
@@ -170,7 +171,7 @@ spotter codex work --findings findings.json --instruction "docs 更新" --approv
|
|
|
170
171
|
spotter codex-hook install
|
|
171
172
|
# Codex native hooks の修復 / 明示登録 (通常は spotter install が実行)
|
|
172
173
|
spotter codex-hook diagnostics
|
|
173
|
-
# Codex
|
|
174
|
+
# Codex hook の登録/readiness を診断。trust は /hooks で review
|
|
174
175
|
spotter uninstall # hook 登録を解除 (~/.spotter は残す)
|
|
175
176
|
```
|
|
176
177
|
|
|
@@ -184,8 +185,10 @@ SPOTTER_CODEX_RISK_CHECK=1 spotter daemon start --session-id ... --project-root
|
|
|
184
185
|
`spotter codex risk-check` に渡します。hook 応答は Codex を待ちません。
|
|
185
186
|
配線だけ確認する場合は `SPOTTER_CODEX_RISK_CHECK_DRY_RUN=1` を併用します。
|
|
186
187
|
|
|
187
|
-
Primary auditor backend policy: Claude hooks
|
|
188
|
-
Codex native hooks は Codex CLI
|
|
188
|
+
Primary auditor backend policy: Claude hooks の auto selection は PATH に Codex CLI があれば Codex CLI、
|
|
189
|
+
なければ Haiku compatibility path。Codex native hooks の auto selection は Codex CLI です。
|
|
190
|
+
`SPOTTER_AUDITOR_BACKEND` の明示 override はどちらの host でも優先し、runtime failure では別 backend へ
|
|
191
|
+
hidden fallback しません。
|
|
189
192
|
Codex 側の SessionStart hook は `.spotter/tool-db.codex.json` を bg refresh し、Claude DB には触れません。
|
|
190
193
|
Codex CLI auditor の子プロセスは、hook 判定を安く速く保つため既定で `gpt-5.4-mini` と
|
|
191
194
|
`model_reasoning_effort="low"` を明示指定します。実測や制御された実験では
|
|
@@ -194,21 +197,23 @@ Codex CLI auditor の子プロセスは、hook 判定を安く速く保つため
|
|
|
194
197
|
|
|
195
198
|
## 設計ドキュメント
|
|
196
199
|
|
|
197
|
-
- **現行設計 (カタログ / 収集経路 / 分類軸)**: [docs/
|
|
200
|
+
- **現行設計 (カタログ / 収集経路 / 分類軸)**: [docs/01_catalog-design.md](docs/01_catalog-design.md) — v1.0.0 以降の真実源
|
|
198
201
|
- **現時点で塞がっていない穴 + 実測未検証の懸念**: [docs/open-issues.md](docs/open-issues.md) — 新規作業に入る前に必読
|
|
199
|
-
- **Runtime contract**: [docs/
|
|
202
|
+
- **Runtime contract**: [docs/02_spotter-claude-contract.md](docs/02_spotter-claude-contract.md) — Claude hook / daemon / Haiku 契約と Codex native hook policy
|
|
200
203
|
- **実装規範と不変条件 (§0)**: [CLAUDE.md](CLAUDE.md) — フォールバック禁止 / silent fallback 禁止 / 暫定コード禁止
|
|
201
204
|
- **Archive**: [docs/archive/](docs/archive/) — 完了済み Codex rollout 計画、primary backend smoke log、v0.1 設計議事録
|
|
202
205
|
|
|
203
206
|
## 既知の制約
|
|
204
207
|
|
|
205
|
-
- v1.4.8 以降、Claude / Codex 両 host で `Stop` hook は **遅延配送 (deferred delivery)**
|
|
208
|
+
- v1.4.8 以降、Claude / Codex 両 host で `Stop` hook は **遅延配送 (deferred delivery)** に統一されています。`Stop` で見落としツールを検出した場合、Spotter は `<projectRoot>/.spotter/pending/<sessionId>.json` に指摘を積み、次の same-session `UserPromptSubmit` で `additionalContext` として配信します。当ターンの最初の応答は transcript にそのまま残ります
|
|
206
209
|
- pending ファイルは Claude / Codex が同じパス (`.spotter/pending/`) を共有します。host-neutral 設計です
|
|
207
|
-
- **JSON スキーマ違反は v0.5.0 以降「想定済み異常」として
|
|
210
|
+
- **Haiku の JSON スキーマ違反は v0.5.0 以降「想定済み異常」として session renew + `role_collapse_reset` で回復**します。**v1.4.15 以降、auditor/daemon の失敗はプロンプトをブロックしません**: `UserPromptSubmit` は `[Spotter からの警告]` を出して exit 0。v1.4.17 では `Stop` 失敗も warning pending に積み、次の same-session prompt で1回配信します。直後に session が終わる場合だけ、配送先となる次 prompt がありません
|
|
208
211
|
|
|
209
212
|
<details>
|
|
210
213
|
<summary><strong>📋 最近のハイライト</strong></summary>
|
|
211
214
|
|
|
215
|
+
- **daemon は異常死しても復活する** (v1.4.16) — daemon が graceful shutdown を経ず死んでも (マシンスリープ / 強制終了 / `SessionEnd` 前の crash)、残った Unix socket が以後の起動を塞がなくなった。`startDaemon` が bind 前に orphan socket を除去するので、次の `UserPromptSubmit` の auto-resurrect が `EADDRINUSE` で crash-loop せずに成功し、「そのセッションが永久に未監査」になる事態を防ぐ
|
|
216
|
+
- **失敗は声に出して縮退、host を固めない** (v1.4.15) — auditor backend が失敗したとき (例: codex のログイン失効) も、`UserPromptSubmit` hook はプロンプトを黙って消さずに `[Spotter からの警告]` を出して通す。codex ログイン失効時は直し方 (`codex login`) を明示する
|
|
212
217
|
- **プラグイン形式の MCP サーバー対応** — `plugin:everything-claude-code:context7` のように名前に内部コロンを含むサーバーを正しくパースし、配下のツールをカタログに取り込めるようになった (旧版はこの形式のサーバーをすべて単一の `"plugin"` に潰して、Claude の監査から silent に脱落させていた)
|
|
213
218
|
- **プロジェクト単位の監査隔離** — daemon が監査に使うのはローカル DB のみ。グローバル DB は description 再利用キャッシュに役割限定。**他プロジェクト**でインストールしたツールが現プロジェクトの監査に混入することはない
|
|
214
219
|
- **手放しでカタログ維持** — `spotter install` が Claude DB を自動 seed、Claude / Codex それぞれの SessionStart が host-local DB を bg refresh する。手書き管理は一切不要
|
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
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
|
|
18
|
+
Spotter runs a separate auditor with the full tool catalog and checks both the user's prompt and the primary agent's reply. Automatic selection uses Codex CLI on a Claude host when available, otherwise the session-scoped Haiku path; on a Codex host it defaults to Codex CLI. An explicit backend override takes precedence, but a runtime failure never silently switches backend. When Spotter finds a missed tool, it injects a transparent recommendation into the next available context. **The primary agent is never asked to self-audit** — that would defeat the premise. Detection happens through hooks, independent of the primary agent's intent.
|
|
19
19
|
|
|
20
20
|
<p align="center">
|
|
21
21
|
<img src=".github/concept.svg" alt="Claude answers · Spotter watches" width="80%">
|
|
@@ -59,6 +59,7 @@ Codex hooks working across Homebrew Node upgrades.
|
|
|
59
59
|
Since `v0.3.0`, Spotter requires **explicit per-project install** (the earlier `postinstall` auto-registration was the leading cause of orphan daemons). `spotter install` writes hooks into the project's `.claude/settings.json`; the audit is then active only in Claude Code sessions for that project.
|
|
60
60
|
When the Codex CLI is available, the same `spotter install` also registers user-level Codex native hooks. Project activation still depends on the same per-project `.spotter/marker.json`, so unrelated Codex sessions do not trigger Spotter.
|
|
61
61
|
For Codex, install enables the current `[features].hooks = true` flag and still recognizes older `codex_hooks` diagnostics output for compatibility.
|
|
62
|
+
Installer-owned Codex handlers use the current synchronous command schema. After install or upgrade, review them with `/hooks`, then open a fresh Codex session; `spotter codex-hook diagnostics` reports registration/readiness but does not guess hook trust.
|
|
62
63
|
|
|
63
64
|
After upgrading Spotter, re-run `spotter install` in each installed project when release notes mention hook setting changes. The global package update changes the code path, but existing `.claude/settings.json` timeout values are not rewritten automatically.
|
|
64
65
|
|
|
@@ -80,8 +81,8 @@ spotter codex-hook install
|
|
|
80
81
|
|
|
81
82
|
- **Node.js 22.5+**
|
|
82
83
|
- **Claude Code 2.0+**
|
|
83
|
-
- **
|
|
84
|
-
- **
|
|
84
|
+
- **Codex CLI** for the default Codex-native backend and the preferred Claude-host auditor path. The auto-selected Codex backend does not fall back to Haiku after a runtime failure
|
|
85
|
+
- **Claude Max plan** only when a Claude host selects the Haiku path (Codex CLI is absent or `SPOTTER_AUDITOR_BACKEND=haiku` is explicit)
|
|
85
86
|
|
|
86
87
|
## Architecture
|
|
87
88
|
|
|
@@ -126,7 +127,7 @@ flowchart LR
|
|
|
126
127
|
SK --> DB
|
|
127
128
|
AG --> DB
|
|
128
129
|
BL --> DB
|
|
129
|
-
DB --> H[
|
|
130
|
+
DB --> H[Independent auditor<br/>Codex CLI when available<br/>otherwise session-scoped Haiku]
|
|
130
131
|
```
|
|
131
132
|
|
|
132
133
|
The audited catalog is host-local: Claude uses `<project>/.spotter/tool-db.json`, while Codex uses `<project>/.spotter/tool-db.codex.json`. **The daemon audits against the Claude local DB only**, and Codex native hooks read the Codex local DB. Global description caches are host-specific too: Claude uses `~/.spotter/tool-db.json`, while Codex uses `~/.spotter/tool-db.codex.json`. They are shared only across projects for the same host and are never audit sources. Each host-local DB matches that host's **current** discovery snapshot for the project (stale entries are pruned on refresh), so tools from another project or another host cannot overwrite this session's audit catalog.
|
|
@@ -171,7 +172,7 @@ spotter codex work --findings findings.json --instruction "Update docs" --approv
|
|
|
171
172
|
spotter codex-hook install
|
|
172
173
|
# repair / explicitly register Codex native hooks (normally handled by spotter install)
|
|
173
174
|
spotter codex-hook diagnostics
|
|
174
|
-
# check Codex
|
|
175
|
+
# check Codex hook registration/readiness; trust is reviewed with /hooks
|
|
175
176
|
spotter uninstall # remove hooks from this project (leaves ~/.spotter intact)
|
|
176
177
|
```
|
|
177
178
|
|
|
@@ -185,9 +186,10 @@ When enabled, the daemon dispatches `pass:false` findings to `spotter codex risk
|
|
|
185
186
|
in a detached process. Hook responses do not wait for Codex. Add
|
|
186
187
|
`SPOTTER_CODEX_RISK_CHECK_DRY_RUN=1` to exercise the wiring without calling Codex.
|
|
187
188
|
|
|
188
|
-
Primary auditor backend policy: Claude hooks
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
Primary auditor backend policy: Claude hooks automatically select Codex CLI when it is available on PATH,
|
|
190
|
+
otherwise the Haiku-compatible path. Codex native hooks automatically select Codex CLI. An explicit
|
|
191
|
+
`SPOTTER_AUDITOR_BACKEND` override wins on either host; runtime failure never triggers a hidden fallback.
|
|
192
|
+
The Codex SessionStart hook refreshes `.spotter/tool-db.codex.json` in the background
|
|
191
193
|
without touching the Claude DB.
|
|
192
194
|
Codex CLI auditor child processes explicitly use `gpt-5.4-mini` with
|
|
193
195
|
`model_reasoning_effort="low"` by default so hook checks stay cheap and fast;
|
|
@@ -197,21 +199,23 @@ those values for smoke tests or controlled experiments.
|
|
|
197
199
|
|
|
198
200
|
## Design docs
|
|
199
201
|
|
|
200
|
-
- **Current design** (catalog, discovery, classification axes): [docs/
|
|
202
|
+
- **Current design** (catalog, discovery, classification axes): [docs/01_catalog-design.md](docs/01_catalog-design.md) — source of truth from v1.0.0
|
|
201
203
|
- **Open issues + unverified concerns**: [docs/open-issues.md](docs/open-issues.md) — read this before starting new work
|
|
202
|
-
- **Runtime contract**: [docs/
|
|
204
|
+
- **Runtime contract**: [docs/02_spotter-claude-contract.md](docs/02_spotter-claude-contract.md) — Claude hook / daemon / Haiku contract plus Codex native hook policy
|
|
203
205
|
- **Implementation invariants (§0)**: [CLAUDE.md](CLAUDE.md) — no fallbacks, no silent failures, no provisional code
|
|
204
206
|
- **Archived plans and history**: [docs/archive/](docs/archive/) — completed Codex rollout plans, primary backend smoke logs, and the frozen v0.1 design discussion
|
|
205
207
|
|
|
206
208
|
## Known limitations
|
|
207
209
|
|
|
208
|
-
- The `Stop` hook fires **after**
|
|
210
|
+
- The `Stop` hook fires **after** the first answer has already been streamed. Spotter therefore queues a finding for the next same-session prompt instead of rewriting that answer. Detection accuracy in `UserPromptSubmit` (the *pre-response* stage) remains the primary quality axis
|
|
209
211
|
- `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)
|
|
210
|
-
- **Since v0.5.0, JSON schema violations from Haiku are treated as expected
|
|
212
|
+
- **Since v0.5.0, JSON schema violations from Haiku are treated as expected anomalies** (session renew + `role_collapse_reset`). **Since v1.4.15, an auditor/daemon failure no longer blocks the prompt**: `UserPromptSubmit` emits a loud `[Spotter からの警告]` and exits 0. In v1.4.17, a `Stop` failure is queued as the same kind of warning and delivered once on the next same-session prompt. If the session ends immediately, no later prompt exists and that final warning cannot be surfaced
|
|
211
213
|
|
|
212
214
|
<details>
|
|
213
215
|
<summary><strong>📋 Recent highlights</strong></summary>
|
|
214
216
|
|
|
217
|
+
- **Daemon recovers after an ungraceful death** (v1.4.16) — if the daemon dies without graceful shutdown (machine sleep, force-quit, crash before `SessionEnd`), the Unix socket it leaves behind no longer bricks every restart. `startDaemon` removes the orphaned socket before binding, so the next `UserPromptSubmit` auto-resurrect succeeds instead of crash-looping on `EADDRINUSE` and leaving the session permanently unaudited
|
|
218
|
+
- **Failures degrade loudly, never freeze the host** (v1.4.15) — when the auditor backend fails (e.g. codex login expired), the `UserPromptSubmit` hook surfaces a `[Spotter からの警告]` and lets your prompt through instead of silently erasing it. codex login expiry names the one-line fix (`codex login`)
|
|
215
219
|
- **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
|
|
216
220
|
- **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
|
|
217
221
|
- **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
|