claude-spotter 1.3.0 → 1.4.1
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 +49 -2
- package/README.ja.md +55 -16
- package/README.md +56 -17
- package/bin/spotter.mjs +37 -6
- package/package.json +3 -3
- package/scripts/postinstall.mjs +3 -1
- package/src/cli/auditor-cmd.mjs +359 -0
- package/src/cli/codex-cmd.mjs +254 -0
- package/src/cli/codex-hook-cmd.mjs +752 -0
- package/src/cli/db-cmd.mjs +46 -12
- package/src/cli/diagnostics-cmd.mjs +120 -0
- package/src/cli/doctor.mjs +94 -19
- package/src/cli/install.mjs +48 -10
- package/src/core/auditor-backend.mjs +230 -0
- package/src/core/auditor-error.mjs +16 -0
- package/src/core/auditor-response.mjs +96 -0
- package/src/core/codex-cli-backend.mjs +342 -0
- package/src/core/codex-risk-dispatch.mjs +93 -0
- package/src/core/codex-sidecar-auditor-backend.mjs +310 -0
- package/src/core/codex-sidecar-policy.mjs +194 -0
- package/src/core/codex-sidecar-runner.mjs +740 -0
- package/src/core/codex-transcript.mjs +65 -0
- package/src/core/daemon-log-diagnostics.mjs +407 -0
- package/src/core/host-agent.mjs +18 -0
- package/src/core/judgment.mjs +86 -0
- package/src/core/sidecar-context.mjs +117 -0
- package/src/daemon/daemon.mjs +90 -97
- package/src/daemon/haiku-caller.mjs +23 -71
- package/src/daemon/transport.mjs +10 -2
- package/src/hooks/lib.mjs +8 -2
- package/src/hooks/session-start.mjs +9 -4
- package/src/hooks/spawn-daemon.mjs +2 -2
- package/src/hooks/user-prompt.mjs +16 -10
- package/src/index.mjs +70 -1
- package/src/tool-db/frontmatter.mjs +66 -3
- package/src/tool-db/investigate-codex.mjs +241 -0
- package/src/tool-db/investigate-mcp-http.mjs +3 -1
- package/src/tool-db/investigate-mcp.mjs +73 -10
- package/src/tool-db/loader.mjs +16 -3
- package/src/tool-db/refresh.mjs +16 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.4.1
|
|
4
|
+
|
|
5
|
+
**Codex native hooks の有効化手順を `spotter install` に集約する patch release**。v1.4.0 は npm publish まで成功したが、Codex hooks を使うには `spotter codex-hook install` が別手順として残っていた。完成条件を「global npm install 後、各プロジェクトで `spotter install` する以外の手作業を不要にする」と再定義し、Codex CLI がある環境では `spotter install` が Codex hooks も idempotent に登録するようにした。
|
|
6
|
+
|
|
7
|
+
### 変更点
|
|
8
|
+
|
|
9
|
+
- **編集 [src/cli/install.mjs](src/cli/install.mjs)**: project install 時に Codex CLI (`codex --version`) を検出し、存在する場合は `installCodexHooks()` を呼んで `~/.codex/hooks.json` と `[features].codex_hooks = true` を更新する。Codex CLI が無い環境では明示メッセージを出して Codex hooks 登録だけを行わない
|
|
10
|
+
- **編集 [test/install.test.mjs](test/install.test.mjs)**: `spotter install` が Codex CLI presence 時に Codex hooks を登録する回帰テストを追加。既存 refresh 系テストは実ユーザー `~/.codex` を触らないよう DI で固定
|
|
11
|
+
- **編集 README / README.ja / postinstall / CLAUDE.md / open issues**: インストール手順を `npm install -g claude-spotter` → 各プロジェクトで `spotter install` に集約。`spotter codex-hook install` は修復 / 明示登録用 command として残す
|
|
12
|
+
|
|
13
|
+
### ユーザー側で必要な手順
|
|
14
|
+
|
|
15
|
+
1. `npm install -g claude-spotter@1.4.1` で global update
|
|
16
|
+
2. 各プロジェクトで `spotter install` を実行する。Claude hooks、`.spotter/marker.json`、Claude catalog seed が設定され、Codex CLI がある環境では Codex native hooks も登録される
|
|
17
|
+
|
|
18
|
+
## 1.4.0
|
|
19
|
+
|
|
20
|
+
**Codex native hooks を npm 配布可能な完成状態へ昇格する minor bump**。`npm install -g claude-spotter@1.4.0` で `spotter` CLI を global install し、各プロジェクトでは `spotter install`、Codex を使う場合は追加で `spotter codex-hook install` を実行するだけで動く状態にした。手書き tool list や install 時の Codex seed は不要で、Codex 側 catalog は SessionStart hook が自動更新する。
|
|
21
|
+
|
|
22
|
+
### 主要変更
|
|
23
|
+
|
|
24
|
+
- **Codex native hooks**: `spotter codex-hook install|uninstall|diagnostics|session-start|user-prompt-submit|stop` を npm 配布対象として整備。Codex `SessionStart` は `spotter db refresh --host-agent codex` を detached 起動し、Codex tool catalog を `.spotter/tool-db.codex.json` に更新する。Claude `.spotter/tool-db.json` には触れない
|
|
25
|
+
- **Codex primary auditor backend**: Codex host の既定 backend を Codex CLI (`codex exec`) にした。`UserPromptSubmit` / `Stop` は Codex local DB だけを読み、Codex CLI unavailable / schema invalid / non-zero exit / timeout は structured error として surface する。Haiku への hidden fallback はしない
|
|
26
|
+
- **Codex CLI safety**: 子 Codex は read-only sandbox、stdin `ignore`、`model_reasoning_effort="low"`、hook auditor timeout 20s、bounded stderr diagnostics、`--output-schema` / `--output-last-message` を使う。timeout 時も last-message file に schema-valid final JSON があれば `completionReason=last_message_before_process_close` として success 扱いし、process close 遅延による誤 timeout を避ける
|
|
27
|
+
- **再帰 / セッション増殖ガード**: Codex CLI / `codex-sidecar` 子プロセスに `SPOTTER_PARENT_PID`、`SPOTTER_BACKEND`、`SPOTTER_CHILD_BACKEND` を入れ、hook 共通入口 `isChildCall()` がこれらを stdin 読み取り前に検知して return する。Claude 時代に経験した sub-agent / child session 増殖事故の再発を避ける
|
|
28
|
+
- **host-local tool-db 分離**: Claude は `.spotter/tool-db.json`、Codex は `.spotter/tool-db.codex.json` を使う。`spotter db refresh --host-agent codex` は Codex MCP / skills discovery だけを反映し、Claude refresh と相互に prune / overwrite しない
|
|
29
|
+
- **`codex-sidecar` の位置づけ整理**: primary auditor としては明示 override (`SPOTTER_AUDITOR_BACKEND=codex-sidecar`) で使えるが、Codex host default は Codex CLI。`codex-sidecar` は durable result / diagnostics / worktree / MCP boundary を持つ second-pass (`risk-check`, `review`, `explore`, `opinion`) と approved `work` workflow の基盤として残す
|
|
30
|
+
- **diagnostics / docs**: `spotter doctor` に Codex CLI / Codex hooks / `codex-sidecar` readiness を追加。README / README.ja / CLAUDE.md / contract docs / open issues / migration TODO を v1.4.0 の完成条件へ更新
|
|
31
|
+
- **packaging hardening**: npm publish 時に bin が消える罠を避けるため `package.json` の `bin.spotter` を `bin/spotter.mjs` に正規化。package-lock も `1.4.0` に更新。MCP initialize の `clientInfo.version` は `src/version.mjs` 由来にして package version drift を解消
|
|
32
|
+
|
|
33
|
+
### 実測 / 検証
|
|
34
|
+
|
|
35
|
+
- `npm test`: 272 tests, 271 pass, 1 skip
|
|
36
|
+
- Codex native hook smoke: `UserPromptSubmit Completed` / `Stop Completed`
|
|
37
|
+
- Codex hook latency smoke: normal `UserPromptSubmit` 約 7.4s、short `Stop` skip 約 0.08s
|
|
38
|
+
- 4 象限 primary auditor matrix: `claude.codex-cli=10041ms`, `claude.codex-sidecar=12863ms`, `codex.codex-cli=10383ms`, `codex.codex-sidecar=13983ms`
|
|
39
|
+
- `spotter codex risk-check --host-agent codex`: durable `.spotter/sidecar-results/*-codex-risk-check.json` を保存
|
|
40
|
+
- `spotter codex work --dry-run --approve-work --allowed-path ... --remove-worktree --host-agent codex`: scoped work workflow success
|
|
41
|
+
|
|
42
|
+
### ユーザー側で必要な手順
|
|
43
|
+
|
|
44
|
+
1. `npm install -g claude-spotter@1.4.0` で global update
|
|
45
|
+
2. Claude Code で使う各プロジェクトで `spotter install` を実行する。これは `.claude/settings.json` と `.spotter/marker.json` を作り、Claude catalog の初回 seed も実行する
|
|
46
|
+
3. Codex native hooks を使う場合は一度だけ `spotter codex-hook install` を実行する。以後、Codex `SessionStart` が `.spotter/tool-db.codex.json` を自動 refresh する
|
|
47
|
+
4. `spotter doctor` と `spotter codex-hook diagnostics` で global CLI / Codex hooks / tool-db 状態を確認できる
|
|
48
|
+
|
|
3
49
|
## 1.3.0
|
|
4
50
|
|
|
5
51
|
**Haiku spawn 時に user/project の MCP server を一切 load しないよう強制 — WSL2 で観測された CPU 100% 飽和 + 孤児 `npm exec` プロセス累積 + チャット入力無反応 の根本原因を断った minor bump**。修正は `claude -p` 起動引数に `--strict-mcp-config --mcp-config <empty>` を必ず付けるだけの最小実装、副作用なし。
|
|
@@ -41,8 +87,9 @@ WSL2 の CPU 使用率が 100% に張り付き、何かがプロセスを「無
|
|
|
41
87
|
### Chime / Spotter ユーザー側で必要な手順
|
|
42
88
|
|
|
43
89
|
1. `npm install -g claude-spotter@1.3.0` で global update
|
|
44
|
-
2.
|
|
45
|
-
3.
|
|
90
|
+
2. Haiku spawn の MCP-disable は次の SessionStart から自動的に新コードが効く
|
|
91
|
+
3. 既 install プロジェクトでも `spotter install` を再実行して、`.claude/settings.json` の UserPromptSubmit / Stop hook timeout を 60s に更新する (旧 settings の 15s/30s は global update だけでは書き換わらない)
|
|
92
|
+
4. 既存の孤児 daemon があれば `kill <pid>` + `rm ~/.spotter/runtime/session-*.pid` で掃除 (今後は v1.3.0 の MCP-disable で sudden death 自体が大幅減少見込み)
|
|
46
93
|
|
|
47
94
|
## 1.2.6
|
|
48
95
|
|
package/README.ja.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
> **気づく役と実行する役を分離する。** Claude Code の横で並走し、Bell (主役の Claude) が**ツールを呼び忘れたとき**だけ静かに指摘する監査役。
|
|
15
15
|
|
|
16
|
-
Claude
|
|
16
|
+
Claude には「使えるツールがあるのに、使うべきタイミングで使わない」という構造的な弱点があります。記録すべき決定を memory / caveat MCP に残さない、docs lookup MCP を呼ばずに古い知識で応答する、ブラウザ自動化 MCP で確認せず UI 状態を推測する — **「分からないと自覚できない」から、ツールを取りに行けない**。
|
|
17
17
|
|
|
18
18
|
Spotter はツールカタログを完全に把握した別エージェント (Claude Haiku 4.5) をセッション毎に常駐させ、Bell の発話予定と応答を並走監査します。見落としを検出すると透明化された指摘として Bell に届け、補正応答を促します。**Bell が自覚して呼ぶ**設計は本プロダクトの存在意義を破壊するため、Bell から呼ぶのではなく hook 経由で Bell の意思と独立に検出する構造を取っています。
|
|
19
19
|
|
|
@@ -23,17 +23,16 @@ Spotter が拾うのは、たとえばこういう瞬間です。
|
|
|
23
23
|
|
|
24
24
|
| 状況 | Bell の応答 | Spotter の指摘 |
|
|
25
25
|
|---|---|---|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
26
|
+
| 「この OAuth の落とし穴を覚えて」 | 了解だけして進める | memory / caveat MCP の使用機会 |
|
|
27
|
+
| 「このパッケージの最新版 API は?」 | 学習時点の知識で答える | docs lookup MCP の照会機会 |
|
|
28
|
+
| 「この危ない patch をレビューして」 | 自分だけで見直す | reviewer sub-agent の使用機会 |
|
|
29
29
|
| 事実の断定 | 裏付けなしで「〜です」 | 検証用ツールの差し込み余地 |
|
|
30
|
-
| 「このライブラリの最新版の使い方は?」 | 学習データから書き起こす | docs lookup MCP の照会機会 |
|
|
31
30
|
| 「この UI 今もちゃんと動く?」 | コード読みだけで結論 | ブラウザ自動化 MCP の使用機会 |
|
|
32
31
|
| 「以前何を決めたっけ?」 | 推測 / 失念のまま回答 | メモリ / ノート系 MCP の照会機会 |
|
|
33
32
|
|
|
34
33
|
判定軸は 2 段階:
|
|
35
34
|
|
|
36
|
-
- **入力時 (`stage=user_input`)**:
|
|
35
|
+
- **入力時 (`stage=user_input`)**: ユーザー要請に対し、ローカルカタログの description から用途が明確に該当するツールを列挙する **要請充足チェック**
|
|
37
36
|
- **応答後 (`stage=turn_end`)**: Bell の最終応答に対し、事実の断定 / 記録すべき新情報 / 既知情報の参照それぞれに、カタログ上のツール (検証 / 登録 / 照会) を差し込める余地がないかを問う **ツール適用機会の監査**
|
|
38
37
|
|
|
39
38
|
## インストール
|
|
@@ -45,6 +44,9 @@ spotter install
|
|
|
45
44
|
```
|
|
46
45
|
|
|
47
46
|
`v0.3.0` 以降は**プロジェクト単位の明示的 install** を採用しています (v0.2 までの `postinstall` 自動登録はデーモン増殖の主因だったため撤回)。各プロジェクトの `.claude/settings.json` に hook を登録し、そのプロジェクトでの Claude Code セッションのみで有効になります。
|
|
47
|
+
Codex CLI が使える環境では、同じ `spotter install` が user-level の Codex native hooks も登録します。実際に動くプロジェクトは `spotter install` が作る `.spotter/marker.json` で制限されるため、無関係な Codex セッションでは Spotter は起動しません。
|
|
48
|
+
|
|
49
|
+
Spotter を upgrade した後、release note で hook 設定変更が案内されている場合は、各 install 済みプロジェクトで `spotter install` を再実行してください。global package update でコード経路は変わりますが、既存 `.claude/settings.json` の timeout 値は自動では書き換わりません。
|
|
48
50
|
|
|
49
51
|
```bash
|
|
50
52
|
spotter uninstall # このプロジェクトの hook 登録を解除
|
|
@@ -54,7 +56,8 @@ spotter uninstall # このプロジェクトの hook 登録を解除
|
|
|
54
56
|
|
|
55
57
|
- **Node.js 22.5 以上**
|
|
56
58
|
- **Claude Code 2.0 以上**
|
|
57
|
-
-
|
|
59
|
+
- **現行 Claude-backed auditor path では Claude Max プラン** (`claude -p` で Haiku を起動するため)
|
|
60
|
+
- **Codex native hooks では Codex CLI**。Codex host の監査は既定で `codex exec` を使い、Haiku へ fallback しません
|
|
58
61
|
|
|
59
62
|
## アーキテクチャ
|
|
60
63
|
|
|
@@ -91,16 +94,16 @@ flowchart LR
|
|
|
91
94
|
LG["Legacy — ~/.claude/.mcp.json"]
|
|
92
95
|
end
|
|
93
96
|
SCOPES -. merge .-> MCP
|
|
94
|
-
MCP --> DB[(
|
|
97
|
+
MCP --> DB[(ホスト別ローカル tool-db<br/>name + description<br/>プロジェクト単位)]
|
|
95
98
|
SK --> DB
|
|
96
99
|
AG --> DB
|
|
97
100
|
BL --> DB
|
|
98
101
|
DB --> H[Haiku 監査<br/>session-scoped, preamble-once]
|
|
99
102
|
```
|
|
100
103
|
|
|
101
|
-
監査対象のツール (name + description) は `<project>/.spotter/tool-db.json`
|
|
104
|
+
監査対象のツール (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 を読みます。グローバル DB `~/.spotter/tool-db.json` は他プロジェクトでの description 再利用キャッシュとしてのみ機能し、監査入力には混ぜません。各 host-local DB は **その host の現時点の discovery 結果と一致** (refresh 時に prune される) するため、別プロジェクトや別 host のツールリストで上書きされることはありません。
|
|
102
105
|
|
|
103
|
-
**`spotter install`
|
|
106
|
+
**`spotter install` が Claude catalog の初回 seed を自動実行し、Claude Code セッション起動ごとに SessionStart hook が bg で `spotter db refresh` を走らせる**ため、Claude 通常運用で手動コマンドを叩く必要はありません。Codex CLI が使える環境では、同じ `spotter install` が Codex native hooks も登録します。Codex `SessionStart` hook は `spotter db refresh --host-agent codex` を bg 起動して `.spotter/tool-db.codex.json` を更新します。Claude catalog には書き込みません。Claude discovery は `claude mcp list` と Claude skills / sub-agents、Codex discovery は `codex mcp list/get` と Codex skills を読むため、両 host の利用可能ツール差分を別 DB として保持できます。各 MCP サーバーの `tools/list` は JSON-RPC で取得 (HTTP / SSE / stdio transport 対応)、スキルとサブエージェントは frontmatter から直接抽出、claude.ai baseline (OAuth proxy 経由の Gmail / Calendar / Drive 25 件) は Claude 側でのみ `claude mcp list` に該当サーバーが存在する環境で注入されます。**手書きでツールリストを管理する必要はありません**。
|
|
104
107
|
|
|
105
108
|
## Throughline との関係
|
|
106
109
|
|
|
@@ -117,19 +120,54 @@ flowchart LR
|
|
|
117
120
|
## よく使うコマンド
|
|
118
121
|
|
|
119
122
|
```bash
|
|
120
|
-
spotter db list #
|
|
121
|
-
spotter db
|
|
122
|
-
#
|
|
123
|
-
spotter db
|
|
123
|
+
spotter db list # 現在の Claude local tool-db を表示
|
|
124
|
+
spotter db list --host-agent codex
|
|
125
|
+
# 現在の Codex local tool-db を表示
|
|
126
|
+
spotter db refresh # Claude MCP / スキル / サブエージェントから description を収集して Claude DB 更新
|
|
127
|
+
spotter db refresh --host-agent codex
|
|
128
|
+
# Codex MCP / スキルから description を収集して .spotter/tool-db.codex.json を更新
|
|
129
|
+
# (Claude は install + Claude SessionStart、Codex は codex-hook install 後の
|
|
130
|
+
# Codex SessionStart で自動実行されるので通常は不要)
|
|
131
|
+
spotter db rebuild # Claude local + global DB を両方消してから refresh (カタログ設計変更時のクリーン用)
|
|
124
132
|
spotter status # 稼働中の daemon 一覧
|
|
125
|
-
spotter doctor # 環境診断 (Node / claude CLI / tool-db 整合性)
|
|
133
|
+
spotter doctor # 環境診断 (Node / claude CLI / Codex readiness / tool-db 整合性)
|
|
134
|
+
spotter diagnostics logs # daemon log から pass=false / backend latency / anomaly signal を集計
|
|
135
|
+
spotter codex risk-check --findings findings.json --host-agent claude
|
|
136
|
+
# Spotter finding を codex-sidecar に渡して read-only risk analysis
|
|
137
|
+
spotter codex review|explore|opinion --findings findings.json --host-agent claude
|
|
138
|
+
# その他の read-only codex-sidecar second-pass workflow
|
|
139
|
+
spotter codex work --findings findings.json --instruction "docs 更新" --approve-work \
|
|
140
|
+
--allowed-path docs/ --preserve-worktree
|
|
141
|
+
# 承認済み codex-sidecar work を isolated worktree で実行
|
|
142
|
+
spotter codex-hook install
|
|
143
|
+
# Codex native hooks の修復 / 明示登録 (通常は spotter install が実行)
|
|
144
|
+
spotter codex-hook diagnostics
|
|
145
|
+
# Codex hooks feature と Spotter hook 登録を診断
|
|
126
146
|
spotter uninstall # hook 登録を解除 (~/.spotter は残す)
|
|
127
147
|
```
|
|
128
148
|
|
|
149
|
+
Codex risk dispatch を daemon から非同期に流す場合:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
SPOTTER_CODEX_RISK_CHECK=1 spotter daemon start --session-id ... --project-root ...
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
有効時は daemon が `pass:false` finding を detached process の
|
|
156
|
+
`spotter codex risk-check` に渡します。hook 応答は Codex を待ちません。
|
|
157
|
+
配線だけ確認する場合は `SPOTTER_CODEX_RISK_CHECK_DRY_RUN=1` を併用します。
|
|
158
|
+
|
|
159
|
+
Primary auditor backend policy: Claude hooks は現行の Haiku compatibility path を既定のまま維持します。
|
|
160
|
+
Codex native hooks は Codex CLI を既定 backend とし、Haiku へ fallback しません。
|
|
161
|
+
Codex 側の SessionStart hook は `.spotter/tool-db.codex.json` を bg refresh し、Claude DB には触れません。
|
|
162
|
+
明示 smoke には `SPOTTER_AUDITOR_BACKEND=codex-sidecar` も使えます。
|
|
163
|
+
|
|
129
164
|
## 設計ドキュメント
|
|
130
165
|
|
|
131
166
|
- **現行設計 (カタログ / 収集経路 / 分類軸)**: [docs/catalog-design.md](docs/catalog-design.md) — v1.0.0 以降の真実源
|
|
132
167
|
- **現時点で塞がっていない穴 + 実測未検証の懸念**: [docs/open-issues.md](docs/open-issues.md) — 新規作業に入る前に必読
|
|
168
|
+
- **Claude contract capture**: [docs/SPOTTER_CLAUDE_CONTRACT.md](docs/SPOTTER_CLAUDE_CONTRACT.md) — Codex 作業で維持すべき hook / daemon / Haiku の現行契約
|
|
169
|
+
- **Claude / Codex 両対応ブリーフ**: [docs/SPOTTER_CODEX_DUAL_SUPPORT.md](docs/SPOTTER_CODEX_DUAL_SUPPORT.md) と完了済み [TODO](docs/SPOTTER_CODEX_DUAL_SUPPORT_TODO.md) — second-pass `codex-sidecar` workflow
|
|
170
|
+
- **Primary auditor backend migration**: [docs/SPOTTER_PRIMARY_BACKEND_TODO.md](docs/SPOTTER_PRIMARY_BACKEND_TODO.md) — Codex CLI / `codex-sidecar` auditor backend の rollout 状況
|
|
133
171
|
- **実装規範と不変条件 (§0)**: [CLAUDE.md](CLAUDE.md) — フォールバック禁止 / silent fallback 禁止 / 暫定コード禁止
|
|
134
172
|
- **歴史記録 (v0.1 時点の設計議事録)**: [docs/spotter-plan.md](docs/spotter-plan.md) — 作成時点で固定された議論過程のスナップショット、現行設計は上記 3 点を参照
|
|
135
173
|
|
|
@@ -143,7 +181,8 @@ spotter uninstall # hook 登録を解除 (~/.spotter は残す)
|
|
|
143
181
|
|
|
144
182
|
- **プラグイン形式の MCP サーバー対応** — `plugin:everything-claude-code:context7` のように名前に内部コロンを含むサーバーを正しくパースし、配下のツールをカタログに取り込めるようになった (旧版はこの形式のサーバーをすべて単一の `"plugin"` に潰して、Bell の監査から silent に脱落させていた)
|
|
145
183
|
- **プロジェクト単位の監査隔離** — daemon が監査に使うのはローカル DB のみ。グローバル DB は description 再利用キャッシュに役割限定。**他プロジェクト**でインストールしたツールが現プロジェクトの監査に混入することはない
|
|
146
|
-
- **手放しでカタログ維持** — `spotter install` が
|
|
184
|
+
- **手放しでカタログ維持** — `spotter install` が Claude DB を自動 seed、Claude / Codex それぞれの SessionStart が host-local DB を bg refresh する。手書き管理は一切不要
|
|
185
|
+
- **Codex native hooks** — Codex host は primary auditor backend として Codex CLI を使い、`.spotter/tool-db.codex.json` を Claude DB と分離し、backend failure は Haiku fallback ではなく明示 error として扱う
|
|
147
186
|
- **監査対象** — ユーザー追加分 (MCP / スキル / サブエージェント) のみ。Claude Code 本体側のツールは意図的に対象外 (Bell は元から自発率が高いため)
|
|
148
187
|
- **実装規範** — フォールバック禁止 / silent fallback 禁止 / 暫定コード禁止 ([CLAUDE.md §0](CLAUDE.md))
|
|
149
188
|
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
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**.
|
|
15
15
|
|
|
16
|
-
Claude has a structural blind spot: **it can't reach for a tool it doesn't realize it needs**. It
|
|
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
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.
|
|
19
19
|
|
|
@@ -23,17 +23,16 @@ Examples of what Spotter catches:
|
|
|
23
23
|
|
|
24
24
|
| Situation | What Bell would do | What Spotter flags |
|
|
25
25
|
|---|---|---|
|
|
26
|
-
| "
|
|
27
|
-
| "
|
|
28
|
-
| "
|
|
26
|
+
| "Please remember this OAuth gotcha" | Acknowledge and move on | Missed call to a memory / caveat MCP |
|
|
27
|
+
| "How does this package API work in the latest version?" | Answer from training-time knowledge | Missed call to a docs-lookup MCP |
|
|
28
|
+
| "Review this risky patch" | Self-review only | Missed call to a reviewer sub-agent |
|
|
29
29
|
| Asserting a fact | State it without verification | Opportunity to call a verification tool |
|
|
30
|
-
| "How does this library API work in the latest version?" | Recite from training data | Missed call to a docs-lookup MCP |
|
|
31
30
|
| "Does this UI still render correctly?" | Reason from source code alone | Missed call to a browser-automation MCP |
|
|
32
31
|
| "What did we decide about X earlier?" | Guess or admit forgetting | Missed call to a memory / notes MCP |
|
|
33
32
|
|
|
34
33
|
Spotter audits in two stages:
|
|
35
34
|
|
|
36
|
-
- **`stage=user_input`** — given the user's prompt, list any tools whose
|
|
35
|
+
- **`stage=user_input`** — given the user's prompt, list any local catalog tools whose description clearly applies. A *prompt-fulfillment* check
|
|
37
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
|
|
38
37
|
|
|
39
38
|
## Install
|
|
@@ -45,6 +44,9 @@ spotter install
|
|
|
45
44
|
```
|
|
46
45
|
|
|
47
46
|
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.
|
|
47
|
+
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.
|
|
48
|
+
|
|
49
|
+
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.
|
|
48
50
|
|
|
49
51
|
```bash
|
|
50
52
|
spotter uninstall # remove hooks from this project
|
|
@@ -54,7 +56,8 @@ spotter uninstall # remove hooks from this project
|
|
|
54
56
|
|
|
55
57
|
- **Node.js 22.5+**
|
|
56
58
|
- **Claude Code 2.0+**
|
|
57
|
-
- **Claude Max plan** (Spotter spawns Haiku via `claude -p`)
|
|
59
|
+
- **Claude Max plan** for the current Claude-backed auditor path (Spotter spawns Haiku via `claude -p`)
|
|
60
|
+
- **Codex CLI** for Codex native hooks. Codex host auditing uses `codex exec` by default and does not fall back to Haiku
|
|
58
61
|
|
|
59
62
|
## Architecture
|
|
60
63
|
|
|
@@ -91,16 +94,16 @@ flowchart LR
|
|
|
91
94
|
LG["Legacy — ~/.claude/.mcp.json"]
|
|
92
95
|
end
|
|
93
96
|
SCOPES -. merged into .-> MCP
|
|
94
|
-
MCP --> DB[(
|
|
97
|
+
MCP --> DB[(Host-local tool-db<br/>name + description<br/>per project)]
|
|
95
98
|
SK --> DB
|
|
96
99
|
AG --> DB
|
|
97
100
|
BL --> DB
|
|
98
101
|
DB --> H[Haiku audit<br/>session-scoped, preamble-once]
|
|
99
102
|
```
|
|
100
103
|
|
|
101
|
-
The audited catalog
|
|
104
|
+
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. The global DB at `~/.spotter/tool-db.json` is a description-reuse cache shared across projects, not an audit source. 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.
|
|
102
105
|
|
|
103
|
-
**`spotter install` seeds the catalog automatically, and the SessionStart hook runs a background `spotter db refresh` on every Claude Code session start** — so you don't need to invoke catalog commands by hand. Each MCP server's `tools/list` is fetched via JSON-RPC (HTTP / SSE / stdio transports supported); skill and sub-agent metadata comes straight from frontmatter; the claude.ai baseline (25 hand-curated entries for Gmail / Calendar / Drive over OAuth proxy) is injected only when `claude mcp list` confirms the server is present. **You never have to maintain the tool list by hand.**
|
|
106
|
+
**`spotter install` seeds the Claude catalog automatically, and the SessionStart hook runs a background `spotter db refresh` on every Claude Code session start** — so you don't need to invoke Claude catalog commands by hand. When Codex CLI is available, the same `spotter install` registers Codex native hooks; their `SessionStart` hook starts `spotter db refresh --host-agent codex` in the background, updating `.spotter/tool-db.codex.json` without touching the Claude catalog. Claude discovery reads `claude mcp list` plus Claude skills / sub-agents; Codex discovery reads `codex mcp list/get` plus Codex skills. Each MCP server's `tools/list` is fetched via JSON-RPC (HTTP / SSE / stdio transports supported); skill and sub-agent metadata comes straight from frontmatter; the claude.ai baseline (25 hand-curated entries for Gmail / Calendar / Drive over OAuth proxy) is injected only for Claude when `claude mcp list` confirms the server is present. **You never have to maintain the tool list by hand.**
|
|
104
107
|
|
|
105
108
|
## Spotter and Throughline
|
|
106
109
|
|
|
@@ -117,21 +120,56 @@ Both share the principle of **"don't rely on the primary agent (Bell) to do it i
|
|
|
117
120
|
## Common commands
|
|
118
121
|
|
|
119
122
|
```bash
|
|
120
|
-
spotter db list # show the current local tool-db
|
|
121
|
-
spotter db
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
spotter db
|
|
123
|
+
spotter db list # show the current Claude local tool-db
|
|
124
|
+
spotter db list --host-agent codex
|
|
125
|
+
# show the current Codex local tool-db
|
|
126
|
+
spotter db refresh # rediscover Claude MCP / skills / sub-agents and update the Claude DB
|
|
127
|
+
spotter db refresh --host-agent codex
|
|
128
|
+
# rediscover Codex MCP / skills and update .spotter/tool-db.codex.json
|
|
129
|
+
# (Claude refresh is automatic on install + Claude SessionStart;
|
|
130
|
+
# Codex refresh is automatic on Codex SessionStart after codex-hook install)
|
|
131
|
+
spotter db rebuild # wipe Claude local + global DBs and refresh from scratch
|
|
125
132
|
# (use after catalog-shape changes)
|
|
126
133
|
spotter status # list running daemons
|
|
127
|
-
spotter doctor # environment check (Node / claude CLI / tool-db integrity)
|
|
134
|
+
spotter doctor # environment check (Node / claude CLI / Codex readiness / tool-db integrity)
|
|
135
|
+
spotter diagnostics logs # summarize daemon logs for pass=false / backend latency / anomaly signals
|
|
136
|
+
spotter codex risk-check --findings findings.json --host-agent claude
|
|
137
|
+
# run read-only codex-sidecar risk analysis for Spotter findings
|
|
138
|
+
spotter codex review|explore|opinion --findings findings.json --host-agent claude
|
|
139
|
+
# run other read-only codex-sidecar second-pass workflows
|
|
140
|
+
spotter codex work --findings findings.json --instruction "Update docs" --approve-work \
|
|
141
|
+
--allowed-path docs/ --preserve-worktree
|
|
142
|
+
# run approved codex-sidecar work in an isolated worktree
|
|
143
|
+
spotter codex-hook install
|
|
144
|
+
# repair / explicitly register Codex native hooks (normally handled by spotter install)
|
|
145
|
+
spotter codex-hook diagnostics
|
|
146
|
+
# check Codex hooks feature and Spotter hook entries
|
|
128
147
|
spotter uninstall # remove hooks from this project (leaves ~/.spotter intact)
|
|
129
148
|
```
|
|
130
149
|
|
|
150
|
+
Optional async Codex risk dispatch:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
SPOTTER_CODEX_RISK_CHECK=1 spotter daemon start --session-id ... --project-root ...
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
When enabled, the daemon dispatches `pass:false` findings to `spotter codex risk-check`
|
|
157
|
+
in a detached process. Hook responses do not wait for Codex. Add
|
|
158
|
+
`SPOTTER_CODEX_RISK_CHECK_DRY_RUN=1` to exercise the wiring without calling Codex.
|
|
159
|
+
|
|
160
|
+
Primary auditor backend policy: Claude hooks keep the current Haiku-compatible path by
|
|
161
|
+
default. Codex native hooks use Codex CLI by default and do not fall back to Haiku;
|
|
162
|
+
their SessionStart hook refreshes `.spotter/tool-db.codex.json` in the background
|
|
163
|
+
without touching the Claude DB.
|
|
164
|
+
`SPOTTER_AUDITOR_BACKEND=codex-sidecar` is available for explicit sidecar auditor smoke.
|
|
165
|
+
|
|
131
166
|
## Design docs
|
|
132
167
|
|
|
133
168
|
- **Current design** (catalog, discovery, classification axes): [docs/catalog-design.md](docs/catalog-design.md) — source of truth from v1.0.0
|
|
134
169
|
- **Open issues + unverified concerns**: [docs/open-issues.md](docs/open-issues.md) — read this before starting new work
|
|
170
|
+
- **Claude contract capture**: [docs/SPOTTER_CLAUDE_CONTRACT.md](docs/SPOTTER_CLAUDE_CONTRACT.md) — current hook / daemon / Haiku behavior that Codex work must preserve
|
|
171
|
+
- **Claude / Codex dual-support brief**: [docs/SPOTTER_CODEX_DUAL_SUPPORT.md](docs/SPOTTER_CODEX_DUAL_SUPPORT.md) and completed [TODO](docs/SPOTTER_CODEX_DUAL_SUPPORT_TODO.md) — second-pass `codex-sidecar` workflows
|
|
172
|
+
- **Primary auditor backend migration**: [docs/SPOTTER_PRIMARY_BACKEND_TODO.md](docs/SPOTTER_PRIMARY_BACKEND_TODO.md) — Codex CLI / `codex-sidecar` auditor backend rollout status
|
|
135
173
|
- **Implementation invariants (§0)**: [CLAUDE.md](CLAUDE.md) — no fallbacks, no silent failures, no provisional code
|
|
136
174
|
- **Historical record (v0.1 design discussion)**: [docs/spotter-plan.md](docs/spotter-plan.md) — frozen design-discussion snapshot
|
|
137
175
|
|
|
@@ -145,7 +183,8 @@ spotter uninstall # remove hooks from this project (leaves ~/.spotter int
|
|
|
145
183
|
|
|
146
184
|
- **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
|
|
147
185
|
- **Per-project audit isolation** — the daemon audits against the local DB only; the global DB has been demoted to a description-reuse cache. Tools discovered in *other* projects can never bleed into this project's audit set
|
|
148
|
-
- **Zero-touch catalog** — `spotter install` seeds the
|
|
186
|
+
- **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
|
|
187
|
+
- **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
|
|
149
188
|
- **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
|
|
150
189
|
- **Implementation invariants** — no fallbacks, no silent failures, no provisional code (see [§0 in CLAUDE.md](CLAUDE.md))
|
|
151
190
|
|
package/bin/spotter.mjs
CHANGED
|
@@ -7,6 +7,10 @@ import { runUninstall } from '../src/cli/uninstall.mjs';
|
|
|
7
7
|
import { runDoctor } from '../src/cli/doctor.mjs';
|
|
8
8
|
import { runStatus } from '../src/cli/status.mjs';
|
|
9
9
|
import { runDbList, runDbRefresh, runDbRebuild } from '../src/cli/db-cmd.mjs';
|
|
10
|
+
import { runCodexCommand } from '../src/cli/codex-cmd.mjs';
|
|
11
|
+
import { runCodexHookCommand } from '../src/cli/codex-hook-cmd.mjs';
|
|
12
|
+
import { runAuditorCommand } from '../src/cli/auditor-cmd.mjs';
|
|
13
|
+
import { runDiagnosticsCommand } from '../src/cli/diagnostics-cmd.mjs';
|
|
10
14
|
import { runDaemonStart } from '../src/cli/daemon-cmd.mjs';
|
|
11
15
|
import { runSessionStart } from '../src/hooks/session-start.mjs';
|
|
12
16
|
import { runUserPrompt } from '../src/hooks/user-prompt.mjs';
|
|
@@ -26,11 +30,26 @@ Usage:
|
|
|
26
30
|
spotter uninstall [-y] remove spotter hooks from <cwd>/.claude/settings.json
|
|
27
31
|
and remove <cwd>/.spotter/marker.json
|
|
28
32
|
spotter uninstall --user [-y] remove from ~/.claude/settings.json
|
|
29
|
-
spotter db list
|
|
30
|
-
spotter db refresh
|
|
31
|
-
|
|
33
|
+
spotter db list [--host-agent HOST] show host-local tool-db (claude by default)
|
|
34
|
+
spotter db refresh [--host-agent HOST]
|
|
35
|
+
discover MCP / skills / sub-agents and update DB
|
|
36
|
+
spotter db rebuild [--host-agent HOST]
|
|
37
|
+
wipe host-local + global DBs then refresh
|
|
32
38
|
spotter status show running daemons
|
|
33
39
|
spotter doctor environment diagnostic
|
|
40
|
+
spotter diagnostics logs [--json] summarize daemon logs for precision diagnostics
|
|
41
|
+
spotter codex risk-check --findings FILE
|
|
42
|
+
run read-only codex-sidecar risk analysis
|
|
43
|
+
spotter codex review|explore|opinion --findings FILE
|
|
44
|
+
run read-only codex-sidecar second-pass workflows
|
|
45
|
+
spotter codex work --findings FILE --approve-work --allowed-path PATH
|
|
46
|
+
run approved codex-sidecar worktree workflow
|
|
47
|
+
spotter codex-hook install|uninstall|diagnostics
|
|
48
|
+
(experimental) manage Codex native hooks
|
|
49
|
+
spotter auditor judge --stage STAGE --input FILE
|
|
50
|
+
(experimental) run primary auditor backend once
|
|
51
|
+
spotter auditor matrix --stage STAGE --input FILE
|
|
52
|
+
(experimental) compare primary auditor backend matrix
|
|
34
53
|
spotter daemon start --session-id ID (internal) run session daemon
|
|
35
54
|
spotter hook <event> (internal) hook dispatch
|
|
36
55
|
events: session-start | user-prompt |
|
|
@@ -67,9 +86,9 @@ async function main() {
|
|
|
67
86
|
}
|
|
68
87
|
case 'db': {
|
|
69
88
|
const sub = rest[0];
|
|
70
|
-
if (sub === 'list') { await runDbList(); return; }
|
|
71
|
-
if (sub === 'refresh') { await runDbRefresh(); return; }
|
|
72
|
-
if (sub === 'rebuild') { await runDbRebuild(); return; }
|
|
89
|
+
if (sub === 'list') { await runDbList({ argv: rest.slice(1) }); return; }
|
|
90
|
+
if (sub === 'refresh') { await runDbRefresh({ argv: rest.slice(1) }); return; }
|
|
91
|
+
if (sub === 'rebuild') { await runDbRebuild({ argv: rest.slice(1) }); return; }
|
|
73
92
|
process.stderr.write(`unknown db subcommand: ${sub}\n${USAGE}`);
|
|
74
93
|
process.exit(2);
|
|
75
94
|
return;
|
|
@@ -80,6 +99,18 @@ async function main() {
|
|
|
80
99
|
case 'doctor':
|
|
81
100
|
await runDoctor();
|
|
82
101
|
return;
|
|
102
|
+
case 'codex':
|
|
103
|
+
await runCodexCommand({ argv: rest });
|
|
104
|
+
return;
|
|
105
|
+
case 'codex-hook':
|
|
106
|
+
await runCodexHookCommand({ argv: rest });
|
|
107
|
+
return;
|
|
108
|
+
case 'auditor':
|
|
109
|
+
await runAuditorCommand({ argv: rest });
|
|
110
|
+
return;
|
|
111
|
+
case 'diagnostics':
|
|
112
|
+
await runDiagnosticsCommand({ argv: rest });
|
|
113
|
+
return;
|
|
83
114
|
case 'daemon': {
|
|
84
115
|
const sub = rest[0];
|
|
85
116
|
if (sub === 'start') { await runDaemonStart({ argv: rest.slice(1) }); return; }
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-spotter",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Audit agent running alongside Claude Code that catches missed tool calls — 気づく役と実行する役の分離",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
|
-
"spotter": "
|
|
7
|
+
"spotter": "bin/spotter.mjs"
|
|
8
8
|
},
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./src/index.mjs"
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
|
-
"url": "https://github.com/kitepon-rgb/Spotter.git"
|
|
30
|
+
"url": "git+https://github.com/kitepon-rgb/Spotter.git"
|
|
31
31
|
},
|
|
32
32
|
"bugs": {
|
|
33
33
|
"url": "https://github.com/kitepon-rgb/Spotter/issues"
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -22,8 +22,10 @@ if (process.env.CI === 'true' || process.env.CI === '1') {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
console.log('claude-spotter installed.');
|
|
25
|
-
console.log(' Next step
|
|
25
|
+
console.log(' Next step for Claude Code projects you want audited:');
|
|
26
26
|
console.log(' cd <your-project>');
|
|
27
27
|
console.log(' spotter install');
|
|
28
28
|
console.log(' This writes hooks to <project>/.claude/settings.json and a .spotter/');
|
|
29
29
|
console.log(' marker so unrelated `claude -p` invocations do not trigger Spotter.');
|
|
30
|
+
console.log(' If Codex CLI is installed, `spotter install` also registers Codex hooks.');
|
|
31
|
+
console.log(' Codex hooks refresh .spotter/tool-db.codex.json on SessionStart.');
|