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 +17 -0
- package/docs/11_dashboard-operations.md +11 -4
- package/ops/dashboard/launchd/dev.kitepon.spotter-dashboard-device.plist +4 -0
- package/ops/dashboard/systemd/spotter-dashboard-hub.service +1 -0
- package/ops/dashboard/windows/spotter-dashboard-device.ps1 +1 -1
- package/ops/dashboard/windows/spotter-dashboard-tunnel.ps1 +1 -1
- package/package.json +1 -1
- package/src/core/evaluation-store.mjs +2 -2
- package/src/dashboard/render.mjs +2 -1
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
|
|
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
|
-
|
|
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:
|
|
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>
|
|
@@ -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
|
|
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:
|
|
6
|
+
-R '127.0.0.1:53943:127.0.0.1:53944' $MainServer
|
|
7
7
|
exit $LASTEXITCODE
|
package/package.json
CHANGED
|
@@ -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 =
|
|
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を競う前に、既定
|
|
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);
|
package/src/dashboard/render.mjs
CHANGED
|
@@ -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)}
|
|
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; }
|