svamp-cli 0.2.346 → 0.2.356

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.
Files changed (30) hide show
  1. package/bin/skills/artifact/SKILL.md +19 -5
  2. package/bin/skills/crew/SKILL.md +42 -11
  3. package/dist/{acpBackend-BZ1MJhQV.mjs → acpBackend-UaBD4zL3.mjs} +3 -0
  4. package/dist/{agentCommands-B2Nl7Fof.mjs → agentCommands-D91RcjqQ.mjs} +4 -4
  5. package/dist/{claudeAuth-iAerdaMr.mjs → claudeAuth-C0wc1GTM.mjs} +45 -1
  6. package/dist/cli.mjs +78 -69
  7. package/dist/{commands-D1pZq3d4.mjs → commands-B-yczgz_.mjs} +14 -10
  8. package/dist/{commands-BOpoVBOM.mjs → commands-BMeDrpSv.mjs} +3 -3
  9. package/dist/{commands-H4PsTGn8.mjs → commands-BbmypSgx.mjs} +5 -2
  10. package/dist/{commands-C2aODeVc.mjs → commands-BkdbelFo.mjs} +26 -11
  11. package/dist/{commands-BB1Kcyt-.mjs → commands-C13-yE2R.mjs} +32 -3
  12. package/dist/{commands-D69mnkYu.mjs → commands-CoOc4qiw.mjs} +2 -2
  13. package/dist/{commands-CiRCwjkJ.mjs → commands-sPvRcG3J.mjs} +9 -9
  14. package/dist/{detectIsolation-CzoDCEnh.mjs → detectIsolation-CrV8IFDv.mjs} +36 -16
  15. package/dist/{fleet-DM_Q7w69.mjs → fleet-Ca-UjJNL.mjs} +40 -15
  16. package/dist/{hookSettings-DYMTUgVA.mjs → hookSettings-FFc1pi8j.mjs} +174 -27
  17. package/dist/index.mjs +8 -8
  18. package/dist/{loopVerify-B47sSjxe.mjs → loopVerify-DALtTk2V.mjs} +1 -1
  19. package/dist/{notifyCommands-D-IKIxiq.mjs → notifyCommands-CCUE18Q-.mjs} +1 -1
  20. package/dist/package-BrsiNutS.mjs +64 -0
  21. package/dist/{rpc-BB6RF4-F.mjs → rpc-CBkSkzsI.mjs} +8 -8
  22. package/dist/{rpc-Cf0grcru.mjs → rpc-ccY7xvlo.mjs} +6 -3
  23. package/dist/{run-ChdsgaSD.mjs → run-DCq3aEiF.mjs} +3 -3
  24. package/dist/{run-DkjwF-zA.mjs → run-DDmeV9K3.mjs} +190 -59
  25. package/dist/{scheduler-BY30ZrB9.mjs → scheduler-BkVJ27Ki.mjs} +8 -8
  26. package/dist/{serveAuth-DbVLRCRR.mjs → serveAuth-4M0vwMyj.mjs} +53 -11
  27. package/dist/{serveCommands-CUHUiYnZ.mjs → serveCommands-CLhkccJM.mjs} +8 -8
  28. package/dist/{store-Bn0ByYev.mjs → store-B4E6NzG6.mjs} +10 -1
  29. package/package.json +2 -2
  30. package/dist/package-DtuINqf5.mjs +0 -64
@@ -1,4 +1,4 @@
1
- import { r as resolveProjectRoot, u as updateIssue, p as parseScopeArg, I as ISSUE_SCOPES, g as getIssue, c as checkVerifyCommandAsync, a as parseStatusArg, b as ISSUE_STATUSES, d as resumeIssue, e as pauseIssue, f as addComment, h as addIssue, l as listIssues, i as isPendingIssue, s as searchIssues, j as isVisibleTo } from './store-Bn0ByYev.mjs';
1
+ import { r as resolveProjectRoot, a as applyTriageStatus, u as updateIssue, p as parseScopeArg, I as ISSUE_SCOPES, g as getIssue, c as checkVerifyCommandAsync, b as parseStatusArg, d as ISSUE_STATUSES, e as resumeIssue, f as pauseIssue, h as addComment, i as addIssue, l as listIssues, j as isPendingIssue, s as searchIssues, k as isVisibleTo } from './store-B4E6NzG6.mjs';
2
2
  import 'node:fs';
3
3
  import 'node:path';
4
4
  import 'node:crypto';
@@ -66,7 +66,8 @@ async function issueRpc(cwd, params, deps = {}) {
66
66
  }
