claude-spotter 1.4.0 → 1.4.2
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 +29 -0
- package/README.ja.md +3 -5
- package/README.md +3 -5
- package/package.json +2 -2
- package/scripts/postinstall.mjs +1 -2
- package/src/cli/install.mjs +36 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.4.2
|
|
4
|
+
|
|
5
|
+
**既存 project の hook command path を npm global 版へ更新する patch release**。v1.4.1 の `spotter install` は Codex hooks を自動登録するようになったが、既存 `.claude/settings.json` に `spotter.mjs` hook がある場合、登録済み判定で timeout だけ更新し、command path を現在の package root へ差し替えていなかった。local checkout 由来の hook が残ると、global npm update 後も古い checkout を呼び続け得るため修正。
|
|
6
|
+
|
|
7
|
+
### 変更点
|
|
8
|
+
|
|
9
|
+
- **編集 [src/cli/install.mjs](src/cli/install.mjs)**: 既存 Spotter hook を見つけた場合も `hook.command` を現在の `SPOTTER_BIN` に更新する。これにより `npm install -g claude-spotter` 後、各プロジェクトで `spotter install` を再実行すれば hook は global npm 版へ揃う
|
|
10
|
+
- **編集 [test/install.test.mjs](test/install.test.mjs)**: 古い `/old/bin/spotter.mjs` hook が `spotter install` で現在の package path に差し替わる回帰テストを追加
|
|
11
|
+
|
|
12
|
+
### ユーザー側で必要な手順
|
|
13
|
+
|
|
14
|
+
1. `npm install -g claude-spotter@1.4.2`
|
|
15
|
+
2. 各プロジェクトで `spotter install`
|
|
16
|
+
|
|
17
|
+
## 1.4.1
|
|
18
|
+
|
|
19
|
+
**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 に登録するようにした。
|
|
20
|
+
|
|
21
|
+
### 変更点
|
|
22
|
+
|
|
23
|
+
- **編集 [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 登録だけを行わない
|
|
24
|
+
- **編集 [test/install.test.mjs](test/install.test.mjs)**: `spotter install` が Codex CLI presence 時に Codex hooks を登録する回帰テストを追加。既存 refresh 系テストは実ユーザー `~/.codex` を触らないよう DI で固定
|
|
25
|
+
- **編集 README / README.ja / postinstall / CLAUDE.md / open issues**: インストール手順を `npm install -g claude-spotter` → 各プロジェクトで `spotter install` に集約。`spotter codex-hook install` は修復 / 明示登録用 command として残す
|
|
26
|
+
|
|
27
|
+
### ユーザー側で必要な手順
|
|
28
|
+
|
|
29
|
+
1. `npm install -g claude-spotter@1.4.1` で global update
|
|
30
|
+
2. 各プロジェクトで `spotter install` を実行する。Claude hooks、`.spotter/marker.json`、Claude catalog seed が設定され、Codex CLI がある環境では Codex native hooks も登録される
|
|
31
|
+
|
|
3
32
|
## 1.4.0
|
|
4
33
|
|
|
5
34
|
**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 が自動更新する。
|
package/README.ja.md
CHANGED
|
@@ -41,12 +41,10 @@ Spotter が拾うのは、たとえばこういう瞬間です。
|
|
|
41
41
|
npm install -g claude-spotter
|
|
42
42
|
cd your-project
|
|
43
43
|
spotter install
|
|
44
|
-
# 任意: Codex native hooks を使う場合
|
|
45
|
-
spotter codex-hook install
|
|
46
44
|
```
|
|
47
45
|
|
|
48
46
|
`v0.3.0` 以降は**プロジェクト単位の明示的 install** を採用しています (v0.2 までの `postinstall` 自動登録はデーモン増殖の主因だったため撤回)。各プロジェクトの `.claude/settings.json` に hook を登録し、そのプロジェクトでの Claude Code セッションのみで有効になります。
|
|
49
|
-
Codex
|
|
47
|
+
Codex CLI が使える環境では、同じ `spotter install` が user-level の Codex native hooks も登録します。実際に動くプロジェクトは `spotter install` が作る `.spotter/marker.json` で制限されるため、無関係な Codex セッションでは Spotter は起動しません。
|
|
50
48
|
|
|
51
49
|
Spotter を upgrade した後、release note で hook 設定変更が案内されている場合は、各 install 済みプロジェクトで `spotter install` を再実行してください。global package update でコード経路は変わりますが、既存 `.claude/settings.json` の timeout 値は自動では書き換わりません。
|
|
52
50
|
|
|
@@ -105,7 +103,7 @@ flowchart LR
|
|
|
105
103
|
|
|
106
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 のツールリストで上書きされることはありません。
|
|
107
105
|
|
|
108
|
-
**`spotter install` が Claude catalog の初回 seed を自動実行し、Claude Code セッション起動ごとに SessionStart hook が bg で `spotter db refresh` を走らせる**ため、Claude 通常運用で手動コマンドを叩く必要はありません。Codex
|
|
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` に該当サーバーが存在する環境で注入されます。**手書きでツールリストを管理する必要はありません**。
|
|
109
107
|
|
|
110
108
|
## Throughline との関係
|
|
111
109
|
|
|
@@ -142,7 +140,7 @@ spotter codex work --findings findings.json --instruction "docs 更新" --approv
|
|
|
142
140
|
--allowed-path docs/ --preserve-worktree
|
|
143
141
|
# 承認済み codex-sidecar work を isolated worktree で実行
|
|
144
142
|
spotter codex-hook install
|
|
145
|
-
# Codex native
|
|
143
|
+
# Codex native hooks の修復 / 明示登録 (通常は spotter install が実行)
|
|
146
144
|
spotter codex-hook diagnostics
|
|
147
145
|
# Codex hooks feature と Spotter hook 登録を診断
|
|
148
146
|
spotter uninstall # hook 登録を解除 (~/.spotter は残す)
|
package/README.md
CHANGED
|
@@ -41,12 +41,10 @@ Spotter audits in two stages:
|
|
|
41
41
|
npm install -g claude-spotter
|
|
42
42
|
cd your-project
|
|
43
43
|
spotter install
|
|
44
|
-
# Optional, for Codex native hooks:
|
|
45
|
-
spotter codex-hook install
|
|
46
44
|
```
|
|
47
45
|
|
|
48
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.
|
|
49
|
-
Codex
|
|
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.
|
|
50
48
|
|
|
51
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.
|
|
52
50
|
|
|
@@ -105,7 +103,7 @@ flowchart LR
|
|
|
105
103
|
|
|
106
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.
|
|
107
105
|
|
|
108
|
-
**`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. Codex
|
|
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.**
|
|
109
107
|
|
|
110
108
|
## Spotter and Throughline
|
|
111
109
|
|
|
@@ -143,7 +141,7 @@ spotter codex work --findings findings.json --instruction "Update docs" --approv
|
|
|
143
141
|
--allowed-path docs/ --preserve-worktree
|
|
144
142
|
# run approved codex-sidecar work in an isolated worktree
|
|
145
143
|
spotter codex-hook install
|
|
146
|
-
# register Codex native
|
|
144
|
+
# repair / explicitly register Codex native hooks (normally handled by spotter install)
|
|
147
145
|
spotter codex-hook diagnostics
|
|
148
146
|
# check Codex hooks feature and Spotter hook entries
|
|
149
147
|
spotter uninstall # remove hooks from this project (leaves ~/.spotter intact)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-spotter",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"description": "Audit agent running alongside Claude Code that catches missed tool calls — 気づく役と実行する役の分離",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -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
|
@@ -27,6 +27,5 @@ 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('
|
|
31
|
-
console.log(' spotter codex-hook install');
|
|
30
|
+
console.log(' If Codex CLI is installed, `spotter install` also registers Codex hooks.');
|
|
32
31
|
console.log(' Codex hooks refresh .spotter/tool-db.codex.json on SessionStart.');
|
package/src/cli/install.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
// `spotter install` — create ~/.spotter/, register hooks
|
|
1
|
+
// `spotter install` — create ~/.spotter/, register Claude hooks, and register
|
|
2
|
+
// Codex native hooks when the Codex CLI is available.
|
|
2
3
|
//
|
|
3
4
|
// Per plan §15.4, this shows a diff and asks for confirmation before touching settings.json.
|
|
4
5
|
//
|
|
@@ -12,6 +13,7 @@
|
|
|
12
13
|
// has no projectRoot so DB seeding is skipped there).
|
|
13
14
|
|
|
14
15
|
import { mkdir, writeFile, readFile, access } from 'node:fs/promises';
|
|
16
|
+
import { spawnSync } from 'node:child_process';
|
|
15
17
|
import { homedir } from 'node:os';
|
|
16
18
|
import { join, resolve, dirname } from 'node:path';
|
|
17
19
|
import { fileURLToPath } from 'node:url';
|
|
@@ -19,6 +21,7 @@ import { createInterface } from 'node:readline/promises';
|
|
|
19
21
|
import { version as SPOTTER_VERSION } from '../version.mjs';
|
|
20
22
|
import { refresh } from '../tool-db/refresh.mjs';
|
|
21
23
|
import { localDbPath, globalDbPath } from '../tool-db/loader.mjs';
|
|
24
|
+
import { installCodexHooks } from './codex-hook-cmd.mjs';
|
|
22
25
|
|
|
23
26
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
24
27
|
const PACKAGE_ROOT = resolve(HERE, '..', '..');
|
|
@@ -45,7 +48,16 @@ const HOOK_EVENTS = [
|
|
|
45
48
|
{ event: 'SessionEnd', sub: 'session-end', timeout: 3 },
|
|
46
49
|
];
|
|
47
50
|
|
|
48
|
-
export async function runInstall({
|
|
51
|
+
export async function runInstall({
|
|
52
|
+
target = 'project',
|
|
53
|
+
autoYes = false,
|
|
54
|
+
cwd = process.cwd(),
|
|
55
|
+
skipRefresh = false,
|
|
56
|
+
skipCodexHooks = skipRefresh,
|
|
57
|
+
refreshFn = refresh,
|
|
58
|
+
codexCliPresentFn = isCodexCliPresent,
|
|
59
|
+
installCodexHooksFn = installCodexHooks,
|
|
60
|
+
} = {}) {
|
|
49
61
|
const settingsPath = target === 'user'
|
|
50
62
|
? join(homedir(), '.claude', 'settings.json')
|
|
51
63
|
: join(cwd, '.claude', 'settings.json');
|
|
@@ -108,6 +120,16 @@ export async function runInstall({ target = 'project', autoYes = false, cwd = pr
|
|
|
108
120
|
console.log(`wrote ${settingsPath}`);
|
|
109
121
|
}
|
|
110
122
|
|
|
123
|
+
if (target === 'project' && !skipCodexHooks) {
|
|
124
|
+
if (codexCliPresentFn()) {
|
|
125
|
+
const result = await installCodexHooksFn();
|
|
126
|
+
console.log(' Codex hooks registered');
|
|
127
|
+
console.log(` Codex hooks: ${result.hooksPath}`);
|
|
128
|
+
} else {
|
|
129
|
+
console.log(' Codex CLI not found — Codex hooks not registered');
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
111
133
|
// Seed the tool-db so the first session has something to audit against.
|
|
112
134
|
// Runs regardless of whether settings.json changed — re-running `spotter install`
|
|
113
135
|
// on an already-installed project is the canonical way to refresh tool-db drift
|
|
@@ -134,6 +156,7 @@ export async function runInstall({ target = 'project', autoYes = false, cwd = pr
|
|
|
134
156
|
|
|
135
157
|
console.log('\nnext steps:');
|
|
136
158
|
console.log(' reload Claude Code (or open a new session) to activate Spotter');
|
|
159
|
+
console.log(' open a new Codex session to activate Codex hooks when Codex CLI is installed');
|
|
137
160
|
}
|
|
138
161
|
|
|
139
162
|
async function exists(path) {
|
|
@@ -145,6 +168,16 @@ async function exists(path) {
|
|
|
145
168
|
}
|
|
146
169
|
}
|
|
147
170
|
|
|
171
|
+
function isCodexCliPresent() {
|
|
172
|
+
const result = spawnSync('codex', ['--version'], {
|
|
173
|
+
encoding: 'utf8',
|
|
174
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
175
|
+
timeout: 5_000,
|
|
176
|
+
windowsHide: true,
|
|
177
|
+
});
|
|
178
|
+
return result.status === 0;
|
|
179
|
+
}
|
|
180
|
+
|
|
148
181
|
async function loadSettings(path) {
|
|
149
182
|
try {
|
|
150
183
|
const raw = await readFile(path, 'utf8');
|
|
@@ -171,6 +204,7 @@ function mergeHooks(current) {
|
|
|
171
204
|
if (hook?.type !== 'command') continue;
|
|
172
205
|
if (!hook.command?.includes('spotter.mjs') || !hook.command?.includes(`hook ${sub}`)) continue;
|
|
173
206
|
alreadyHas = true;
|
|
207
|
+
hook.command = command;
|
|
174
208
|
hook.timeout = timeout;
|
|
175
209
|
}
|
|
176
210
|
}
|