claude-spotter 1.5.0 → 1.5.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,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.5.2 — 2026-08-04
4
+
5
+ - **Mac LaunchAgentでNodeを解決。** `spotter`の絶対pathだけでなく、env shebangが使う
6
+ Homebrew Nodeを含むPATHをplistへ明示し、launchdの最小PATHでもdevice serverを起動できるようにした。
7
+ - **Windows nativeとWSL2のloopback portを分離。** WSL2 localhost relayがWindows側の53940も
8
+ 占有する実環境に合わせ、Windows native deviceを53944へ移し、main-serverの53943 tunnelも
9
+ 53944へ接続する。Windowsを選んだ時にWSL2の評価DBが表示される衝突を解消した。
10
+ - **評価SQLiteの初回同時open待ちを実測に合わせた。** 高負荷のNode 22.13でschema作成の競合が
11
+ 既定1秒を超えたため、SQLite自身のbounded `busy_timeout`を5秒へ変更した。retry、lockfile、
12
+ background処理は追加せず、lockがない通常処理は待たない。
13
+
14
+ ## 1.5.1 — 2026-08-04
15
+
16
+ - **main-server hubのsystemd PATHを明示設定可能にした。** user managerがnvmのnpm binを
17
+ 継承しない実環境に合わせ、hub unitも`dashboard-hub.env`を読む。device unitと同じく、
18
+ 実測したnpm binをPATHへ置き、端末固有のversion pathを配布unitへ焼かない。
19
+
3
20
  ## 1.5.0 — 2026-08-04
4
21
 
5
22
  - **評価結果を端末別Web dashboardで表示。** 各端末の`~/.spotter/evaluation.db`をrequestごとに読み、
@@ -2,7 +2,9 @@
2
2
 
3
3
  ## 固定構成
4
4
 
5
- 各端末のdevice serverは`127.0.0.1:53940`だけで待ち受ける。main-serverのhub
5
+ 各端末のdevice serverはloopbackだけで待ち受ける。main-server、Mac、FOX WSL2
6
+ `127.0.0.1:53940`、FOX Windows nativeはWSL2 localhost relayとの衝突を避けて
7
+ `127.0.0.1:53944`を使う。main-serverのhubは
6
8
  Docker Caddyから到達できる`172.18.0.1:53940`で待ち受ける。評価DBは各端末の
7
9
  `~/.spotter/evaluation.db`をその場で読み、端末外へ複製しない。
8
10
 
@@ -40,6 +42,12 @@ SPOTTER_DEVICE_ID=main-server
40
42
  SPOTTER_DEVICE_NAME=main-server
41
43
  ```
42
44
 
45
+ device envと同じPATHを`~/.config/spotter/dashboard-hub.env`にも置く。main-serverの例:
46
+
47
+ ```ini
48
+ PATH=/home/kite/.nvm/versions/node/v24.14.1/bin:/usr/local/bin:/usr/bin:/bin
49
+ ```
50
+
43
51
  ```sh
44
52
  systemctl --user daemon-reload
45
53
  systemctl --user enable --now spotter-dashboard-device.service spotter-dashboard-hub.service
@@ -47,8 +55,7 @@ curl --fail http://127.0.0.1:53940/_spotter/health
47
55
  curl --fail http://172.18.0.1:53940/
48
56
  ```
49
57
 
50
- systemd user managerの`PATH`から`spotter`が見えない場合だけ、ユーザー環境の実際のnpm bin
51
- unitの`Environment=PATH=...`として追加する。別の起動経路へfallbackしない。
58
+ device envにも同じPATH行を置く。値は各端末で実測したnpm binを使い、別の起動経路へfallbackしない。
52
59
 
53
60
  ## FOX WSL2
54
61
 
@@ -83,7 +90,7 @@ main-serverのSSH host名またはIPを明示して次を1回実行する。
83
90
  登録される2 taskはログオン時にdevice serverとreverse tunnelを起動する。確認:
84
91
 
85
92
  ```powershell
86
- Invoke-RestMethod http://127.0.0.1:53940/_spotter/health
93
+ Invoke-RestMethod http://127.0.0.1:53944/_spotter/health
87
94
  Get-ScheduledTask -TaskName 'Spotter dashboard *' | Get-ScheduledTaskInfo