67
67
  case "add": {
68
68
  const owner = params.session || null;
69
- const scope = params.scope || (owner ? "session" : "project");
69
+ const scope = params.scope == null ? owner ? "session" : "project" : parseScopeArg(params.scope);
70
+ if (!scope) throw new Error(`issue add: invalid --scope "${String(params.scope)}" (expected one of: ${ISSUE_SCOPES.join(", ")})`);
70
71
  let title = params.title ? String(params.title) : "";
71
72
  let body = params.body ? String(params.body) : void 0;
72
73
  let original;
@@ -201,7 +202,9 @@ ${res.output || ""}
201
202
  const v = buildVerify(params);
202
203
  if (v) patch.verify = v;
203
204
  if (params.body != null) patch.body = String(params.body);
204
- patch.status = "ready";
205
+ applyTriageStatus(root, String(params.id), patch, (m) => {
206
+ throw new Error(m);
207
+ });
205
208
  const updated = updateIssue(root, String(params.id), patch);
206
209
  if (!updated) throw new Error(`Issue not found: ${params.id}`);
207
210
  return updated;
@@ -3,10 +3,10 @@ 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-DYMTUgVA.mjs';
6
+ import { c as createSessionStore, r as registerMachineService, g as generateHookSettings } from './hookSettings-FFc1pi8j.mjs';
7
7
  import { createServer } from 'node:http';
8
8
  import { spawn } from 'node:child_process';
9
- import { applyClaudeProxyEnv } from './claudeAuth-iAerdaMr.mjs';
9
+ import { applyClaudeProxyEnv } from './claudeAuth-C0wc1GTM.mjs';
10
10
  import { createInterface } from 'node:readline';
11
11
  import 'node:crypto';
12
12
  import 'fs';
@@ -23,7 +23,7 @@ import 'http';
23
23
  import 'net';
24
24
  import 'os';
25
25
  import './instance-CeHz5C8v.mjs';
26
- import './serveAuth-DbVLRCRR.mjs';
26
+ import './serveAuth-4M0vwMyj.mjs';
27
27
  import './envFlag-COOuJ3AH.mjs';
28
28
  import './codexProvider-BtxYc5Rj.mjs';
29
29
  import './fileLock-BMPwCrB6.mjs';
@@ -1,11 +1,11 @@
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-DYMTUgVA.mjs';
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-FFc1pi8j.mjs';
9
9
  import { a as composeSessionId, g as generateFriendlyName, d as friendlyNameFromId, f as formatHandle, e as clearInboundContext, w as writeInboundContext, i as isHopCapParked, j as classifyInbound, k as consumeAwaitingReply, l as peekAwaitingReply } from './friendlyName-1UZcyDhu.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';
@@ -13,7 +13,7 @@ import { join, dirname, basename, resolve as resolve$1 } from 'node:path';
13
13
  import { c as connectToHypha } from './hyphaClient-ybivOjZo.mjs';
14
14
  import { execSync, execFileSync, spawn } from 'node:child_process';
15
15
  import { S as SharingNotificationSync } from './sharingNotificationSync-qGIQ-3yf.mjs';
16
- import { AcpBackend } from './acpBackend-BZ1MJhQV.mjs';
16
+ import { AcpBackend } from './acpBackend-UaBD4zL3.mjs';
17
17
  import { KNOWN_ACP_AGENTS, KNOWN_CODEX_AGENTS } from './acpAgentConfig-CObOPlA8.mjs';
18
18
  import { c as codexAppServerAvailable, C as CodexAppServerBackend } from './codexAppServerBackend-VGsYtbqg.mjs';
19
19
  import { codexPermissionSettings, codexForcedModel, codexModelMenu, codexClampModel, resolveCodexProvider, codexDefaultModel } from './codexProvider-BtxYc5Rj.mjs';
@@ -22,19 +22,19 @@ import { GeminiTransport } from './GeminiTransport-3OkhtFRO.mjs';
22
22
  import { KimiTransport } from './KimiTransport-D8n009Tr.mjs';
23
23
  import { kimiModelMenu, kimiClampModel, kimiSpawnEnv, kimiDefaultModel } from './kimiProvider-DbxODebR.mjs';
24
24
  import { ensureKimiProviderConfigured } from './kimiSetup-NGsoYB5h.mjs';
25
- import { detectIsolationCapabilities } from './detectIsolation-CzoDCEnh.mjs';
25
+ import { detectIsolationCapabilities } from './detectIsolation-CrV8IFDv.mjs';
26
26
  import { w as wrapWithIsolation } from './wrapCommand-CdNawSaa.mjs';
27
27
  import { applySecurityContext } from './securityContext-Cm5UTCuD.mjs';
28
- import { mkdir, copyFile, writeFile, rm, readdir, stat, readFile, rename } from 'node:fs/promises';
28
+ import { mkdir, copyFile, writeFile, chmod, rm, readdir, stat, readFile, rename } from 'node:fs/promises';
29
29
  import { homedir, platform } from 'node:os';
30
- import { applyClaudeProxyEnv, updateEnvFile } from './claudeAuth-iAerdaMr.mjs';
30
+ import { applyClaudeProxyEnv, probeLongContext1MEntitlement, LONG_CONTEXT_ENTITLEMENT_RECHECK_MS, updateEnvFile } from './claudeAuth-C0wc1GTM.mjs';
31
31
  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
32
  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-B47sSjxe.mjs';
34
- import { p as parseJwtEmail } from './serveAuth-DbVLRCRR.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-DALtTk2V.mjs';
34
+ import { p as parseJwtEmail } from './serveAuth-4M0vwMyj.mjs';
35
35
  import { getSkillsServer, getArtifactBaseUrl } from './api-BHjyC0Ph.mjs';
36
36
  import { l as loadInstanceConfig } from './instance-CeHz5C8v.mjs';
37
- import { l as listIssues, h as addIssue, o as routeCrewVerdict, r as resolveProjectRoot$1 } from './store-Bn0ByYev.mjs';
37
+ import { l as listIssues, i as addIssue, q as routeCrewVerdict, r as resolveProjectRoot$1 } from './store-B4E6NzG6.mjs';
38
38
  import { c as workflowSteps, d as workflowsDir, l as listWorkflows, i as isWorkflowEnabled } from './store-fi0f-ff1.mjs';
39
39
  import { randomBytes } from 'node:crypto';
40
40
 
@@ -1390,7 +1390,8 @@ async function stageCredentialsForSharing(sessionId) {
1390
1390
  "-w"
1391
1391
  ], { encoding: "utf-8", timeout: 5e3 }).trim();
