svamp-cli 0.2.346 → 0.2.358
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/bin/skills/artifact/SKILL.md +19 -5
- package/bin/skills/crew/SKILL.md +42 -11
- package/dist/{acpBackend-BZ1MJhQV.mjs → acpBackend-UaBD4zL3.mjs} +3 -0
- package/dist/{agentCommands-B2Nl7Fof.mjs → agentCommands-C_KvvYFp.mjs} +5 -5
- package/dist/{claudeAuth-iAerdaMr.mjs → claudeAuth-DMDvPNhO.mjs} +55 -6
- package/dist/cli.mjs +164 -86
- package/dist/{commands-D69mnkYu.mjs → commands-B19lVZjm.mjs} +10 -3
- package/dist/{commands-BB1Kcyt-.mjs → commands-Bmoy6Rlw.mjs} +34 -4
- package/dist/{commands-CiRCwjkJ.mjs → commands-CFBKkfX8.mjs} +9 -9
- package/dist/{commands-D1pZq3d4.mjs → commands-CcdoQIkb.mjs} +126 -25
- package/dist/{commands-BOpoVBOM.mjs → commands-DH_YQrAP.mjs} +5 -21
- package/dist/{commands-H4PsTGn8.mjs → commands-DRxANaS5.mjs} +65 -19
- package/dist/{commands-C2aODeVc.mjs → commands-nkvTnUJj.mjs} +29 -13
- package/dist/{detectIsolation-CzoDCEnh.mjs → detectIsolation-CrV8IFDv.mjs} +36 -16
- package/dist/{fleet-DM_Q7w69.mjs → fleet-Ca-UjJNL.mjs} +40 -15
- package/dist/friendlyName-B-OEwt0t.mjs +341 -0
- package/dist/{headlessCli-C8HzQvis.mjs → headlessCli-BpTXz6FD.mjs} +24 -16
- package/dist/{hookSettings-DYMTUgVA.mjs → hookSettings-CvvUhwCK.mjs} +294 -55
- package/dist/{friendlyName-1UZcyDhu.mjs → inboxGuard-CDqmIypF.mjs} +32 -347
- package/dist/index.mjs +10 -9
- package/dist/{loopVerify-B47sSjxe.mjs → loopVerify-CxAKJB5a.mjs} +1 -1
- package/dist/{notifyCommands-D-IKIxiq.mjs → notifyCommands-CCUE18Q-.mjs} +1 -1
- package/dist/package-DTTWvJbp.mjs +64 -0
- package/dist/{rpc-Cf0grcru.mjs → rpc-CAlAHQAy.mjs} +8 -3
- package/dist/{rpc-BB6RF4-F.mjs → rpc-CacreLQ8.mjs} +13 -9
- package/dist/{run-ChdsgaSD.mjs → run-Bc81iurl.mjs} +27 -8
- package/dist/{run-DkjwF-zA.mjs → run-DKOND4dO.mjs} +222 -73
- package/dist/{scheduler-BY30ZrB9.mjs → scheduler-IyLWBF8T.mjs} +28 -10
- package/dist/{serveAuth-DbVLRCRR.mjs → serveAuth-4M0vwMyj.mjs} +53 -11
- package/dist/{serveCommands-CUHUiYnZ.mjs → serveCommands-B-Ym_QXc.mjs} +8 -8
- package/dist/{store-Bn0ByYev.mjs → store-D8dok6_d.mjs} +62 -14
- package/package.json +3 -3
- package/dist/package-DtuINqf5.mjs +0 -64
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import {
|
|
1
|
+
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { c as composeSessionId, g as generateFriendlyName } from './friendlyName-B-OEwt0t.mjs';
|
|
2
2
|
import os from 'node:os';
|
|
3
3
|
import { resolve, join } from 'node:path';
|
|
4
4
|
import { existsSync, readFileSync, watch } from 'node:fs';
|
|
5
5
|
import { c as connectToHypha } from './hyphaClient-ybivOjZo.mjs';
|
|
6
|
-
import { c as createSessionStore, r as registerMachineService, g as generateHookSettings } from './hookSettings-
|
|
6
|
+
import { c as createSessionStore, r as registerMachineService, g as generateHookSettings } from './hookSettings-CvvUhwCK.mjs';
|
|
7
7
|
import { createServer } from 'node:http';
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
9
|
-
import { applyClaudeProxyEnv } from './claudeAuth-
|
|
9
|
+
import { applyClaudeProxyEnv } from './claudeAuth-DMDvPNhO.mjs';
|
|
10
10
|
import { createInterface } from 'node:readline';
|
|
11
11
|
import 'node:crypto';
|
|
12
12
|
import 'fs';
|
|
@@ -23,9 +23,10 @@ import 'http';
|
|
|
23
23
|
import 'net';
|
|
24
24
|
import 'os';
|
|
25
25
|
import './instance-CeHz5C8v.mjs';
|
|
26
|
-
import './serveAuth-
|
|
26
|
+
import './serveAuth-4M0vwMyj.mjs';
|
|
27
27
|
import './envFlag-COOuJ3AH.mjs';
|
|
28
28
|
import './codexProvider-BtxYc5Rj.mjs';
|
|
29
|
+
import './inboxGuard-CDqmIypF.mjs';
|
|
29
30
|
import './fileLock-BMPwCrB6.mjs';
|
|
30
31
|
import 'node:events';
|
|
31
32
|
import './cron-hHGdb5kU.mjs';
|
|
@@ -321,6 +322,7 @@ async function runRemoteMode(opts) {
|
|
|
321
322
|
opts.abort.addEventListener("abort", () => abortController.abort(), { once: true });
|
|
322
323
|
}
|
|
323
324
|
try {
|
|
325
|
+
let liveSessionId = opts.claudeSessionId;
|
|
324
326
|
while (!exitReason && !abortController.signal.aborted) {
|
|
325
327
|
const message = await Promise.race([
|
|
326
328
|
opts.nextMessage(),
|
|
@@ -334,12 +336,25 @@ async function runRemoteMode(opts) {
|
|
|
334
336
|
claudeBin,
|
|
335
337
|
cwd,
|
|
336
338
|
message,
|
|
337
|
-
|
|
339
|
+
// #1703: read the LIVE id, not the one captured when runRemoteMode was called.
|
|
340
|
+
//
|
|
341
|
+
// This used to pass `opts.claudeSessionId`, which is frozen at entry — and the id
|
|
342
|
+
// discovered on turn 1 is written by onSessionFound into loop.ts's own variable,
|
|
343
|
+
// which this function will not re-read until it returns and is called again. So
|
|
344
|
+
// turn 2 spawned with NO --resume: the web app sent "read foo.ts" then "now
|
|
345
|
+
// refactor it", and the second turn had never heard of foo.ts. EVERY remote-mode
|
|
346
|
+
// turn after the first was amnesiac, and each one was a full uncached prefix.
|
|
347
|
+
// loop.ts's header states the intended contract: "Session ID is preserved across
|
|
348
|
+
// switches (same Claude conversation)."
|
|
349
|
+
sessionId: liveSessionId,
|
|
338
350
|
permissionMode: opts.permissionMode,
|
|
339
351
|
hookSettingsPath: opts.hookSettingsPath,
|
|
340
352
|
claudeArgs: opts.claudeArgs,
|
|
341
353
|
signal: abortController.signal,
|
|
342
|
-
onSessionFound:
|
|
354
|
+
onSessionFound: (id) => {
|
|
355
|
+
liveSessionId = id;
|
|
356
|
+
opts.onSessionFound(id);
|
|
357
|
+
},
|
|
343
358
|
onThinkingChange,
|
|
344
359
|
onMessage,
|
|
345
360
|
log
|
|
@@ -385,6 +400,8 @@ async function runClaudeTurn(opts) {
|
|
|
385
400
|
`);
|
|
386
401
|
const spawnEnv = { ...process.env, CLAUDE_CODE_ENTRYPOINT: "sdk-ts" };
|
|
387
402
|
delete spawnEnv.CLAUDECODE;
|
|
403
|
+
const proxyDesc = applyClaudeProxyEnv(spawnEnv);
|
|
404
|
+
if (proxyDesc) opts.log?.(`[remote] Claude auth: ${proxyDesc}`);
|
|
388
405
|
const child = spawn(opts.claudeBin, args, {
|
|
389
406
|
stdio: ["pipe", "pipe", "pipe"],
|
|
390
407
|
cwd: opts.cwd,
|
|
@@ -526,7 +543,7 @@ function mapPermissionMode(mode) {
|
|
|
526
543
|
async function loop(opts) {
|
|
527
544
|
const { log } = opts;
|
|
528
545
|
let mode = opts.startingMode;
|
|
529
|
-
let claudeSessionId = null;
|
|
546
|
+
let claudeSessionId = opts.resumeSessionId || null;
|
|
530
547
|
const onSessionFound = (id) => {
|
|
531
548
|
if (id !== claudeSessionId) {
|
|
532
549
|
log(`[loop] Session ID: ${id}`);
|
|
@@ -872,7 +889,7 @@ async function runInteractive(options) {
|
|
|
872
889
|
process.on("SIGTERM", handleExit);
|
|
873
890
|
process.on("SIGINT", handleExit);
|
|
874
891
|
const claudeArgs = [...options.claudeArgs || []];
|
|
875
|
-
if (options.resumeSessionId
|
|
892
|
+
if (!options.resumeSessionId && options.continueSession) {
|
|
876
893
|
claudeArgs.push("--continue");
|
|
877
894
|
}
|
|
878
895
|
restoreConsoleLogs();
|
|
@@ -898,6 +915,8 @@ async function runInteractive(options) {
|
|
|
898
915
|
try {
|
|
899
916
|
const exitCode = await loop({
|
|
900
917
|
cwd,
|
|
918
|
+
resumeSessionId: options.resumeSessionId,
|
|
919
|
+
// #1702
|
|
901
920
|
startingMode: "local",
|
|
902
921
|
hookSettingsPath: hookSettings?.settingsPath || "",
|
|
903
922
|
permissionMode,
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import os from 'os';
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
|
-
import fs__default, { existsSync as existsSync$1, readFileSync as readFileSync$1, realpathSync, writeFileSync as writeFileSync$1, renameSync as renameSync$1, rmSync as rmSync$1, mkdirSync as mkdirSync$1, copyFileSync, unlinkSync as unlinkSync$1, readdirSync as readdirSync$1, watch, rmdirSync, statSync as statSync$1 } from 'fs';
|
|
3
|
+
import fs__default, { existsSync as existsSync$1, readFileSync as readFileSync$1, realpathSync, writeFileSync as writeFileSync$1, renameSync as renameSync$1, rmSync as rmSync$1, mkdirSync as mkdirSync$1, copyFileSync, unlinkSync as unlinkSync$1, readdirSync as readdirSync$1, watch, rmdirSync, statSync as statSync$1, chmodSync } from 'fs';
|
|
4
4
|
import { delimiter, join as join$1, resolve, dirname as dirname$1, basename as basename$1 } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { spawn as spawn$1, execFile, exec } from 'child_process';
|
|
7
7
|
import { randomUUID, createHash } from 'crypto';
|
|
8
|
-
import { a as authorizeRequest, b as countFileLines, P as ProcessSupervisor, d as retryStreakExhausted, e as computeRetryDelayMs, f as getRateLimitRetryConfig, g as generateHookSettings, h as getAccount, i as resolveAccountEnv, j as isRetryableRateLimit, c as createSessionStore, E as EXEC_MAX_BUFFER, k as execFailureOutcome, l as execSuccessOutcome, m as formatInboxMessageXml, n as loadInbox, o as isPending, p as ensureCodexHome, q as loadPersistedMachineMetadata, s as savePersistedMachineMetadata, r as registerMachineService, t as channelKeyGrantsFileAccess, C as ChannelStore, u as refreshDueAnthropicAccounts, v as refreshAnthropicToken } from './hookSettings-
|
|
9
|
-
import {
|
|
8
|
+
import { a as authorizeRequest, b as countFileLines, P as ProcessSupervisor, d as retryStreakExhausted, e as computeRetryDelayMs, f as getRateLimitRetryConfig, g as generateHookSettings, h as getAccount, i as resolveAccountEnv, j as isRetryableRateLimit, c as createSessionStore, E as EXEC_MAX_BUFFER, k as execFailureOutcome, l as execSuccessOutcome, m as formatInboxMessageXml, n as loadInbox, o as isPending, p as ensureCodexHome, q as loadPersistedMachineMetadata, s as savePersistedMachineMetadata, r as registerMachineService, t as channelKeyGrantsFileAccess, C as ChannelStore, u as refreshDueAnthropicAccounts, v as refreshAnthropicToken } from './hookSettings-CvvUhwCK.mjs';
|
|
9
|
+
import { c as composeSessionId, g as generateFriendlyName, a as friendlyNameFromId, f as formatHandle } from './friendlyName-B-OEwt0t.mjs';
|
|
10
10
|
import { w as withFileLock } from './fileLock-BMPwCrB6.mjs';
|
|
11
11
|
import { mkdirSync, writeFileSync, rmSync, existsSync, renameSync, readFileSync, statSync, openSync, fstatSync, readSync, closeSync, readdirSync, unlinkSync, linkSync } from 'node:fs';
|
|
12
12
|
import { join, dirname, basename, resolve as resolve$1 } from 'node:path';
|
|
13
13
|
import { c as connectToHypha } from './hyphaClient-ybivOjZo.mjs';
|
|
14
|
+
import { clearInboundContext, writeInboundContext, isHopCapParked, classifyInbound, consumeAwaitingReply, peekAwaitingReply } from './inboxGuard-CDqmIypF.mjs';
|
|
14
15
|
import { execSync, execFileSync, spawn } from 'node:child_process';
|
|
15
16
|
import { S as SharingNotificationSync } from './sharingNotificationSync-qGIQ-3yf.mjs';
|
|
16
|
-
import { AcpBackend } from './acpBackend-
|
|
17
|
+
import { AcpBackend } from './acpBackend-UaBD4zL3.mjs';
|
|
17
18
|
import { KNOWN_ACP_AGENTS, KNOWN_CODEX_AGENTS } from './acpAgentConfig-CObOPlA8.mjs';
|
|
18
19
|
import { c as codexAppServerAvailable, C as CodexAppServerBackend } from './codexAppServerBackend-VGsYtbqg.mjs';
|
|
19
20
|
import { codexPermissionSettings, codexForcedModel, codexModelMenu, codexClampModel, resolveCodexProvider, codexDefaultModel } from './codexProvider-BtxYc5Rj.mjs';
|
|
@@ -22,19 +23,19 @@ import { GeminiTransport } from './GeminiTransport-3OkhtFRO.mjs';
|
|
|
22
23
|
import { KimiTransport } from './KimiTransport-D8n009Tr.mjs';
|
|
23
24
|
import { kimiModelMenu, kimiClampModel, kimiSpawnEnv, kimiDefaultModel } from './kimiProvider-DbxODebR.mjs';
|
|
24
25
|
import { ensureKimiProviderConfigured } from './kimiSetup-NGsoYB5h.mjs';
|
|
25
|
-
import { detectIsolationCapabilities } from './detectIsolation-
|
|
26
|
+
import { detectIsolationCapabilities } from './detectIsolation-CrV8IFDv.mjs';
|
|
26
27
|
import { w as wrapWithIsolation } from './wrapCommand-CdNawSaa.mjs';
|
|
27
28
|
import { applySecurityContext } from './securityContext-Cm5UTCuD.mjs';
|
|
28
|
-
import { mkdir, copyFile, writeFile, rm, readdir, stat, readFile, rename } from 'node:fs/promises';
|
|
29
|
+
import { mkdir, copyFile, writeFile, chmod, rm, readdir, stat, readFile, rename } from 'node:fs/promises';
|
|
29
30
|
import { homedir, platform } from 'node:os';
|
|
30
|
-
import { applyClaudeProxyEnv, updateEnvFile } from './claudeAuth-
|
|
31
|
+
import { applyClaudeProxyEnv, probeLongContext1MEntitlement, LONG_CONTEXT_ENTITLEMENT_RECHECK_MS, updateEnvFile } from './claudeAuth-DMDvPNhO.mjs';
|
|
31
32
|
import { d as decodeTokenExpiry, i as isTokenExpired, c as classifyBootFailure, w as writeBootStatus, a as clearBootStatus, b as isAuthExpiryError, s as shouldRenewToken, T as TOKEN_LIFETIME_SEC, R as RENEW_CHECK_INTERVAL_MS } from './bootStatus-DqtNgJch.mjs';
|
|
32
33
|
import { e as envFlagEnabled } from './envFlag-COOuJ3AH.mjs';
|
|
33
|
-
import { r as resolveEvaluatorModel, c as backlogOraclePending, d as runLoopVerification, l as loopCancelledDuringVerify, e as resolveLoopDurable, f as decideLoopContinuation, g as resolveMaxAutoResumes, h as grantedExtensionCount, i as resolveMaxExtensions, j as resolveStuckLimit, k as decideVerifyErrorHandling, m as resolveVerifyErrorRetries, t as terminalPhaseForDone, n as accumulateLedger, s as sumUsageTokens, o as effectiveSoftCap, p as checkLoopBudget, q as isHardBudgetStop, u as isCostCeiling, v as summarizeExtensions, w as rearmStartedAt, x as oracleScopeSessionId, y as shouldRearmDormantLoop, z as parseDaemonShareEmails, D as DAEMON_SHARE_EMAILS_ENV, A as applyDaemonShareSeed, a as buildMachineShareUrl, B as recordProgressMarker, C as assessLoopProgress, E as resolveExtensionTurns, F as grantLoopExtension, G as buildGoalCondition, H as computeSoftTurnCap, U as UNBOUNDED_LOOP_ITERATIONS } from './loopVerify-
|
|
34
|
-
import { p as parseJwtEmail } from './serveAuth-
|
|
34
|
+
import { r as resolveEvaluatorModel, c as backlogOraclePending, d as runLoopVerification, l as loopCancelledDuringVerify, e as resolveLoopDurable, f as decideLoopContinuation, g as resolveMaxAutoResumes, h as grantedExtensionCount, i as resolveMaxExtensions, j as resolveStuckLimit, k as decideVerifyErrorHandling, m as resolveVerifyErrorRetries, t as terminalPhaseForDone, n as accumulateLedger, s as sumUsageTokens, o as effectiveSoftCap, p as checkLoopBudget, q as isHardBudgetStop, u as isCostCeiling, v as summarizeExtensions, w as rearmStartedAt, x as oracleScopeSessionId, y as shouldRearmDormantLoop, z as parseDaemonShareEmails, D as DAEMON_SHARE_EMAILS_ENV, A as applyDaemonShareSeed, a as buildMachineShareUrl, B as recordProgressMarker, C as assessLoopProgress, E as resolveExtensionTurns, F as grantLoopExtension, G as buildGoalCondition, H as computeSoftTurnCap, U as UNBOUNDED_LOOP_ITERATIONS } from './loopVerify-CxAKJB5a.mjs';
|
|
35
|
+
import { p as parseJwtEmail } from './serveAuth-4M0vwMyj.mjs';
|
|
35
36
|
import { getSkillsServer, getArtifactBaseUrl } from './api-BHjyC0Ph.mjs';
|
|
36
37
|
import { l as loadInstanceConfig } from './instance-CeHz5C8v.mjs';
|
|
37
|
-
import {
|
|
38
|
+
import { r as resolveProjectRoot$1, l as listIssues, i as addIssue, q as routeCrewVerdict } from './store-D8dok6_d.mjs';
|
|
38
39
|
import { c as workflowSteps, d as workflowsDir, l as listWorkflows, i as isWorkflowEnabled } from './store-fi0f-ff1.mjs';
|
|
39
40
|
import { randomBytes } from 'node:crypto';
|
|
40
41
|
|
|
@@ -1390,7 +1391,8 @@ async function stageCredentialsForSharing(sessionId) {
|
|
|
1390
1391
|
"-w"
|
|
1391
1392
|
], { encoding: "utf-8", timeout: 5e3 }).trim();
|
|
1392
1393
|
if (keychainData.startsWith("{") || keychainData.startsWith("[")) {
|
|
1393
|
-
await writeFile(stagedCredFile, keychainData);
|
|
1394
|
+
await writeFile(stagedCredFile, keychainData, { mode: 384 });
|
|
1395
|
+
await chmod(stagedCredFile, 384);
|
|
1394
1396
|
}
|
|
1395
1397
|
} catch {
|
|
1396
1398
|
}
|
|
@@ -1550,6 +1552,25 @@ function resolveContainedCwd(directory, cwd, hasSecurityContext) {
|
|
|
1550
1552
|
return resolved;
|
|
1551
1553
|
}
|
|
1552
1554
|
|
|
1555
|
+
function getLoopDir(directory, sessionId) {
|
|
1556
|
+
let root = directory;
|
|
1557
|
+
try {
|
|
1558
|
+
root = resolveProjectRoot$1(directory);
|
|
1559
|
+
} catch {
|
|
1560
|
+
}
|
|
1561
|
+
if (sessionId) {
|
|
1562
|
+
const rooted = join(root, ".svamp", sessionId, "loop");
|
|
1563
|
+
if (existsSync(join(rooted, "loop-state.json"))) return rooted;
|
|
1564
|
+
const rawScoped = join(directory, ".svamp", sessionId, "loop");
|
|
1565
|
+
if (existsSync(join(rawScoped, "loop-state.json"))) return rawScoped;
|
|
1566
|
+
for (const legacy of [join(root, ".claude", "loop"), join(directory, ".claude", "loop")]) {
|
|
1567
|
+
if (existsSync(join(legacy, "loop-state.json"))) return legacy;
|
|
1568
|
+
}
|
|
1569
|
+
return rooted;
|
|
1570
|
+
}
|
|
1571
|
+
return join(root, ".claude", "loop");
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1553
1574
|
const DEFAULT_LOG_PRUNE_POLICY = {
|
|
1554
1575
|
keepFiles: 10,
|
|
1555
1576
|
maxAgeDays: 14,
|
|
@@ -1682,6 +1703,25 @@ function shortRunId(seed) {
|
|
|
1682
1703
|
return (h >>> 0).toString(36).padStart(7, "0").slice(0, 7);
|
|
1683
1704
|
}
|
|
1684
1705
|
const RECONCILE_GRACE_MS = 12e4;
|
|
1706
|
+
const reportedWriteErrnos = /* @__PURE__ */ new Set();
|
|
1707
|
+
const RUN_STORE_LOCK_OPTS = (where) => ({
|
|
1708
|
+
deadlineMs: 3e3,
|
|
1709
|
+
breakOnDeadOwner: true,
|
|
1710
|
+
onFailOpen: (lockPath) => reportRunStoreWriteFailure(
|
|
1711
|
+
`${where}/fail-open`,
|
|
1712
|
+
Object.assign(new Error(`lock timeout on ${lockPath} \u2014 wrote UNLOCKED, a concurrent run record may have been lost`), { code: "ELOCKTIMEOUT" })
|
|
1713
|
+
)
|
|
1714
|
+
});
|
|
1715
|
+
function reportRunStoreWriteFailure(where, err) {
|
|
1716
|
+
const code = String(err?.code || err?.name || "UNKNOWN");
|
|
1717
|
+
if (reportedWriteErrnos.has(code)) return;
|
|
1718
|
+
reportedWriteErrnos.add(code);
|
|
1719
|
+
const hint = code === "ENOSPC" ? " \u2014 THE DISK IS FULL. Workflow run records are being DROPPED, and session transcripts are likely failing to persist too. This also mimics a concurrency bug (#0681/#1631)." : code === "EROFS" ? " \u2014 the filesystem is read-only." : code === "EACCES" || code === "EPERM" ? " \u2014 permission denied on the runs directory." : "";
|
|
1720
|
+
console.error(`[workflow] run-store write failed in ${where} (${code})${hint} Further ${code} failures will not be repeated. (#1631)`);
|
|
1721
|
+
}
|
|
1722
|
+
function __resetRunStoreWriteFailureReporting() {
|
|
1723
|
+
reportedWriteErrnos.clear();
|
|
1724
|
+
}
|
|
1685
1725
|
function recordRun(projectRoot, run) {
|
|
1686
1726
|
try {
|
|
1687
1727
|
const dir = runsDir(projectRoot);
|
|
@@ -1696,8 +1736,9 @@ function recordRun(projectRoot, run) {
|
|
|
1696
1736
|
const tmp = `${file}.tmp-${process.pid}-${randomBytes(4).toString("hex")}`;
|
|
1697
1737
|
writeFileSync(tmp, kept.map((r) => JSON.stringify(r)).join("\n") + "\n");
|
|
1698
1738
|
renameSync(tmp, file);
|
|
1699
|
-
});
|
|
1700
|
-
} catch {
|
|
1739
|
+
}, RUN_STORE_LOCK_OPTS("recordRun"));
|
|
1740
|
+
} catch (err) {
|
|
1741
|
+
reportRunStoreWriteFailure("recordRun", err);
|
|
1701
1742
|
}
|
|
1702
1743
|
}
|
|
1703
1744
|
function loadRuns(projectRoot, workflow) {
|
|
@@ -1740,40 +1781,47 @@ function reconcileInterruptedRuns(projectRoot) {
|
|
|
1740
1781
|
for (const entry of readdirSync(dir)) {
|
|
1741
1782
|
if (!entry.endsWith(".jsonl")) continue;
|
|
1742
1783
|
const file = join(dir, entry);
|
|
1743
|
-
let
|
|
1784
|
+
let fixedHere = 0;
|
|
1744
1785
|
try {
|
|
1745
|
-
|
|
1786
|
+
withFileLock(`${file}.lock`, () => {
|
|
1787
|
+
let runs;
|
|
1746
1788
|
try {
|
|
1747
|
-
|
|
1789
|
+
runs = readFileSync(file, "utf-8").split("\n").filter(Boolean).map((l) => {
|
|
1790
|
+
try {
|
|
1791
|
+
return JSON.parse(l);
|
|
1792
|
+
} catch {
|
|
1793
|
+
return null;
|
|
1794
|
+
}
|
|
1795
|
+
}).filter((r) => !!r);
|
|
1748
1796
|
} catch {
|
|
1749
|
-
return
|
|
1797
|
+
return;
|
|
1750
1798
|
}
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
if (!changed) continue;
|
|
1767
|
-
try {
|
|
1768
|
-
withFileLock(`${file}.lock`, () => {
|
|
1799
|
+
let changed = false;
|
|
1800
|
+
for (const r of runs) {
|
|
1801
|
+
if (r.status !== "running") continue;
|
|
1802
|
+
if (isWorkflowInFlight(projectRoot, r.workflow)) continue;
|
|
1803
|
+
const raw = r.startedAt;
|
|
1804
|
+
const startedMs = typeof raw === "number" ? raw : Date.parse(String(raw ?? ""));
|
|
1805
|
+
if (Number.isFinite(startedMs) && Date.now() - startedMs < RECONCILE_GRACE_MS) continue;
|
|
1806
|
+
r.status = "failed";
|
|
1807
|
+
r.error = r.error || "interrupted by daemon restart";
|
|
1808
|
+
r.finishedAt = r.finishedAt || r.startedAt;
|
|
1809
|
+
changed = true;
|
|
1810
|
+
fixedHere++;
|
|
1811
|
+
}
|
|
1812
|
+
if (!changed) return;
|
|
1813
|
+
const kept = runs.slice(-maxRunsPerWorkflow());
|
|
1769
1814
|
const tmp = `${file}.tmp-${process.pid}-${randomBytes(4).toString("hex")}`;
|
|
1770
|
-
writeFileSync(tmp,
|
|
1815
|
+
writeFileSync(tmp, kept.map((r) => JSON.stringify(r)).join("\n") + "\n");
|
|
1771
1816
|
renameSync(tmp, file);
|
|
1772
|
-
});
|
|
1773
|
-
} catch {
|
|
1817
|
+
}, RUN_STORE_LOCK_OPTS("reconcileInterruptedRuns"));
|
|
1818
|
+
} catch (err) {
|
|
1819
|
+
reportRunStoreWriteFailure("reconcileInterruptedRuns", err);
|
|
1774
1820
|
}
|
|
1821
|
+
fixed += fixedHere;
|
|
1775
1822
|
}
|
|
1776
|
-
} catch {
|
|
1823
|
+
} catch (err) {
|
|
1824
|
+
reportRunStoreWriteFailure("reconcileInterruptedRuns/outer", err);
|
|
1777
1825
|
}
|
|
1778
1826
|
return fixed;
|
|
1779
1827
|
}
|
|
@@ -1960,6 +2008,7 @@ var runStore = /*#__PURE__*/Object.freeze({
|
|
|
1960
2008
|
MAX_RUNS_PER_WORKFLOW: MAX_RUNS_PER_WORKFLOW,
|
|
1961
2009
|
MAX_STREAM_CHARS: MAX_STREAM_CHARS,
|
|
1962
2010
|
STEP_TIMEOUT_MS: STEP_TIMEOUT_MS,
|
|
2011
|
+
__resetRunStoreWriteFailureReporting: __resetRunStoreWriteFailureReporting,
|
|
1963
2012
|
capStream: capStream,
|
|
1964
2013
|
escalateWorkflowFailure: escalateWorkflowFailure,
|
|
1965
2014
|
getRun: getRun,
|
|
@@ -1969,6 +2018,7 @@ var runStore = /*#__PURE__*/Object.freeze({
|
|
|
1969
2018
|
maxRunsPerWorkflow: maxRunsPerWorkflow,
|
|
1970
2019
|
reconcileInterruptedRuns: reconcileInterruptedRuns,
|
|
1971
2020
|
recordRun: recordRun,
|
|
2021
|
+
reportRunStoreWriteFailure: reportRunStoreWriteFailure,
|
|
1972
2022
|
runWorkflow: runWorkflow,
|
|
1973
2023
|
runsDir: runsDir,
|
|
1974
2024
|
stepTimeoutMs: stepTimeoutMs
|
|
@@ -2353,7 +2403,16 @@ function acquireSupervisorLock(pidFile, pid = process.pid) {
|
|
|
2353
2403
|
}
|
|
2354
2404
|
return { acquired: false, staleCleaned: true };
|
|
2355
2405
|
}
|
|
2356
|
-
|
|
2406
|
+
const alive = isPidAlive(existingPid);
|
|
2407
|
+
const verdict = classifyLockHolder({
|
|
2408
|
+
pid: existingPid,
|
|
2409
|
+
alive,
|
|
2410
|
+
// Only interrogate a live pid — a dead one is already stale, and `ps` costs a fork.
|
|
2411
|
+
holderStartedMs: alive ? readProcessStartMs(existingPid) : null,
|
|
2412
|
+
lockWrittenMs: getFileWrittenMs(pidFile),
|
|
2413
|
+
bootTimeMs: getBootTimeMs()
|
|
2414
|
+
});
|
|
2415
|
+
if (verdict === "held") {
|
|
2357
2416
|
return { acquired: false, heldBy: existingPid };
|
|
2358
2417
|
}
|
|
2359
2418
|
try {
|
|
@@ -2362,6 +2421,62 @@ function acquireSupervisorLock(pidFile, pid = process.pid) {
|
|
|
2362
2421
|
}
|
|
2363
2422
|
return { acquired: false, staleCleaned: true };
|
|
2364
2423
|
}
|
|
2424
|
+
const RECYCLED_PID_TOLERANCE_MS = 5e3;
|
|
2425
|
+
function classifyLockHolder(opts) {
|
|
2426
|
+
const { pid, alive, holderStartedMs = null, lockWrittenMs = null, bootTimeMs = null } = opts;
|
|
2427
|
+
if (!pid || Number.isNaN(pid) || pid <= 0) return "stale";
|
|
2428
|
+
if (!alive) return "stale";
|
|
2429
|
+
if (bootTimeMs !== null && lockWrittenMs !== null && lockWrittenMs < bootTimeMs) return "stale";
|
|
2430
|
+
if (holderStartedMs !== null && lockWrittenMs !== null && holderStartedMs > lockWrittenMs + RECYCLED_PID_TOLERANCE_MS) {
|
|
2431
|
+
return "stale";
|
|
2432
|
+
}
|
|
2433
|
+
return "held";
|
|
2434
|
+
}
|
|
2435
|
+
function readProcessStartMs(pid) {
|
|
2436
|
+
if (!pid || Number.isNaN(pid) || pid <= 0) return null;
|
|
2437
|
+
if (process.platform === "win32") return null;
|
|
2438
|
+
try {
|
|
2439
|
+
const out = execFileSync("ps", ["-ww", "-o", "lstart=", "-p", String(pid)], {
|
|
2440
|
+
encoding: "utf-8",
|
|
2441
|
+
timeout: 5e3,
|
|
2442
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2443
|
+
}).trim();
|
|
2444
|
+
if (!out) return null;
|
|
2445
|
+
const ms = Date.parse(out);
|
|
2446
|
+
return Number.isFinite(ms) ? ms : null;
|
|
2447
|
+
} catch {
|
|
2448
|
+
return null;
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
function getFileWrittenMs(file) {
|
|
2452
|
+
try {
|
|
2453
|
+
return statSync(file).mtimeMs;
|
|
2454
|
+
} catch {
|
|
2455
|
+
return null;
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
function getBootTimeMs() {
|
|
2459
|
+
if (process.platform === "win32") return null;
|
|
2460
|
+
try {
|
|
2461
|
+
if (process.platform === "linux") {
|
|
2462
|
+
const uptimeSec = parseFloat(readFileSync("/proc/uptime", "utf-8").trim().split(/\s+/)[0]);
|
|
2463
|
+
if (!Number.isFinite(uptimeSec) || uptimeSec < 0) return null;
|
|
2464
|
+
return Date.now() - uptimeSec * 1e3;
|
|
2465
|
+
}
|
|
2466
|
+
const out = execFileSync("sysctl", ["-n", "kern.boottime"], {
|
|
2467
|
+
encoding: "utf-8",
|
|
2468
|
+
timeout: 5e3,
|
|
2469
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
2470
|
+
});
|
|
2471
|
+
const m = out.match(/sec\s*=\s*(\d+)/);
|
|
2472
|
+
if (!m) return null;
|
|
2473
|
+
const sec = parseInt(m[1], 10);
|
|
2474
|
+
if (!Number.isFinite(sec) || sec <= 0) return null;
|
|
2475
|
+
return sec * 1e3;
|
|
2476
|
+
} catch {
|
|
2477
|
+
return null;
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2365
2480
|
function acquireSupervisorLockWithRetry(pidFile, pid = process.pid) {
|
|
2366
2481
|
let result = acquireSupervisorLock(pidFile, pid);
|
|
2367
2482
|
if (!result.acquired && result.staleCleaned) {
|
|
@@ -2390,7 +2505,7 @@ function isSupervisorPid(pid) {
|
|
|
2390
2505
|
if (!pid || Number.isNaN(pid) || pid <= 0) return false;
|
|
2391
2506
|
if (process.platform === "win32") return null;
|
|
2392
2507
|
try {
|
|
2393
|
-
const out = execFileSync("ps", ["-o", "command=", "-p", String(pid)], {
|
|
2508
|
+
const out = execFileSync("ps", ["-ww", "-o", "command=", "-p", String(pid)], {
|
|
2394
2509
|
encoding: "utf-8",
|
|
2395
2510
|
timeout: 5e3,
|
|
2396
2511
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -2510,11 +2625,15 @@ var supervisorLock = /*#__PURE__*/Object.freeze({
|
|
|
2510
2625
|
__proto__: null,
|
|
2511
2626
|
acquireSupervisorLock: acquireSupervisorLock,
|
|
2512
2627
|
acquireSupervisorLockWithRetry: acquireSupervisorLockWithRetry,
|
|
2628
|
+
classifyLockHolder: classifyLockHolder,
|
|
2513
2629
|
findOrphanedSyncPids: findOrphanedSyncPids,
|
|
2630
|
+
getBootTimeMs: getBootTimeMs,
|
|
2631
|
+
getFileWrittenMs: getFileWrittenMs,
|
|
2514
2632
|
getPpid: getPpid,
|
|
2515
2633
|
isPidAlive: isPidAlive,
|
|
2516
2634
|
isSupervisorPid: isSupervisorPid,
|
|
2517
2635
|
killOrphanedSyncs: killOrphanedSyncs,
|
|
2636
|
+
readProcessStartMs: readProcessStartMs,
|
|
2518
2637
|
releaseSupervisorLock: releaseSupervisorLock,
|
|
2519
2638
|
shouldSignalSupervisor: shouldSignalSupervisor,
|
|
2520
2639
|
watchParentLiveness: watchParentLiveness
|
|
@@ -3119,16 +3238,6 @@ function writeSvampConfig(configPath, config) {
|
|
|
3119
3238
|
}
|
|
3120
3239
|
const DEFAULT_LOOP_MAX_ITERATIONS = UNBOUNDED_LOOP_ITERATIONS;
|
|
3121
3240
|
const LOOP_CHECKPOINT_CADENCE = 25;
|
|
3122
|
-
function getLoopDir(directory, sessionId) {
|
|
3123
|
-
if (sessionId) {
|
|
3124
|
-
const scoped = join$1(directory, ".svamp", sessionId, "loop");
|
|
3125
|
-
if (existsSync$1(join$1(scoped, "loop-state.json"))) return scoped;
|
|
3126
|
-
const legacy = join$1(directory, ".claude", "loop");
|
|
3127
|
-
if (existsSync$1(join$1(legacy, "loop-state.json"))) return legacy;
|
|
3128
|
-
return scoped;
|
|
3129
|
-
}
|
|
3130
|
-
return join$1(directory, ".claude", "loop");
|
|
3131
|
-
}
|
|
3132
3241
|
function readLoopState(directory, sessionId) {
|
|
3133
3242
|
try {
|
|
3134
3243
|
const p = join$1(getLoopDir(directory, sessionId), "loop-state.json");
|
|
@@ -4237,7 +4346,11 @@ async function startDaemon(options) {
|
|
|
4237
4346
|
function saveExposedTunnels(specs) {
|
|
4238
4347
|
try {
|
|
4239
4348
|
mkdirSync$1(SVAMP_HOME, { recursive: true });
|
|
4240
|
-
writeFileSync$1(EXPOSED_TUNNELS_FILE, JSON.stringify({ tunnels: specs }, null, 2));
|
|
4349
|
+
writeFileSync$1(EXPOSED_TUNNELS_FILE, JSON.stringify({ tunnels: specs }, null, 2), { mode: 384 });
|
|
4350
|
+
try {
|
|
4351
|
+
chmodSync(EXPOSED_TUNNELS_FILE, 384);
|
|
4352
|
+
} catch {
|
|
4353
|
+
}
|
|
4241
4354
|
} catch (err) {
|
|
4242
4355
|
logger.log(`[exposed-tunnels] Persist failed: ${err.message}`);
|
|
4243
4356
|
}
|
|
@@ -4256,7 +4369,7 @@ async function startDaemon(options) {
|
|
|
4256
4369
|
try {
|
|
4257
4370
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
4258
4371
|
if (!dir) return;
|
|
4259
|
-
const { reconcileServiceLinks } = await import('./agentCommands-
|
|
4372
|
+
const { reconcileServiceLinks } = await import('./agentCommands-C_KvvYFp.mjs');
|
|
4260
4373
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
4261
4374
|
const config = readSvampConfig(configPath);
|
|
4262
4375
|
const entries = Array.from(urls.entries());
|
|
@@ -4278,7 +4391,7 @@ async function startDaemon(options) {
|
|
|
4278
4391
|
try {
|
|
4279
4392
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
4280
4393
|
if (!dir) return;
|
|
4281
|
-
const { reconcileServiceLinks } = await import('./agentCommands-
|
|
4394
|
+
const { reconcileServiceLinks } = await import('./agentCommands-C_KvvYFp.mjs');
|
|
4282
4395
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
4283
4396
|
const config = readSvampConfig(configPath);
|
|
4284
4397
|
const incoming = [{
|
|
@@ -4299,7 +4412,7 @@ async function startDaemon(options) {
|
|
|
4299
4412
|
try {
|
|
4300
4413
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
4301
4414
|
if (!dir) return;
|
|
4302
|
-
const { dropServiceLinks } = await import('./agentCommands-
|
|
4415
|
+
const { dropServiceLinks } = await import('./agentCommands-C_KvvYFp.mjs');
|
|
4303
4416
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
4304
4417
|
const config = readSvampConfig(configPath);
|
|
4305
4418
|
if (dropServiceLinks(config, "serve", mountName)) {
|
|
@@ -4315,7 +4428,7 @@ async function startDaemon(options) {
|
|
|
4315
4428
|
try {
|
|
4316
4429
|
const dir = loadSessionIndex()[sessionId]?.directory;
|
|
4317
4430
|
if (!dir) return;
|
|
4318
|
-
const { dropServiceLinks } = await import('./agentCommands-
|
|
4431
|
+
const { dropServiceLinks } = await import('./agentCommands-C_KvvYFp.mjs');
|
|
4319
4432
|
const configPath = getSvampConfigPath(dir, sessionId);
|
|
4320
4433
|
const config = readSvampConfig(configPath);
|
|
4321
4434
|
if (dropServiceLinks(config, "tunnel", tunnelName)) {
|
|
@@ -4332,7 +4445,7 @@ async function startDaemon(options) {
|
|
|
4332
4445
|
let managedLinkSessionsSeeded = false;
|
|
4333
4446
|
async function reconcileAllServiceLinks() {
|
|
4334
4447
|
try {
|
|
4335
|
-
const { reconcileServiceLinksExact, hasManagedServiceLink } = await import('./agentCommands-
|
|
4448
|
+
const { reconcileServiceLinksExact, hasManagedServiceLink } = await import('./agentCommands-C_KvvYFp.mjs');
|
|
4336
4449
|
const desiredBySession = /* @__PURE__ */ new Map();
|
|
4337
4450
|
const push = (sessionId, entry) => {
|
|
4338
4451
|
if (!sessionId || !entry.url) return;
|
|
@@ -4406,7 +4519,7 @@ async function startDaemon(options) {
|
|
|
4406
4519
|
}, delayMs);
|
|
4407
4520
|
}
|
|
4408
4521
|
async function createExposedTunnel(spec) {
|
|
4409
|
-
const { FrpcTunnel } = await import('./hookSettings-
|
|
4522
|
+
const { FrpcTunnel } = await import('./hookSettings-CvvUhwCK.mjs').then(function (n) { return n.w; });
|
|
4410
4523
|
const tunnel = new FrpcTunnel({
|
|
4411
4524
|
name: spec.name,
|
|
4412
4525
|
ports: spec.ports,
|
|
@@ -4427,7 +4540,7 @@ async function startDaemon(options) {
|
|
|
4427
4540
|
}
|
|
4428
4541
|
const tunnelRecreateState = /* @__PURE__ */ new Map();
|
|
4429
4542
|
const tunnelRecreateInFlight = /* @__PURE__ */ new Set();
|
|
4430
|
-
const { ServeManager } = await import('./hookSettings-
|
|
4543
|
+
const { ServeManager } = await import('./hookSettings-CvvUhwCK.mjs').then(function (n) { return n.y; });
|
|
4431
4544
|
const serveManager = new ServeManager(SVAMP_HOME, (msg) => logger.log(`[SERVE] ${msg}`), hyphaServerUrl);
|
|
4432
4545
|
serveManager.setMountUnboundHook((sessionId, mountName) => {
|
|
4433
4546
|
void dropMountSessionLink(sessionId, mountName);
|
|
@@ -5354,21 +5467,34 @@ ${parts.join("\n")}`);
|
|
|
5354
5467
|
} catch (e) {
|
|
5355
5468
|
logger.log(`[Session ${sessionId}] verifyGoalCompletion threw \u2014 failing closed (retry/park): ${e?.message || e}`);
|
|
5356
5469
|
try {
|
|
5470
|
+
const curLsErr = readLoopState(directory, sessionId);
|
|
5471
|
+
if (loopCancelledDuringVerify(curLsErr)) {
|
|
5472
|
+
logger.log(`[Session ${sessionId}] loop was cancelled during a FAILED verification \u2014 not re-kicking (#0308/#1542)`);
|
|
5473
|
+
return;
|
|
5474
|
+
}
|
|
5475
|
+
const freshErr = curLsErr || ls;
|
|
5476
|
+
const carry = {
|
|
5477
|
+
ledger: freshErr.ledger ?? ls.ledger,
|
|
5478
|
+
progress_history: freshErr.progress_history ?? ls.progress_history,
|
|
5479
|
+
extensions: freshErr.extensions ?? ls.extensions,
|
|
5480
|
+
auto_resumes: freshErr.auto_resumes ?? ls.auto_resumes,
|
|
5481
|
+
holds: freshErr.holds ?? ls.holds
|
|
5482
|
+
};
|
|
5357
5483
|
const durable2 = resolveLoopDurable({ durable: ls.durable, oracle: oracleCmd });
|
|
5358
5484
|
const decision = decideVerifyErrorHandling({
|
|
5359
|
-
priorErrors: ls.verify_errors,
|
|
5485
|
+
priorErrors: freshErr.verify_errors ?? ls.verify_errors,
|
|
5360
5486
|
maxRetries: resolveVerifyErrorRetries(process.env.SVAMP_LOOP_VERIFY_ERROR_RETRIES),
|
|
5361
5487
|
reason: `verify threw: ${e?.message || e}`
|
|
5362
5488
|
});
|
|
5363
5489
|
if (decision.action === "retry") {
|
|
5364
5490
|
const cond = ls.task || "";
|
|
5365
|
-
writeGoalLoopState(directory, sessionId, { ...ls, active: true, phase: "continue", started_at: startedAt, verify_errors: decision.attempt });
|
|
5491
|
+
writeGoalLoopState(directory, sessionId, { ...ls, ...carry, active: true, phase: "continue", started_at: startedAt, verify_errors: decision.attempt });
|
|
5366
5492
|
sessionService.pushMessage({ type: "message", message: `\u26A0\uFE0F Loop verification error \u2014 ${decision.reason}`, level: "warning" }, "event");
|
|
5367
5493
|
enqueueLoopMessage(`/goal ${cond} \u2014 the completion check could not run; CONTINUE and it will be re-verified. Not done.`, "\u26A0\uFE0F Re-verifying loop");
|
|
5368
5494
|
if (!trackedSession.stopped) setTimeout(() => processMessageQueueRef?.(), 200);
|
|
5369
5495
|
} else {
|
|
5370
5496
|
const parkPhase = terminalPhaseForDone(durable2);
|
|
5371
|
-
writeGoalLoopState(directory, sessionId, { ...ls, active: parkPhase === "dormant", phase: parkPhase, completed_at: Date.now(), verify_errors: 0 });
|
|
5497
|
+
writeGoalLoopState(directory, sessionId, { ...ls, ...carry, active: parkPhase === "dormant", phase: parkPhase, completed_at: Date.now(), verify_errors: 0 });
|
|
5372
5498
|
checkSvampConfig?.();
|
|
5373
5499
|
}
|
|
5374
5500
|
} catch {
|
|
@@ -5851,7 +5977,7 @@ ${parts.join("\n")}`);
|
|
|
5851
5977
|
const hasBackgroundTasks = backgroundTaskCount > 0;
|
|
5852
5978
|
if (hasBackgroundTasks) {
|
|
5853
5979
|
const taskInfo = `Background tasks still running (${backgroundTaskCount}): ${backgroundTaskNames.join(", ")}`;
|
|
5854
|
-
sessionService.pushMessage({ type: "
|
|
5980
|
+
sessionService.pushMessage({ type: "message", message: taskInfo, level: "warning" }, "event");
|
|
5855
5981
|
}
|
|
5856
5982
|
signalProcessing(false);
|
|
5857
5983
|
sessionWasProcessing = false;
|
|
@@ -5974,7 +6100,7 @@ ${parts.join("\n")}`);
|
|
|
5974
6100
|
if (backgroundTaskCount > 0) {
|
|
5975
6101
|
const taskInfo = `Background tasks still running (${backgroundTaskCount}): ${backgroundTaskNames.join(", ")}`;
|
|
5976
6102
|
logger.log(`[Session ${sessionId}] ${taskInfo}`);
|
|
5977
|
-
sessionService.pushMessage({ type: "
|
|
6103
|
+
sessionService.pushMessage({ type: "message", message: taskInfo, level: "warning" }, "event");
|
|
5978
6104
|
}
|
|
5979
6105
|
justCompactedTurn = false;
|
|
5980
6106
|
compactTurnLatch = false;
|
|
@@ -6889,12 +7015,12 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
6889
7015
|
});
|
|
6890
7016
|
},
|
|
6891
7017
|
onIssue: async (params) => {
|
|
6892
|
-
const { issueRpc } = await import('./rpc-
|
|
7018
|
+
const { issueRpc } = await import('./rpc-CAlAHQAy.mjs');
|
|
6893
7019
|
const issueCwd = resolveContainedCwd(directory, params?.cwd, !!sessionMetadata.securityContext);
|
|
6894
7020
|
return issueRpc(issueCwd, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
6895
7021
|
},
|
|
6896
7022
|
onWorkflow: async (params) => {
|
|
6897
|
-
const { workflowRpc } = await import('./rpc-
|
|
7023
|
+
const { workflowRpc } = await import('./rpc-CacreLQ8.mjs');
|
|
6898
7024
|
const wfCwd = resolveContainedCwd(directory, params?.cwd, !!sessionMetadata.securityContext);
|
|
6899
7025
|
return workflowRpc(wfCwd, params || {});
|
|
6900
7026
|
},
|
|
@@ -7646,12 +7772,12 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
|
|
|
7646
7772
|
});
|
|
7647
7773
|
},
|
|
7648
7774
|
onIssue: async (params) => {
|
|
7649
|
-
const { issueRpc } = await import('./rpc-
|
|
7775
|
+
const { issueRpc } = await import('./rpc-CAlAHQAy.mjs');
|
|
7650
7776
|
const issueCwd = resolveContainedCwd(directory, params?.cwd, !!sessionMetadata.securityContext);
|
|
7651
7777
|
return issueRpc(issueCwd, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
|
|
7652
7778
|
},
|
|
7653
7779
|
onWorkflow: async (params) => {
|
|
7654
|
-
const { workflowRpc } = await import('./rpc-
|
|
7780
|
+
const { workflowRpc } = await import('./rpc-CacreLQ8.mjs');
|
|
7655
7781
|
const wfCwd = resolveContainedCwd(directory, params?.cwd, !!sessionMetadata.securityContext);
|
|
7656
7782
|
return workflowRpc(wfCwd, params || {});
|
|
7657
7783
|
},
|
|
@@ -8391,6 +8517,24 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
8391
8517
|
}
|
|
8392
8518
|
return { success: false, message: `Session ${sessionId} not found or already stopped.` };
|
|
8393
8519
|
};
|
|
8520
|
+
{
|
|
8521
|
+
let lastEntitlementState;
|
|
8522
|
+
const runEntitlementProbe = (first) => {
|
|
8523
|
+
const env = {};
|
|
8524
|
+
applyClaudeProxyEnv(env);
|
|
8525
|
+
void probeLongContext1MEntitlement(env.ANTHROPIC_BASE_URL, env.ANTHROPIC_API_KEY).then((state) => {
|
|
8526
|
+
if (!first && state === lastEntitlementState) return;
|
|
8527
|
+
lastEntitlementState = state;
|
|
8528
|
+
if (state === "entitled") logger.log("[1m-context] entitlement confirmed \u2014 sessions will request the 1M window");
|
|
8529
|
+
else if (state === "not-entitled") logger.log("[1m-context] NOT entitled for this account \u2014 NOT requesting the 1M beta (sessions compact at the 200K window). See #1585.");
|
|
8530
|
+
else logger.log("[1m-context] entitlement could not be determined \u2014 NOT requesting the 1M beta (safe default). See #1585.");
|
|
8531
|
+
}).catch(() => {
|
|
8532
|
+
});
|
|
8533
|
+
};
|
|
8534
|
+
runEntitlementProbe(true);
|
|
8535
|
+
const entitlementTimer = setInterval(() => runEntitlementProbe(false), LONG_CONTEXT_ENTITLEMENT_RECHECK_MS);
|
|
8536
|
+
if (typeof entitlementTimer.unref === "function") entitlementTimer.unref();
|
|
8537
|
+
}
|
|
8394
8538
|
let isolationCapabilities;
|
|
8395
8539
|
try {
|
|
8396
8540
|
isolationCapabilities = await detectIsolationCapabilities();
|
|
@@ -9007,13 +9151,18 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
|
|
|
9007
9151
|
const PING_TIMEOUT_MS = 15e3;
|
|
9008
9152
|
const POST_RECONNECT_GRACE_MS = 2e4;
|
|
9009
9153
|
const RECONNECT_JITTER_MS = 2500;
|
|
9010
|
-
const { WorkflowScheduler } = await import('./scheduler-
|
|
9154
|
+
const { WorkflowScheduler } = await import('./scheduler-IyLWBF8T.mjs');
|
|
9011
9155
|
const workflowProjectRoots = () => {
|
|
9012
|
-
const
|
|
9156
|
+
const roots = /* @__PURE__ */ new Set();
|
|
9013
9157
|
for (const s of pidToTrackedSession.values()) {
|
|
9014
|
-
if (
|
|
9158
|
+
if (s.stopped || !s.directory) continue;
|
|
9159
|
+
try {
|
|
9160
|
+
roots.add(resolveProjectRoot$1(s.directory));
|
|
9161
|
+
} catch {
|
|
9162
|
+
roots.add(s.directory);
|
|
9163
|
+
}
|
|
9015
9164
|
}
|
|
9016
|
-
return [...
|
|
9165
|
+
return [...roots];
|
|
9017
9166
|
};
|
|
9018
9167
|
try {
|
|
9019
9168
|
const { reconcileInterruptedRuns } = await Promise.resolve().then(function () { return runStore; });
|
|
@@ -9692,4 +9841,4 @@ var run = /*#__PURE__*/Object.freeze({
|
|
|
9692
9841
|
writeStopMarker: writeStopMarker
|
|
9693
9842
|
});
|
|
9694
9843
|
|
|
9695
|
-
export { stopDaemon as a, stopMarkerExists as b, clearStopMarker as c, daemonStatus as d,
|
|
9844
|
+
export { stopDaemon as a, stopMarkerExists as b, clearStopMarker as c, daemonStatus as d, loadRuns as e, runStore as f, getRun as g, supervisorLock as h, run as i, listRuns as l, projectInfo as p, runWorkflow as r, startDaemon as s };
|