88
95
  ```
89
96
 
@@ -12,6 +12,10 @@
12
12
  <string>--host</string><string>127.0.0.1</string>
13
13
  <string>--port</string><string>53940</string>
14
14
  </array>
15
+ <key>EnvironmentVariables</key>
16
+ <dict>
17
+ <key>PATH</key><string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
18
+ </dict>
15
19
  <key>RunAtLoad</key><true/>
16
20
  <key>KeepAlive</key><true/>
17
21
  <key>ThrottleInterval</key><integer>10</integer>
@@ -4,6 +4,7 @@ After=network.target
4
4
 
5
5
  [Service]
6
6
  Type=simple
7
+ EnvironmentFile=%h/.config/spotter/dashboard-hub.env
7
8
  ExecStart=/usr/bin/env spotter dashboard hub --config %h/.config/spotter/dashboard-hub.json --host 172.18.0.1 --port 53940
8
9
  Restart=on-failure
9
10
  RestartSec=10
@@ -1,4 +1,4 @@
1
1
  $ErrorActionPreference = 'Stop'
2
2
  $spotter = Join-Path $env:APPDATA 'npm\spotter.cmd'
3
- & $spotter dashboard device --id fox-windows --name 'FOX Windows native' --host 127.0.0.1 --port 53940
3
+ & $spotter dashboard device --id fox-windows --name 'FOX Windows native' --host 127.0.0.1 --port 53944
4
4
  exit $LASTEXITCODE
@@ -3,5 +3,5 @@ $ErrorActionPreference = 'Stop'
3
3
  & "$env:WINDIR\System32\OpenSSH\ssh.exe" -N `
4
4
  -o BatchMode=yes -o ExitOnForwardFailure=yes `
5
5
  -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o TCPKeepAlive=yes `
6
- -R '127.0.0.1:53943:127.0.0.1:53940' $MainServer
6
+ -R '127.0.0.1:53943:127.0.0.1:53944' $MainServer
7
7
  exit $LASTEXITCODE
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-spotter",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "Audit agent running alongside Claude Code that catches missed tool calls — 気づく役と実行する役の分離",
5
5
  "type": "module",
6
6
  "bin": {
@@ -4,7 +4,7 @@ import { dirname, join } from 'node:path';
4
4
  import { DatabaseSync } from 'node:sqlite';
5
5
 
6
6
  export const EVALUATION_STORE_SCHEMA = 'spotter.evaluation_store.v1';
7
- export const DEFAULT_EVALUATION_BUSY_TIMEOUT_MS = 1_000;
7
+ export const DEFAULT_EVALUATION_BUSY_TIMEOUT_MS = 5_000;
8
8
  // daemonの無通信寿命と同じ30分を超えたopen観測は、保存行を変更せず、
9
9
  // report上だけproposal itemをoutcome_missingとして扱う。
10
10
  export const DEFAULT_OPEN_TURN_STALE_MS = 30 * 60 * 1_000;
@@ -29,7 +29,7 @@ export function createEvaluationStore({
29
29
  mkdirSync(dirname(databasePath), { recursive: true, mode: 0o700 });
30
30
  const database = new DatabaseSync(databasePath);
31
31
  // cold startでは別projectのprocessも同じ未作成DBを同時に開き得る。
32
- // WAL化とschema作成が最初のwrite lockを競う前に、既定1秒のbounded waitを有効にする。
32
+ // WAL化とschema作成が最初のwrite lockを競う前に、既定5秒のbounded waitを有効にする。
33
33
  database.exec(`PRAGMA busy_timeout=${busyTimeoutMs};`);
34
34
  database.exec('PRAGMA foreign_keys=ON;');
35
35
  initialize(database);
@@ -50,7 +50,7 @@ export function renderDashboard({
50
50
  <header class="page-header">
51
51
  <p class="eyebrow">Spotter</p>
52
52
  <h1>${escapeHtml(title)}</h1>
53
- ${selectedDevice ? `<p class="subtitle">端末: ${escapeHtml(selectedDevice.name ?? selectedDevice.id)}</p>` : '<p class="subtitle">端末を選択してください。</p>'}
53
+ ${selectedDevice ? `<p class="subtitle">端末: ${escapeHtml(selectedDevice.name ?? selectedDevice.id)} · <a class="device-picker-link" href="/">端末を選び直す</a></p>` : '<p class="subtitle">端末を選択してください。</p>'}
54
54
  </header>
55
55
  ${renderDevices(devices, selectedId)}
56
56
  ${selectedDevice ? renderDeviceContent({ overview: dashboardModel, cases: renderedCases, caseDetail, filters, action }) : ''}
@@ -212,6 +212,7 @@ body { margin: 0; }
212
212
  .eyebrow { color: #3565a0; font-weight: 700; letter-spacing: .08em; margin: 0; text-transform: uppercase; }
213
213
  h1 { margin: .25rem 0; font-size: clamp(1.75rem, 4vw, 2.5rem); } h2 { margin-top: 2rem; } h3 { margin-bottom: .5rem; }
214
214
  .subtitle, .empty { color: #52606d; }
215
+ .device-picker-link { color: inherit; }
215
216
  .device-nav ul { display: flex; flex-wrap: wrap; gap: .5rem; list-style: none; margin: .5rem 0; padding: 0; }
216
217
  .device { align-items: center; border: 1px solid #ccd4dd; border-radius: 999px; color: inherit; display: inline-flex; gap: .45rem; padding: .45rem .7rem; text-decoration: none; }
217
218
  .device[aria-current="page"] { border-color: #1c63b8; box-shadow: 0 0 0 2px #b8d6fa; }.device small { color: #52606d; }.status-dot { background: #a03333; border-radius: 50%; height: .55rem; width: .55rem; }.online .status-dot { background: #16803c; }