1392
1392
  if (keychainData.startsWith("{") || keychainData.startsWith("[")) {
1393
- await writeFile(stagedCredFile, keychainData);
1393
+ await writeFile(stagedCredFile, keychainData, { mode: 384 });
1394
+ await chmod(stagedCredFile, 384);
1394
1395
  }
1395
1396
  } catch {
1396
1397
  }
@@ -1682,6 +1683,17 @@ function shortRunId(seed) {
1682
1683
  return (h >>> 0).toString(36).padStart(7, "0").slice(0, 7);
1683
1684
  }
1684
1685
  const RECONCILE_GRACE_MS = 12e4;
1686
+ const reportedWriteErrnos = /* @__PURE__ */ new Set();
1687
+ function reportRunStoreWriteFailure(where, err) {
1688
+ const code = String(err?.code || err?.name || "UNKNOWN");
1689
+ if (reportedWriteErrnos.has(code)) return;
1690
+ reportedWriteErrnos.add(code);
1691
+ 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." : "";
1692
+ console.error(`[workflow] run-store write failed in ${where} (${code})${hint} Further ${code} failures will not be repeated. (#1631)`);
1693
+ }
1694
+ function __resetRunStoreWriteFailureReporting() {
1695
+ reportedWriteErrnos.clear();
1696
+ }
1685
1697
  function recordRun(projectRoot, run) {
1686
1698
  try {
1687
1699
  const dir = runsDir(projectRoot);
@@ -1697,7 +1709,8 @@ function recordRun(projectRoot, run) {
1697
1709
  writeFileSync(tmp, kept.map((r) => JSON.stringify(r)).join("\n") + "\n");
1698
1710
  renameSync(tmp, file);
1699
1711
  });
1700
- } catch {
1712
+ } catch (err) {
1713
+ reportRunStoreWriteFailure("recordRun", err);
1701
1714
  }
1702
1715
  }
