claude-spotter 1.1.1 → 1.1.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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.1.2
4
+
5
+ **v1.1.1 の code-review で発見した 2 件を修正**。Spotter 自身が監査役として指摘し、実装を補正する自己ドッグフーディング。
6
+
7
+ ### 変更点
8
+
9
+ - **編集 [src/cli/install.mjs](src/cli/install.mjs)**: `refresh` 呼び出しを try/catch で包み、throw 直前に stderr で復旧経路 (`spotter db refresh`) を露出。§0 の fallback 禁止は守りつつ、「hook 登録済み + tool-db なし」状態に陥ったユーザーに次の一手を示す診断メッセージを追加
10
+ - **編集 [src/cli/install.mjs](src/cli/install.mjs)**: `runInstall` に `refreshFn` パラメータを追加 (default: 実 refresh)。テストから mock を注入できるようにした
11
+ - **編集 [test/install.test.mjs](test/install.test.mjs)**: 新規 2 件追加 — (1) 2 回目 install でも refresh が呼ばれる回帰ガード (v1.1.1 fix の直接検証)、(2) refresh 失敗時に stderr に復旧ヒントが出ることを確認
12
+ - **編集 [docs/open-issues.md](docs/open-issues.md)**: P2 に「tool-db.json の並列書き込み race condition」を追記 (install と SessionStart bg refresh が同時に走ると last-writer-wins、実害観測なしなので放置)
13
+
14
+ ### 設計判断
15
+
16
+ - **race condition は v1.1.2 で修正しない**: 実運用で install はユーザー対話的に 1 回叩く想定 = 並列発生頻度は極低、失われた差分は次 refresh で再投入されるので最終収束。lock 機構は over-engineering
17
+
3
18
  ## 1.1.1
4
19
 
5
20
  **既 install プロジェクトで `spotter install` が refresh を skip してしまう bug の hot-fix**。v1.1.0 で追加した tool-db 自動構築が、hook 登録済みの場合に [install.mjs](src/cli/install.mjs) の早期 return に引っかかって走らない穴があった。これでは「既に install 済みのプロジェクトで tool-db.json が作られない」という v1.1.0 が解決すべき症状がそのまま残る。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-spotter",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Audit agent running alongside Claude Code that catches missed tool calls — 気づく役と実行する役の分離",
5
5
  "type": "module",
6
6
  "bin": {
@@ -36,7 +36,7 @@ const HOOK_EVENTS = [
36
36
  { event: 'SessionEnd', sub: 'session-end', timeout: 3 },
37
37
  ];
38
38
 
39
- export async function runInstall({ target = 'project', autoYes = false, cwd = process.cwd(), skipRefresh = false } = {}) {
39
+ export async function runInstall({ target = 'project', autoYes = false, cwd = process.cwd(), skipRefresh = false, refreshFn = refresh } = {}) {
40
40
  const settingsPath = target === 'user'
41
41
  ? join(homedir(), '.claude', 'settings.json')
42
42
  : join(cwd, '.claude', 'settings.json');
@@ -108,10 +108,19 @@ export async function runInstall({ target = 'project', autoYes = false, cwd = pr
108
108
  if (target === 'project' && !skipRefresh) {
109
109
  console.log('\ndiscovering MCP servers, skills, and sub-agents...');
110
110
  const log = (msg) => process.stderr.write(` ${msg}\n`);
111
- const resolved = await refresh({ projectRoot: cwd, logFn: log });
112
- console.log(` ${resolved.size} tool(s) resolved`);
113
- console.log(` local DB: ${localDbPath(cwd)}`);
114
- console.log(` global DB: ${globalDbPath()}`);
111
+ try {
112
+ const resolved = await refreshFn({ projectRoot: cwd, logFn: log });
113
+ console.log(` ${resolved.size} tool(s) resolved`);
114
+ console.log(` local DB: ${localDbPath(cwd)}`);
115
+ console.log(` global DB: ${globalDbPath()}`);
116
+ } catch (err) {
117
+ // §0: throw (fallback 禁止). But surface the recovery path so the user isn't
118
+ // left with "hooks registered, tool-db missing" and no clue what to run.
119
+ process.stderr.write(`\nspotter install: tool-db seeding failed.\n`);
120
+ process.stderr.write(` hooks are registered but tool-db is not ready.\n`);
121
+ process.stderr.write(` recover with: spotter db refresh\n`);
122
+ throw err;
123
+ }
115
124
  }
116
125
 
117
126
  console.log('\nnext steps:');