@tyhld/conductor 0.12.69 → 0.12.71
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/dist/headless.js +24 -4
- package/package.json +1 -1
- package/sales-template/settings.json +0 -15
- package/scripts/update-guard.sh +8 -0
package/dist/headless.js
CHANGED
|
@@ -19,7 +19,7 @@ import { createInterface } from 'node:readline';
|
|
|
19
19
|
import { createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, unlinkSync, writeFileSync } from 'node:fs';
|
|
20
20
|
import path from 'node:path';
|
|
21
21
|
import os from 'node:os';
|
|
22
|
-
import { RELAY_DELIVER_MAX, RELAY_FETCH_TIMEOUT_MS, RELAY_HEARTBEAT_INTERVAL_MS,
|
|
22
|
+
import { CENTRAL_BUSY_HOLD_MAX_MS, RELAY_DELIVER_MAX, RELAY_FETCH_TIMEOUT_MS, RELAY_HEARTBEAT_INTERVAL_MS, RELAY_RESTORE_ORPHANS_ENABLED, buildAnchor, buildSendText, canDeliver, completeWithReport, createRelayState, deliveryReport, fetchCommand, fetchCommandStatus, fetchControl, fetchOrphans, isTerminalCommandStatus, kindOf, markDelivered, noteCentralDown, noteCentralUp, noteReadiness, patchStatus, reconnectDelayMs, selectOrphanToRestore, sendHeartbeat, } from './relay.js';
|
|
23
23
|
const log = (msg) => {
|
|
24
24
|
console.log(`[headless] ${msg}`);
|
|
25
25
|
};
|
|
@@ -471,6 +471,7 @@ export function spawnClaudeProcess(cfg, cmd, sessionId, attempt, isResume) {
|
|
|
471
471
|
exitCode: null,
|
|
472
472
|
exitSignal: null,
|
|
473
473
|
stopped: false,
|
|
474
|
+
timedOut: false,
|
|
474
475
|
eventBuffer: [],
|
|
475
476
|
lastFlushAt: Date.now(),
|
|
476
477
|
lastStopCheckAt: Date.now(),
|
|
@@ -626,6 +627,23 @@ async function checkRunningJob(cfg, state) {
|
|
|
626
627
|
if (job.completed) {
|
|
627
628
|
await flushEvents(cfg, job);
|
|
628
629
|
clearActiveJob(cfg.site);
|
|
630
|
+
if (job.timedOut) {
|
|
631
|
+
// 上限時間で強制停止した → 管制へ理由つきで failed を記録する
|
|
632
|
+
const elapsed = Math.round((Date.now() - job.startedAt) / 1000);
|
|
633
|
+
const reason = `上限時間(${Math.round(CENTRAL_BUSY_HOLD_MAX_MS / 1000)}s)で強制停止 (実行${elapsed}s, exit=${job.exitCode}, signal=${job.exitSignal})`;
|
|
634
|
+
await sendCommandEvents(cfg, job.commandId, [{
|
|
635
|
+
type: 'error',
|
|
636
|
+
text: reason.slice(0, EVENT_TEXT_MAX),
|
|
637
|
+
at: new Date().toISOString(),
|
|
638
|
+
attempt: job.attempt,
|
|
639
|
+
}]);
|
|
640
|
+
await patchStatus(cfg, job.commandId, 'failed', reason.slice(0, EVENT_TEXT_MAX));
|
|
641
|
+
rs.abandoned.add(job.commandId);
|
|
642
|
+
state.job = null;
|
|
643
|
+
rs.lastHeartbeatAt = null;
|
|
644
|
+
log(`WARN site=${cfg.site} id=${job.commandId} ${reason}`);
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
629
647
|
if (job.stopped) {
|
|
630
648
|
// stop_requested で止めた
|
|
631
649
|
await sendCommandEvents(cfg, job.commandId, [{
|
|
@@ -719,10 +737,12 @@ async function checkRunningJob(cfg, state) {
|
|
|
719
737
|
return;
|
|
720
738
|
}
|
|
721
739
|
}
|
|
722
|
-
// タイムアウト
|
|
723
|
-
|
|
740
|
+
// タイムアウト — 中央の上限(3時間)で強制停止する。
|
|
741
|
+
// ★RELAY_PENDING_TIMEOUT_MS(15分)は tmux の pending 解除用。画面なし方式では
|
|
742
|
+
// 作業中の職人そのものを殺すので、中央と同じ CENTRAL_BUSY_HOLD_MAX_MS を使う。
|
|
743
|
+
if (now - job.startedAt > CENTRAL_BUSY_HOLD_MAX_MS) {
|
|
724
744
|
log(`WARN site=${cfg.site} id=${job.commandId} タイムアウト(${Math.round((now - job.startedAt) / 1000)}s) → SIGTERM`);
|
|
725
|
-
job.
|
|
745
|
+
job.timedOut = true;
|
|
726
746
|
await stopJob(job);
|
|
727
747
|
return;
|
|
728
748
|
}
|
package/package.json
CHANGED
|
@@ -63,35 +63,20 @@
|
|
|
63
63
|
"mcp__claude_ai_Supabase__pause_project",
|
|
64
64
|
"mcp__claude_ai_Supabase__restore_project",
|
|
65
65
|
"mcp__claude_ai_Supabase__confirm_cost",
|
|
66
|
-
"Write(**/.env)",
|
|
67
66
|
"Edit(**/.env)",
|
|
68
|
-
"Write(**/.env.*)",
|
|
69
67
|
"Edit(**/.env.*)",
|
|
70
|
-
"Write(**/.dev.vars)",
|
|
71
68
|
"Edit(**/.dev.vars)",
|
|
72
|
-
"Write(**/.dev.vars.local)",
|
|
73
69
|
"Edit(**/.dev.vars.local)",
|
|
74
|
-
"Write(**/.dev.vars.production)",
|
|
75
70
|
"Edit(**/.dev.vars.production)",
|
|
76
|
-
"Write(**/.dev.vars.staging)",
|
|
77
71
|
"Edit(**/.dev.vars.staging)",
|
|
78
|
-
"Write(**/.dev.vars.development)",
|
|
79
72
|
"Edit(**/.dev.vars.development)",
|
|
80
|
-
"Write(**/.dev.vars.preview)",
|
|
81
73
|
"Edit(**/.dev.vars.preview)",
|
|
82
|
-
"Write(**/.claude/settings.json)",
|
|
83
74
|
"Edit(**/.claude/settings.json)",
|
|
84
|
-
"Write(**/.claude/hooks/**)",
|
|
85
75
|
"Edit(**/.claude/hooks/**)",
|
|
86
|
-
"Write(**/.tyhld/**)",
|
|
87
76
|
"Edit(**/.tyhld/**)",
|
|
88
|
-
"Write(**/.ssh/**)",
|
|
89
77
|
"Edit(**/.ssh/**)",
|
|
90
|
-
"Write(**/*.pem)",
|
|
91
78
|
"Edit(**/*.pem)",
|
|
92
|
-
"Write(**/*.key)",
|
|
93
79
|
"Edit(**/*.key)",
|
|
94
|
-
"Write(**/.npmrc)",
|
|
95
80
|
"Edit(**/.npmrc)",
|
|
96
81
|
"Read(**/.env)",
|
|
97
82
|
"Read(**/.env.local)",
|
package/scripts/update-guard.sh
CHANGED
|
@@ -1003,6 +1003,14 @@ RETIRED_DENY = frozenset({
|
|
|
1003
1003
|
# 正しい形(* をワイルドカードとして展開)を正本に足したので、壊れた旧形を退役する。
|
|
1004
1004
|
"Bash(git push * --force:*)", "Bash(git push * -f:*)", "Bash(git push * --force-with-lease:*)",
|
|
1005
1005
|
"Bash(cat .env.*:*)", "Bash(cat *.env:*)",
|
|
1006
|
+
# ★便 88e008ab: Write(…) の禁止は Claude Code では効かない(Edit のみが file-editing を止める)。
|
|
1007
|
+
# 同じ場所の Edit(…) が全15本あるので、Write(…) は警告の原因になるだけの重複。
|
|
1008
|
+
"Write(**/.env)", "Write(**/.env.*)",
|
|
1009
|
+
"Write(**/.dev.vars)", "Write(**/.dev.vars.local)", "Write(**/.dev.vars.production)",
|
|
1010
|
+
"Write(**/.dev.vars.staging)", "Write(**/.dev.vars.development)", "Write(**/.dev.vars.preview)",
|
|
1011
|
+
"Write(**/.claude/settings.json)", "Write(**/.claude/hooks/**)",
|
|
1012
|
+
"Write(**/.tyhld/**)", "Write(**/.ssh/**)",
|
|
1013
|
+
"Write(**/*.pem)", "Write(**/*.key)", "Write(**/.npmrc)",
|
|
1006
1014
|
})
|
|
1007
1015
|
retire_hit = [r for r in cur if r in RETIRED_DENY]
|
|
1008
1016
|
if retire_hit:
|