claude-spotter 1.5.9 → 1.5.10
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 +9 -0
- package/docs/11_dashboard-operations.md +1 -1
- package/package.json +1 -1
- package/src/hooks/lib.mjs +13 -0
- package/src/hooks/pre-tool-use.mjs +2 -0
- package/src/hooks/session-end.mjs +2 -0
- package/src/hooks/session-start.mjs +2 -0
- package/src/hooks/stop.mjs +2 -0
- package/src/hooks/user-prompt.mjs +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,15 @@
|
|
|
3
3
|
各節はそのversion公開時点の変更記録であり、後続versionにより置換された仕様を含む。
|
|
4
4
|
現行runtime契約は[`docs/00_overview.md`](docs/00_overview.md)から辿る。
|
|
5
5
|
|
|
6
|
+
## 1.5.10 — 2026-08-14
|
|
7
|
+
|
|
8
|
+
- **非ClaudeのHook入力を副作用前に無視する。** 非空の`sessionId`と`hookEventName`を持ち、
|
|
9
|
+
Claudeの`session_id`を持たないcamelCase envelopeだけをunsupportedとして識別する。
|
|
10
|
+
SessionStart、UserPromptSubmit、PreToolUse、Stop、SessionEndはproject探索、daemon、評価store、
|
|
11
|
+
tool記録、Stop監査、Hook eventより前に無出力・exit 0で終了する。
|
|
12
|
+
- **正式host範囲を広げない。** camelCase payloadをClaude形へ変換せず、Grok向けtool DB、auditor、
|
|
13
|
+
installer、diagnosticsを追加しない。Claude/Codexの既存入力と処理は変更しない。
|
|
14
|
+
|
|
6
15
|
## 1.5.9 — 2026-08-14
|
|
7
16
|
|
|
8
17
|
- **Codex side conversationのStopを正常終了させる。** Codex公式Hook契約でnullableな
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Spotter評価dashboard運用
|
|
2
2
|
|
|
3
|
-
現行npm配布版: **v1.5.
|
|
3
|
+
現行npm配布版: **v1.5.10**(2026-08-14)。v1.5.10は非Claude Hook入力の副作用前no-op releaseであり、
|
|
4
4
|
dashboard routing構成はv1.5.3から変更していない。
|
|
5
5
|
|
|
6
6
|
この文書はservice設定の正本であり、各端末に現在installされているnpm versionの台帳ではない。
|
package/package.json
CHANGED
package/src/hooks/lib.mjs
CHANGED
|
@@ -46,6 +46,19 @@ export function isSubagentCall(input) {
|
|
|
46
46
|
&& input.agent_id.length > 0;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
// Grok invokes Claude-compatible hook commands with a camelCase wire envelope.
|
|
50
|
+
// Spotter does not support Grok as a host: ignore that envelope before any
|
|
51
|
+
// project lookup, daemon, evaluation, or hook-event side effect.
|
|
52
|
+
export function isUnsupportedNonClaudeEnvelope(input) {
|
|
53
|
+
return input !== null
|
|
54
|
+
&& typeof input === 'object'
|
|
55
|
+
&& typeof input.sessionId === 'string'
|
|
56
|
+
&& input.sessionId.length > 0
|
|
57
|
+
&& typeof input.hookEventName === 'string'
|
|
58
|
+
&& input.hookEventName.length > 0
|
|
59
|
+
&& !Object.hasOwn(input, 'session_id');
|
|
60
|
+
}
|
|
61
|
+
|
|
49
62
|
// Walk up from startCwd looking for .spotter/marker.json. Returns the project
|
|
50
63
|
// root path containing the marker, or null if none was found before reaching
|
|
51
64
|
// the filesystem root.
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
die,
|
|
11
11
|
isChildCall,
|
|
12
12
|
isSubagentCall,
|
|
13
|
+
isUnsupportedNonClaudeEnvelope,
|
|
13
14
|
isOutsideSpotterProject,
|
|
14
15
|
findSpotterMarker,
|
|
15
16
|
recordClaudeHookEvent,
|
|
@@ -29,6 +30,7 @@ export async function runPreToolUse({
|
|
|
29
30
|
} = {}) {
|
|
30
31
|
if (isChildCall()) return;
|
|
31
32
|
const input = await readInput();
|
|
33
|
+
if (isUnsupportedNonClaudeEnvelope(input)) return;
|
|
32
34
|
if (isSubagentCall(input)) return;
|
|
33
35
|
if (isOutsideSpotterProject(input)) return;
|
|
34
36
|
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
requireString,
|
|
9
9
|
isChildCall,
|
|
10
10
|
isSubagentCall,
|
|
11
|
+
isUnsupportedNonClaudeEnvelope,
|
|
11
12
|
isOutsideSpotterProject,
|
|
12
13
|
findSpotterMarker,
|
|
13
14
|
recordClaudeHookEvent,
|
|
@@ -24,6 +25,7 @@ export async function runSessionEnd({
|
|
|
24
25
|
} = {}) {
|
|
25
26
|
if (isChildCall()) return;
|
|
26
27
|
const input = await readInput();
|
|
28
|
+
if (isUnsupportedNonClaudeEnvelope(input)) return;
|
|
27
29
|
if (isSubagentCall(input)) return;
|
|
28
30
|
if (isOutsideSpotterProject(input)) return;
|
|
29
31
|
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
die,
|
|
23
23
|
isChildCall,
|
|
24
24
|
isSubagentCall,
|
|
25
|
+
isUnsupportedNonClaudeEnvelope,
|
|
25
26
|
isOutsideSpotterProject,
|
|
26
27
|
findSpotterMarker,
|
|
27
28
|
recordClaudeHookEvent,
|
|
@@ -39,6 +40,7 @@ export async function runSessionStart({
|
|
|
39
40
|
|
|
40
41
|
const input = await readInput();
|
|
41
42
|
|
|
43
|
+
if (isUnsupportedNonClaudeEnvelope(input)) return;
|
|
42
44
|
if (isSubagentCall(input)) return;
|
|
43
45
|
if (input.source !== 'startup') return;
|
|
44
46
|
if (isOutsideSpotterProject(input)) return;
|
package/src/hooks/stop.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
findSpotterMarker,
|
|
9
9
|
isChildCall,
|
|
10
10
|
isSubagentCall,
|
|
11
|
+
isUnsupportedNonClaudeEnvelope,
|
|
11
12
|
recordClaudeHookEvent,
|
|
12
13
|
} from './lib.mjs';
|
|
13
14
|
import { getLastAssistantText } from './transcript-reader.mjs';
|
|
@@ -26,6 +27,7 @@ export async function runStop({
|
|
|
26
27
|
} = {}) {
|
|
27
28
|
if (isChildCall()) return;
|
|
28
29
|
const input = await readInput();
|
|
30
|
+
if (isUnsupportedNonClaudeEnvelope(input)) return;
|
|
29
31
|
if (isSubagentCall(input)) return;
|
|
30
32
|
// Resolve the installed project once. Keeping this proven root lets the failure event remain
|
|
31
33
|
// attributable even if the marker disappears while the daemon request is in flight.
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
die,
|
|
18
18
|
isChildCall,
|
|
19
19
|
isSubagentCall,
|
|
20
|
+
isUnsupportedNonClaudeEnvelope,
|
|
20
21
|
isOutsideSpotterProject,
|
|
21
22
|
findSpotterMarker,
|
|
22
23
|
recordClaudeHookEvent,
|
|
@@ -48,6 +49,7 @@ export async function runUserPrompt({
|
|
|
48
49
|
} = {}) {
|
|
49
50
|
if (isChildCall()) return;
|
|
50
51
|
const input = await readInput();
|
|
52
|
+
if (isUnsupportedNonClaudeEnvelope(input)) return;
|
|
51
53
|
if (isSubagentCall(input)) return;
|
|
52
54
|
if (isOutsideSpotterProject(input)) return;
|
|
53
55
|
|