1703
1716
  function loadRuns(projectRoot, workflow) {
@@ -1740,40 +1753,47 @@ function reconcileInterruptedRuns(projectRoot) {
1740
1753
  for (const entry of readdirSync(dir)) {
1741
1754
  if (!entry.endsWith(".jsonl")) continue;
1742
1755
  const file = join(dir, entry);
1743
- let runs;
1756
+ let fixedHere = 0;
1744
1757
  try {
1745
- runs = readFileSync(file, "utf-8").split("\n").filter(Boolean).map((l) => {
1758
+ withFileLock(`${file}.lock`, () => {
1759
+ let runs;
1746
1760
  try {
1747
- return JSON.parse(l);
1761
+ runs = readFileSync(file, "utf-8").split("\n").filter(Boolean).map((l) => {
1762
+ try {
1763
+ return JSON.parse(l);
1764
+ } catch {
1765
+ return null;
1766
+ }
1767
+ }).filter((r) => !!r);
1748
1768
  } catch {
1749
- return null;
1769
+ return;
1750
1770
  }
1751
- }).filter((r) => !!r);
1752
- } catch {
1753
- continue;
1754
- }
1755
- let changed = false;
1756
- for (const r of runs) {
1757
- if (r.status !== "running") continue;
1758
- if (isWorkflowInFlight(projectRoot, r.workflow)) continue;
1759
- if (typeof r.startedAt === "number" && Date.now() - r.startedAt < RECONCILE_GRACE_MS) continue;
1760
- r.status = "failed";
1761
- r.error = r.error || "interrupted by daemon restart";
1762
- r.finishedAt = r.finishedAt || r.startedAt;
1763
- changed = true;
1764
- fixed++;
1765
- }
1766
- if (!changed) continue;
1767
- try {
1768
- withFileLock(`${file}.lock`, () => {
1771
+ let changed = false;
1772
+ for (const r of runs) {
1773
+ if (r.status !== "running") continue;
1774
+ if (isWorkflowInFlight(projectRoot, r.workflow)) continue;
1775
+ const raw = r.startedAt;
1776
+ const startedMs = typeof raw === "number" ? raw : Date.parse(String(raw ?? ""));
1777
+ if (Number.isFinite(startedMs) && Date.now() - startedMs < RECONCILE_GRACE_MS) continue;
1778
+ r.status = "failed";
1779
+ r.error = r.error || "interrupted by daemon restart";
1780
+ r.finishedAt = r.finishedAt || r.startedAt;
1781
+ changed = true;
1782
+ fixedHere++;
1783
+ }
1784
+ if (!changed) return;
1785
+ const kept = runs.slice(-maxRunsPerWorkflow());
1769
1786
  const tmp = `${file}.tmp-${process.pid}-${randomBytes(4).toString("hex")}`;
1770
- writeFileSync(tmp, runs.map((r) => JSON.stringify(r)).join("\n") + "\n");
1787
+ writeFileSync(tmp, kept.map((r) => JSON.stringify(r)).join("\n") + "\n");
1771
1788
  renameSync(tmp, file);
1772
1789
  });
1773
- } catch {
1790
+ } catch (err) {
1791
+ reportRunStoreWriteFailure("reconcileInterruptedRuns", err);
1774
1792
  }
1793
+ fixed += fixedHere;
1775
1794
  }
1776
- } catch {
1795
+ } catch (err) {
1796
+ reportRunStoreWriteFailure("reconcileInterruptedRuns/outer", err);
1777
1797
  }
1778
1798
  return fixed;
1779
1799
  }
@@ -1960,6 +1980,7 @@ var runStore = /*#__PURE__*/Object.freeze({
1960
1980
  MAX_RUNS_PER_WORKFLOW: MAX_RUNS_PER_WORKFLOW,
1961
1981
  MAX_STREAM_CHARS: MAX_STREAM_CHARS,
1962
1982
  STEP_TIMEOUT_MS: STEP_TIMEOUT_MS,
1983
+ __resetRunStoreWriteFailureReporting: __resetRunStoreWriteFailureReporting,
1963
1984
  capStream: capStream,
1964
1985
  escalateWorkflowFailure: escalateWorkflowFailure,
1965
1986
  getRun: getRun,
@@ -1969,6 +1990,7 @@ var runStore = /*#__PURE__*/Object.freeze({
1969
1990
  maxRunsPerWorkflow: maxRunsPerWorkflow,
1970
1991
  reconcileInterruptedRuns: reconcileInterruptedRuns,
1971
1992
  recordRun: recordRun,
1993
+ reportRunStoreWriteFailure: reportRunStoreWriteFailure,
1972
1994
  runWorkflow: runWorkflow,
1973
1995
  runsDir: runsDir,
1974
1996
  stepTimeoutMs: stepTimeoutMs
@@ -2353,7 +2375,16 @@ function acquireSupervisorLock(pidFile, pid = process.pid) {
2353
2375
  }
2354
2376
  return { acquired: false, staleCleaned: true };
2355
2377
  }
2356
- if (isPidAlive(existingPid)) {
2378
+ const alive = isPidAlive(existingPid);
2379
+ const verdict = classifyLockHolder({
2380
+ pid: existingPid,
2381
+ alive,
2382
+ // Only interrogate a live pid — a dead one is already stale, and `ps` costs a fork.
2383
+ holderStartedMs: alive ? readProcessStartMs(existingPid) : null,
2384
+ lockWrittenMs: getFileWrittenMs(pidFile),
2385
+ bootTimeMs: getBootTimeMs()
2386
+ });
2387
+ if (verdict === "held") {
2357
2388
  return { acquired: false, heldBy: existingPid };
2358
2389
  }
2359
2390
  try {
@@ -2362,6 +2393,62 @@ function acquireSupervisorLock(pidFile, pid = process.pid) {
2362
2393
  }
2363
2394
  return { acquired: false, staleCleaned: true };
2364
2395
  }
2396
+ const RECYCLED_PID_TOLERANCE_MS = 5e3;
2397
+ function classifyLockHolder(opts) {
2398
+ const { pid, alive, holderStartedMs = null, lockWrittenMs = null, bootTimeMs = null } = opts;
2399
+ if (!pid || Number.isNaN(pid) || pid <= 0) return "stale";
2400
+ if (!alive) return "stale";
2401
+ if (bootTimeMs !== null && lockWrittenMs !== null && lockWrittenMs < bootTimeMs) return "stale";
2402
+ if (holderStartedMs !== null && lockWrittenMs !== null && holderStartedMs > lockWrittenMs + RECYCLED_PID_TOLERANCE_MS) {
2403
+ return "stale";
2404
+ }
2405
+ return "held";
2406
+ }
2407
+ function readProcessStartMs(pid) {
2408
+ if (!pid || Number.isNaN(pid) || pid <= 0) return null;
2409
+ if (process.platform === "win32") return null;
2410
+ try {
2411
+ const out = execFileSync("ps", ["-ww", "-o", "lstart=", "-p", String(pid)], {
2412
+ encoding: "utf-8",
2413
+ timeout: 5e3,
2414
+ stdio: ["ignore", "pipe", "ignore"]
2415
+ }).trim();
2416
+ if (!out) return null;
2417
+ const ms = Date.parse(out);
2418
+ return Number.isFinite(ms) ? ms : null;
2419
+ } catch {
2420
+ return null;
2421
+ }
2422
+ }
2423
+ function getFileWrittenMs(file) {
2424
+ try {
2425
+ return statSync(file).mtimeMs;
2426
+ } catch {
2427
+ return null;
2428
+ }
2429
+ }
2430
+ function getBootTimeMs() {
2431
+ if (process.platform === "win32") return null;
2432
+ try {
2433
+ if (process.platform === "linux") {
2434
+ const uptimeSec = parseFloat(readFileSync("/proc/uptime", "utf-8").trim().split(/\s+/)[0]);
2435
+ if (!Number.isFinite(uptimeSec) || uptimeSec < 0) return null;
2436
+ return Date.now() - uptimeSec * 1e3;
2437
+ }
2438
+ const out = execFileSync("sysctl", ["-n", "kern.boottime"], {
2439
+ encoding: "utf-8",
2440
+ timeout: 5e3,
2441
+ stdio: ["ignore", "pipe", "ignore"]
2442
+ });
2443
+ const m = out.match(/sec\s*=\s*(\d+)/);
2444
+ if (!m) return null;
2445
+ const sec = parseInt(m[1], 10);
2446
+ if (!Number.isFinite(sec) || sec <= 0) return null;
2447
+ return sec * 1e3;
2448
+ } catch {
2449
+ return null;
2450
+ }
2451
+ }
2365
2452
  function acquireSupervisorLockWithRetry(pidFile, pid = process.pid) {
2366
2453
  let result = acquireSupervisorLock(pidFile, pid);
2367
2454
  if (!result.acquired && result.staleCleaned) {
@@ -2390,7 +2477,7 @@ function isSupervisorPid(pid) {
2390
2477
  if (!pid || Number.isNaN(pid) || pid <= 0) return false;
2391
2478
  if (process.platform === "win32") return null;
2392
2479
  try {
2393
- const out = execFileSync("ps", ["-o", "command=", "-p", String(pid)], {
2480
+ const out = execFileSync("ps", ["-ww", "-o", "command=", "-p", String(pid)], {
2394
2481
  encoding: "utf-8",
2395
2482
  timeout: 5e3,
2396
2483
  stdio: ["ignore", "pipe", "ignore"]
@@ -2510,11 +2597,15 @@ var supervisorLock = /*#__PURE__*/Object.freeze({
2510
2597
  __proto__: null,
2511
2598
  acquireSupervisorLock: acquireSupervisorLock,
2512
2599
  acquireSupervisorLockWithRetry: acquireSupervisorLockWithRetry,
2600
+ classifyLockHolder: classifyLockHolder,
2513
2601
  findOrphanedSyncPids: findOrphanedSyncPids,
2602
+ getBootTimeMs: getBootTimeMs,
2603
+ getFileWrittenMs: getFileWrittenMs,
2514
2604
  getPpid: getPpid,
2515
2605
  isPidAlive: isPidAlive,
2516
2606
  isSupervisorPid: isSupervisorPid,
2517
2607
  killOrphanedSyncs: killOrphanedSyncs,
2608
+ readProcessStartMs: readProcessStartMs,
2518
2609
  releaseSupervisorLock: releaseSupervisorLock,
2519
2610
  shouldSignalSupervisor: shouldSignalSupervisor,
2520
2611
  watchParentLiveness: watchParentLiveness
@@ -4237,7 +4328,11 @@ async function startDaemon(options) {
4237
4328
  function saveExposedTunnels(specs) {
4238
4329
  try {
4239
4330
  mkdirSync$1(SVAMP_HOME, { recursive: true });
4240
- writeFileSync$1(EXPOSED_TUNNELS_FILE, JSON.stringify({ tunnels: specs }, null, 2));
4331
+ writeFileSync$1(EXPOSED_TUNNELS_FILE, JSON.stringify({ tunnels: specs }, null, 2), { mode: 384 });
4332
+ try {
4333
+ chmodSync(EXPOSED_TUNNELS_FILE, 384);
4334
+ } catch {
4335
+ }
4241
4336
  } catch (err) {
4242
4337
  logger.log(`[exposed-tunnels] Persist failed: ${err.message}`);
4243
4338
  }
@@ -4256,7 +4351,7 @@ async function startDaemon(options) {
4256
4351
  try {
4257
4352
  const dir = loadSessionIndex()[sessionId]?.directory;
4258
4353
  if (!dir) return;
4259
- const { reconcileServiceLinks } = await import('./agentCommands-B2Nl7Fof.mjs');
4354
+ const { reconcileServiceLinks } = await import('./agentCommands-D91RcjqQ.mjs');
4260
4355
  const configPath = getSvampConfigPath(dir, sessionId);
4261
4356
  const config = readSvampConfig(configPath);
4262
4357
  const entries = Array.from(urls.entries());
@@ -4278,7 +4373,7 @@ async function startDaemon(options) {
4278
4373
  try {
4279
4374
  const dir = loadSessionIndex()[sessionId]?.directory;
4280
4375
  if (!dir) return;
4281
- const { reconcileServiceLinks } = await import('./agentCommands-B2Nl7Fof.mjs');
4376
+ const { reconcileServiceLinks } = await import('./agentCommands-D91RcjqQ.mjs');
4282
4377
  const configPath = getSvampConfigPath(dir, sessionId);
4283
4378
  const config = readSvampConfig(configPath);
4284
4379
  const incoming = [{
@@ -4299,7 +4394,7 @@ async function startDaemon(options) {
4299
4394
  try {
4300
4395
  const dir = loadSessionIndex()[sessionId]?.directory;
4301
4396
  if (!dir) return;
4302
- const { dropServiceLinks } = await import('./agentCommands-B2Nl7Fof.mjs');
4397
+ const { dropServiceLinks } = await import('./agentCommands-D91RcjqQ.mjs');
4303
4398
  const configPath = getSvampConfigPath(dir, sessionId);
4304
4399
  const config = readSvampConfig(configPath);
4305
4400
  if (dropServiceLinks(config, "serve", mountName)) {
@@ -4315,7 +4410,7 @@ async function startDaemon(options) {
4315
4410
  try {
4316
4411
  const dir = loadSessionIndex()[sessionId]?.directory;
4317
4412
  if (!dir) return;
4318
- const { dropServiceLinks } = await import('./agentCommands-B2Nl7Fof.mjs');
4413
+ const { dropServiceLinks } = await import('./agentCommands-D91RcjqQ.mjs');
4319
4414
  const configPath = getSvampConfigPath(dir, sessionId);
4320
4415
  const config = readSvampConfig(configPath);
4321
4416
  if (dropServiceLinks(config, "tunnel", tunnelName)) {
@@ -4332,7 +4427,7 @@ async function startDaemon(options) {
4332
4427
  let managedLinkSessionsSeeded = false;
4333
4428
  async function reconcileAllServiceLinks() {
4334
4429
  try {
4335
- const { reconcileServiceLinksExact, hasManagedServiceLink } = await import('./agentCommands-B2Nl7Fof.mjs');
4430
+ const { reconcileServiceLinksExact, hasManagedServiceLink } = await import('./agentCommands-D91RcjqQ.mjs');
4336
4431
  const desiredBySession = /* @__PURE__ */ new Map();
4337
4432
  const push = (sessionId, entry) => {
4338
4433
  if (!sessionId || !entry.url) return;
@@ -4406,7 +4501,7 @@ async function startDaemon(options) {
4406
4501
  }, delayMs);
4407
4502
  }
4408
4503
  async function createExposedTunnel(spec) {
4409
- const { FrpcTunnel } = await import('./hookSettings-DYMTUgVA.mjs').then(function (n) { return n.w; });
4504
+ const { FrpcTunnel } = await import('./hookSettings-FFc1pi8j.mjs').then(function (n) { return n.w; });
4410
4505
  const tunnel = new FrpcTunnel({
4411
4506
  name: spec.name,
4412
4507
  ports: spec.ports,
@@ -4427,7 +4522,7 @@ async function startDaemon(options) {
4427
4522
  }
4428
4523
  const tunnelRecreateState = /* @__PURE__ */ new Map();
4429
4524
  const tunnelRecreateInFlight = /* @__PURE__ */ new Set();
4430
- const { ServeManager } = await import('./hookSettings-DYMTUgVA.mjs').then(function (n) { return n.y; });
4525
+ const { ServeManager } = await import('./hookSettings-FFc1pi8j.mjs').then(function (n) { return n.y; });
4431
4526
  const serveManager = new ServeManager(SVAMP_HOME, (msg) => logger.log(`[SERVE] ${msg}`), hyphaServerUrl);
4432
4527
  serveManager.setMountUnboundHook((sessionId, mountName) => {
4433
4528
  void dropMountSessionLink(sessionId, mountName);
@@ -5354,21 +5449,34 @@ ${parts.join("\n")}`);
5354
5449
  } catch (e) {
5355
5450
  logger.log(`[Session ${sessionId}] verifyGoalCompletion threw \u2014 failing closed (retry/park): ${e?.message || e}`);
5356
5451
  try {
5452
+ const curLsErr = readLoopState(directory, sessionId);
5453
+ if (loopCancelledDuringVerify(curLsErr)) {
5454
+ logger.log(`[Session ${sessionId}] loop was cancelled during a FAILED verification \u2014 not re-kicking (#0308/#1542)`);
5455
+ return;
5456
+ }
5457
+ const freshErr = curLsErr || ls;
5458
+ const carry = {
5459
+ ledger: freshErr.ledger ?? ls.ledger,
5460
+ progress_history: freshErr.progress_history ?? ls.progress_history,
5461
+ extensions: freshErr.extensions ?? ls.extensions,
5462
+ auto_resumes: freshErr.auto_resumes ?? ls.auto_resumes,
5463
+ holds: freshErr.holds ?? ls.holds
5464
+ };
5357
5465
  const durable2 = resolveLoopDurable({ durable: ls.durable, oracle: oracleCmd });
5358
5466
  const decision = decideVerifyErrorHandling({
5359
- priorErrors: ls.verify_errors,
5467
+ priorErrors: freshErr.verify_errors ?? ls.verify_errors,
5360
5468
  maxRetries: resolveVerifyErrorRetries(process.env.SVAMP_LOOP_VERIFY_ERROR_RETRIES),
5361
5469
  reason: `verify threw: ${e?.message || e}`
5362
5470
  });
5363
5471
  if (decision.action === "retry") {
5364
5472
  const cond = ls.task || "";
5365
- writeGoalLoopState(directory, sessionId, { ...ls, active: true, phase: "continue", started_at: startedAt, verify_errors: decision.attempt });
5473
+ writeGoalLoopState(directory, sessionId, { ...ls, ...carry, active: true, phase: "continue", started_at: startedAt, verify_errors: decision.attempt });
5366
5474
  sessionService.pushMessage({ type: "message", message: `\u26A0\uFE0F Loop verification error \u2014 ${decision.reason}`, level: "warning" }, "event");
5367
5475
  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
5476
  if (!trackedSession.stopped) setTimeout(() => processMessageQueueRef?.(), 200);
5369
5477
  } else {
5370
5478
  const parkPhase = terminalPhaseForDone(durable2);
5371
- writeGoalLoopState(directory, sessionId, { ...ls, active: parkPhase === "dormant", phase: parkPhase, completed_at: Date.now(), verify_errors: 0 });
5479
+ writeGoalLoopState(directory, sessionId, { ...ls, ...carry, active: parkPhase === "dormant", phase: parkPhase, completed_at: Date.now(), verify_errors: 0 });
5372
5480
  checkSvampConfig?.();
5373
5481
  }
5374
5482
  } catch {
@@ -5851,7 +5959,7 @@ ${parts.join("\n")}`);
5851
5959
  const hasBackgroundTasks = backgroundTaskCount > 0;
5852
5960
  if (hasBackgroundTasks) {
5853
5961
  const taskInfo = `Background tasks still running (${backgroundTaskCount}): ${backgroundTaskNames.join(", ")}`;
5854
- sessionService.pushMessage({ type: "session_event", message: taskInfo }, "session");
5962
+ sessionService.pushMessage({ type: "message", message: taskInfo, level: "warning" }, "event");
5855
5963
  }
5856
5964
  signalProcessing(false);
5857
5965
  sessionWasProcessing = false;
@@ -5974,7 +6082,7 @@ ${parts.join("\n")}`);
5974
6082
  if (backgroundTaskCount > 0) {
5975
6083
  const taskInfo = `Background tasks still running (${backgroundTaskCount}): ${backgroundTaskNames.join(", ")}`;
5976
6084
  logger.log(`[Session ${sessionId}] ${taskInfo}`);
5977
- sessionService.pushMessage({ type: "session_event", message: taskInfo }, "session");
6085
+ sessionService.pushMessage({ type: "message", message: taskInfo, level: "warning" }, "event");
5978
6086
  }
5979
6087
  justCompactedTurn = false;
5980
6088
  compactTurnLatch = false;
@@ -6889,12 +6997,12 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
6889
6997
  });
6890
6998
  },
6891
6999
  onIssue: async (params) => {
6892
- const { issueRpc } = await import('./rpc-Cf0grcru.mjs');
7000
+ const { issueRpc } = await import('./rpc-ccY7xvlo.mjs');
6893
7001
  const issueCwd = resolveContainedCwd(directory, params?.cwd, !!sessionMetadata.securityContext);
6894
7002
  return issueRpc(issueCwd, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
6895
7003
  },
6896
7004
  onWorkflow: async (params) => {
6897
- const { workflowRpc } = await import('./rpc-BB6RF4-F.mjs');
7005
+ const { workflowRpc } = await import('./rpc-CBkSkzsI.mjs');
6898
7006
  const wfCwd = resolveContainedCwd(directory, params?.cwd, !!sessionMetadata.securityContext);
6899
7007
  return workflowRpc(wfCwd, params || {});
6900
7008
  },
@@ -7646,12 +7754,12 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
7646
7754
  });
7647
7755
  },
7648
7756
  onIssue: async (params) => {
7649
- const { issueRpc } = await import('./rpc-Cf0grcru.mjs');
7757
+ const { issueRpc } = await import('./rpc-ccY7xvlo.mjs');
7650
7758
  const issueCwd = resolveContainedCwd(directory, params?.cwd, !!sessionMetadata.securityContext);
7651
7759
  return issueRpc(issueCwd, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
7652
7760
  },
7653
7761
  onWorkflow: async (params) => {
7654
- const { workflowRpc } = await import('./rpc-BB6RF4-F.mjs');
7762
+ const { workflowRpc } = await import('./rpc-CBkSkzsI.mjs');
7655
7763
  const wfCwd = resolveContainedCwd(directory, params?.cwd, !!sessionMetadata.securityContext);
7656
7764
  return workflowRpc(wfCwd, params || {});
7657
7765
  },
@@ -8391,6 +8499,24 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
8391
8499
  }
8392
8500
  return { success: false, message: `Session ${sessionId} not found or already stopped.` };
8393
8501
  };
8502
+ {
8503
+ let lastEntitlementState;
8504
+ const runEntitlementProbe = (first) => {
8505
+ const env = {};
8506
+ applyClaudeProxyEnv(env);
8507
+ void probeLongContext1MEntitlement(env.ANTHROPIC_BASE_URL, env.ANTHROPIC_API_KEY).then((state) => {
8508
+ if (!first && state === lastEntitlementState) return;
8509
+ lastEntitlementState = state;
8510
+ if (state === "entitled") logger.log("[1m-context] entitlement confirmed \u2014 sessions will request the 1M window");
8511
+ 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.");
8512
+ else logger.log("[1m-context] entitlement could not be determined \u2014 NOT requesting the 1M beta (safe default). See #1585.");
8513
+ }).catch(() => {
8514
+ });
8515
+ };
8516
+ runEntitlementProbe(true);
8517
+ const entitlementTimer = setInterval(() => runEntitlementProbe(false), LONG_CONTEXT_ENTITLEMENT_RECHECK_MS);
8518
+ if (typeof entitlementTimer.unref === "function") entitlementTimer.unref();
8519
+ }
8394
8520
  let isolationCapabilities;
8395
8521
  try {
8396
8522
  isolationCapabilities = await detectIsolationCapabilities();
@@ -9007,13 +9133,18 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
9007
9133
  const PING_TIMEOUT_MS = 15e3;
9008
9134
  const POST_RECONNECT_GRACE_MS = 2e4;
9009
9135
  const RECONNECT_JITTER_MS = 2500;
9010
- const { WorkflowScheduler } = await import('./scheduler-BY30ZrB9.mjs');
9136
+ const { WorkflowScheduler } = await import('./scheduler-BkVJ27Ki.mjs');
9011
9137
  const workflowProjectRoots = () => {
9012
- const dirs = /* @__PURE__ */ new Set();
9138
+ const roots = /* @__PURE__ */ new Set();
9013
9139
  for (const s of pidToTrackedSession.values()) {
9014
- if (!s.stopped && s.directory) dirs.add(s.directory);
9140
+ if (s.stopped || !s.directory) continue;
9141
+ try {
9142
+ roots.add(resolveProjectRoot$1(s.directory));
9143
+ } catch {
9144
+ roots.add(s.directory);
9145
+ }
9015
9146
  }
9016
- return [...dirs];
9147
+ return [...roots];
9017
9148
  };
9018
9149
  try {
9019
9150
  const { reconcileInterruptedRuns } = await Promise.resolve().then(function () { return runStore; });
@@ -1,7 +1,7 @@
1
1
  import { i as inZone, c as cronMatches } from './cron-hHGdb5kU.mjs';
2
- import { r as resolveProjectRoot } from './store-Bn0ByYev.mjs';
2
+ import { r as resolveProjectRoot } from './store-B4E6NzG6.mjs';
3
3
  import { l as listWorkflows, i as isWorkflowEnabled, w as workflowSchedules } from './store-fi0f-ff1.mjs';
4
- import { r as runWorkflow } from './run-DkjwF-zA.mjs';
4
+ import { r as runWorkflow } from './run-DDmeV9K3.mjs';
5
5
  import 'node:fs';
6
6
  import 'node:path';
7
7
  import 'node:crypto';
@@ -15,7 +15,7 @@ import 'path';
15
15
  import 'url';
16
16
  import 'child_process';
17
17
  import 'crypto';
18
- import './hookSettings-DYMTUgVA.mjs';
18
+ import './hookSettings-FFc1pi8j.mjs';
19
19
  import './types-57J3Re0n.mjs';
20
20
  import './securityContext-Cm5UTCuD.mjs';
21
21
  import './machineTools-DygM1jXW.mjs';
@@ -24,16 +24,16 @@ import 'util';
24
24
  import 'http';
25
25
  import 'net';
26
26
  import './instance-CeHz5C8v.mjs';
27
- import './serveAuth-DbVLRCRR.mjs';
27
+ import './serveAuth-4M0vwMyj.mjs';
28
28
  import 'node:os';
29
29
  import './envFlag-COOuJ3AH.mjs';
30
- import './claudeAuth-iAerdaMr.mjs';
30
+ import './claudeAuth-C0wc1GTM.mjs';
31
31
  import './codexProvider-BtxYc5Rj.mjs';
32
32
  import './friendlyName-1UZcyDhu.mjs';
33
33
  import 'node:events';
34
34
  import './hyphaClient-ybivOjZo.mjs';
35
35
  import './sharingNotificationSync-qGIQ-3yf.mjs';
36
- import './acpBackend-BZ1MJhQV.mjs';
36
+ import './acpBackend-UaBD4zL3.mjs';
37
37
  import '@agentclientprotocol/sdk';
38
38
  import './DefaultTransport-vfp78fug.mjs';
39
39
  import './wrapCommand-CdNawSaa.mjs';
@@ -46,11 +46,11 @@ import './GeminiTransport-3OkhtFRO.mjs';
46
46
  import './KimiTransport-D8n009Tr.mjs';
47
47
  import './kimiProvider-DbxODebR.mjs';
48
48
  import './kimiSetup-NGsoYB5h.mjs';
49
- import './detectIsolation-CzoDCEnh.mjs';
49
+ import './detectIsolation-CrV8IFDv.mjs';
50
50
  import 'node:fs/promises';
51
51
  import './pinnedNono-5ZHb6328.mjs';
52
52
  import './bootStatus-DqtNgJch.mjs';
53
- import './loopVerify-B47sSjxe.mjs';
53
+ import './loopVerify-DALtTk2V.mjs';
54
54
  import './api-BHjyC0Ph.mjs';
55
55
 
56
56
  function cronMatchesSafe(expr, date) {