claude-spotter 1.4.26 → 1.4.28
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 +12 -0
- package/package.json +1 -1
- package/src/cli/codex-hook-cmd.mjs +6 -1
- package/src/cli/diagnostics-cmd.mjs +7 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.4.28 — 2026-07-21
|
|
4
|
+
|
|
5
|
+
- **Windows Codex SessionStartの誤timeoutを修正。** detached refreshを起動するSpotter所有hookの
|
|
6
|
+
host側上限を5秒から30秒へ変更し、Windows nativeのNode起動・project discoveryが5秒を超えても
|
|
7
|
+
SessionStart失敗として切られないようにした。再installは旧5秒設定をcanonical 30秒へ正規化する。
|
|
8
|
+
|
|
9
|
+
## 1.4.27 — 2026-07-21
|
|
10
|
+
|
|
11
|
+
- **Windows PowerShell 5.1向け診断JSONをASCII安全化。** `spotter diagnostics logs --json`は
|
|
12
|
+
非ASCII文字をJSONのUnicode escapeとして出力する。履歴上のtool名に全角括弧などが含まれても、
|
|
13
|
+
Windows PowerShell 5.1のnative stdout誤復号でJSON構造が壊れず、`ConvertFrom-Json`で読める。
|
|
14
|
+
|
|
3
15
|
## 1.4.26 — 2026-07-20
|
|
4
16
|
|
|
5
17
|
- **SessionEnd cleanupを冪等化。** daemonが未起動または既に停止済みの`E_UNREACHABLE`は
|
package/package.json
CHANGED
|
@@ -39,6 +39,7 @@ const HERE = dirname(fileURLToPath(import.meta.url));
|
|
|
39
39
|
const PACKAGE_ROOT = resolve(HERE, '..', '..');
|
|
40
40
|
const SPOTTER_BIN = join(PACKAGE_ROOT, 'bin', 'spotter.mjs');
|
|
41
41
|
const CODEX_HOOK_TIMEOUT_SEC = 60;
|
|
42
|
+
const CODEX_SESSION_START_TIMEOUT_SEC = 30;
|
|
42
43
|
const DEFAULT_CODEX_HOOK_AUDITOR_TIMEOUT_MS = 20_000;
|
|
43
44
|
const DEFAULT_CODEX_STOP_SHORT_FINAL_MAX_CHARS = 120;
|
|
44
45
|
const CODEX_HOOK_FEATURE_NAMES = ['hooks', 'codex_hooks'];
|
|
@@ -623,6 +624,7 @@ function validateSpotterCodexHookEvent(settings, event) {
|
|
|
623
624
|
const candidates = allEntries.filter((hook) => isSpotterCodexCommand(String(hook?.command ?? '')));
|
|
624
625
|
const expectedCandidates = candidates.filter((hook) => isSpotterCodexCommand(String(hook.command ?? ''), event));
|
|
625
626
|
const expected = expectedCandidates.filter((hook) => hook?.type === 'command');
|
|
627
|
+
const expectedTimeout = event === 'SessionStart' ? CODEX_SESSION_START_TIMEOUT_SEC : CODEX_HOOK_TIMEOUT_SEC;
|
|
626
628
|
const issues = [];
|
|
627
629
|
if (expectedCandidates.length === 0) issues.push('missing');
|
|
628
630
|
if (expectedCandidates.length > 1) issues.push('duplicate');
|
|
@@ -632,6 +634,7 @@ function validateSpotterCodexHookEvent(settings, event) {
|
|
|
632
634
|
if (hook.async === true) issues.push('async:true');
|
|
633
635
|
if (!Object.hasOwn(hook, 'timeout')) issues.push('timeout:missing');
|
|
634
636
|
else if (!Number.isFinite(hook.timeout) || hook.timeout <= 0) issues.push('timeout-invalid');
|
|
637
|
+
else if (hook.timeout !== expectedTimeout) issues.push(`timeout!=${expectedTimeout}`);
|
|
635
638
|
if (Object.hasOwn(hook, 'timeoutSec')) issues.push('timeoutSec');
|
|
636
639
|
if (hook.async === false) issues.push('async:false');
|
|
637
640
|
if (hook.statusMessage === null) issues.push('statusMessage:null');
|
|
@@ -658,6 +661,8 @@ function isIncompatibleSpotterHookIssue(issue) {
|
|
|
658
661
|
'type!=command',
|
|
659
662
|
'async:true',
|
|
660
663
|
'timeout-invalid',
|
|
664
|
+
'timeout!=30',
|
|
665
|
+
'timeout!=60',
|
|
661
666
|
'timeoutSec',
|
|
662
667
|
'commandWindows-invalid',
|
|
663
668
|
].includes(issue);
|
|
@@ -884,7 +889,7 @@ function mergeCodexHooks(current, { nodePath, spotterBin, platform = process.pla
|
|
|
884
889
|
next.hooks = next.hooks ?? {};
|
|
885
890
|
const prefix = platform === 'win32' ? '& ' : '';
|
|
886
891
|
addCodexHook(next, 'SessionStart', `${prefix}${quoteArg(nodePath)} ${quoteArg(spotterBin)} codex-hook session-start`, {
|
|
887
|
-
timeout:
|
|
892
|
+
timeout: CODEX_SESSION_START_TIMEOUT_SEC,
|
|
888
893
|
});
|
|
889
894
|
addCodexHook(next, 'UserPromptSubmit', `${prefix}${quoteArg(nodePath)} ${quoteArg(spotterBin)} codex-hook user-prompt-submit`);
|
|
890
895
|
addCodexHook(next, 'Stop', `${prefix}${quoteArg(nodePath)} ${quoteArg(spotterBin)} codex-hook stop`);
|
|
@@ -53,12 +53,18 @@ export async function runDiagnosticsLogsCommand({
|
|
|
53
53
|
const runtimeErrors = await readRuntimeErrorStoreStatusFn();
|
|
54
54
|
const merged = { ...summary, hookEvents, runtimeErrors };
|
|
55
55
|
if (opts.json) {
|
|
56
|
-
writeOutput(
|
|
56
|
+
writeOutput(stringifyAsciiJson(merged) + '\n');
|
|
57
57
|
return;
|
|
58
58
|
}
|
|
59
59
|
writeOutput(formatDaemonLogSummary(merged));
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
function stringifyAsciiJson(value) {
|
|
63
|
+
return JSON.stringify(value, null, 2).replace(/[\u007f-\uffff]/g, (character) =>
|
|
64
|
+
`\\u${character.charCodeAt(0).toString(16).padStart(4, '0')}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
62
68
|
export function formatDaemonLogSummary(summary) {
|
|
63
69
|
const lines = [
|
|
64
70
|
'spotter diagnostics logs',
|