@integrity-labs/agt-cli 0.28.404 → 0.28.405

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.
@@ -12462,4 +12462,4 @@ export {
12462
12462
  stopAllSessionsAndWait,
12463
12463
  getProjectDir
12464
12464
  };
12465
- //# sourceMappingURL=chunk-V5CRVBVC.js.map
12465
+ //# sourceMappingURL=chunk-UYBG62IQ.js.map
@@ -100,7 +100,7 @@ async function spawnPairSession(session) {
100
100
  return { ok: true };
101
101
  } catch {
102
102
  }
103
- const { resolveClaudeBinary } = await import("./persistent-session-GRCJPRH5.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-VMKIIW5Y.js");
104
104
  const claudeBin = resolveClaudeBinary();
105
105
  const pairEnv = {
106
106
  ...process.env,
@@ -373,4 +373,4 @@ export {
373
373
  startClaudePair,
374
374
  submitClaudePairCode
375
375
  };
376
- //# sourceMappingURL=claude-pair-runtime-HDSV7CKE.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-AG4PW6FE.js.map
@@ -45,7 +45,7 @@ import {
45
45
  resolveEffectivePinRaw,
46
46
  safeWriteJsonAtomic,
47
47
  setConfigHash
48
- } from "../chunk-SW3FOBHR.js";
48
+ } from "../chunk-AAWYAPKX.js";
49
49
  import {
50
50
  getProjectDir as getProjectDir2,
51
51
  getReadyTasks,
@@ -147,7 +147,7 @@ import {
147
147
  toOpencodeModel,
148
148
  transcriptActivityAgeSeconds,
149
149
  writeEgressAllowlist
150
- } from "../chunk-V5CRVBVC.js";
150
+ } from "../chunk-UYBG62IQ.js";
151
151
  import {
152
152
  reapOrphanChannelMcps
153
153
  } from "../chunk-XWVM4KPK.js";
@@ -9255,7 +9255,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
9255
9255
  var lastVersionCheckAt = 0;
9256
9256
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
9257
9257
  var lastResponsivenessProbeAt = 0;
9258
- var agtCliVersion = true ? "0.28.404" : "dev";
9258
+ var agtCliVersion = true ? "0.28.405" : "dev";
9259
9259
  function resolveBrewPath(execFileSync2) {
9260
9260
  try {
9261
9261
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -10387,7 +10387,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
10387
10387
  if (codeNames.length === 0) return;
10388
10388
  void (async () => {
10389
10389
  try {
10390
- const { collectDiagnostics } = await import("../persistent-session-GRCJPRH5.js");
10390
+ const { collectDiagnostics } = await import("../persistent-session-VMKIIW5Y.js");
10391
10391
  await api.post("/host/heartbeat", {
10392
10392
  host_id: hostId,
10393
10393
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor)
@@ -10486,7 +10486,7 @@ async function pollCycle() {
10486
10486
  }
10487
10487
  try {
10488
10488
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
10489
- const { collectDiagnostics } = await import("../persistent-session-GRCJPRH5.js");
10489
+ const { collectDiagnostics } = await import("../persistent-session-VMKIIW5Y.js");
10490
10490
  const diagCodeNames = [...agentState.persistentSessionAgents];
10491
10491
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor) : void 0;
10492
10492
  let tailscaleHostname;
@@ -10641,7 +10641,7 @@ async function pollCycle() {
10641
10641
  const {
10642
10642
  collectResponsivenessProbes,
10643
10643
  getResponsivenessIntervalMs
10644
- } = await import("../responsiveness-probe-DNM5APN5.js");
10644
+ } = await import("../responsiveness-probe-ZNMY5RVO.js");
10645
10645
  const probeIntervalMs = getResponsivenessIntervalMs();
10646
10646
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
10647
10647
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -10673,7 +10673,7 @@ async function pollCycle() {
10673
10673
  collectResponsivenessProbes,
10674
10674
  livePendingInboundOldestAgeSeconds,
10675
10675
  parkPendingInbound
10676
- } = await import("../responsiveness-probe-DNM5APN5.js");
10676
+ } = await import("../responsiveness-probe-ZNMY5RVO.js");
10677
10677
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-HYOOQV4A.js");
10678
10678
  const wedgeNow = /* @__PURE__ */ new Date();
10679
10679
  const liveAgents = agentState.persistentSessionAgents;
@@ -13955,7 +13955,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
13955
13955
  void api.post("/host/restart-ack", { host_id: hostId, agent_id: agentId, restart_requested_at: requestedAt }).catch((err) => log(`[restart-lane] ack failed for '${codeName}': ${err.message}`));
13956
13956
  void (async () => {
13957
13957
  try {
13958
- const { collectDiagnostics } = await import("../persistent-session-GRCJPRH5.js");
13958
+ const { collectDiagnostics } = await import("../persistent-session-VMKIIW5Y.js");
13959
13959
  await api.post("/host/heartbeat", {
13960
13960
  host_id: hostId,
13961
13961
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor)
@@ -14005,7 +14005,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
14005
14005
  }
14006
14006
  try {
14007
14007
  const hostId = await getHostId();
14008
- const { collectDiagnostics } = await import("../persistent-session-GRCJPRH5.js");
14008
+ const { collectDiagnostics } = await import("../persistent-session-VMKIIW5Y.js");
14009
14009
  await api.post("/host/heartbeat", {
14010
14010
  host_id: hostId,
14011
14011
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor)
@@ -14458,7 +14458,7 @@ async function processClaudePairSessions(agents) {
14458
14458
  killPairSession,
14459
14459
  pairTmuxSession,
14460
14460
  finalizeClaudePairOnboarding
14461
- } = await import("../claude-pair-runtime-HDSV7CKE.js");
14461
+ } = await import("../claude-pair-runtime-AG4PW6FE.js");
14462
14462
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
14463
14463
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
14464
14464
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -30279,10 +30279,14 @@ import {
30279
30279
  mkdirSync as mkdirSync4,
30280
30280
  readFileSync as readFileSync7,
30281
30281
  renameSync as renameSync4,
30282
+ statSync,
30282
30283
  unlinkSync as unlinkSync2,
30284
+ utimesSync,
30283
30285
  writeFileSync as writeFileSync5
30284
30286
  } from "fs";
30285
30287
  import { join as join7 } from "path";
30288
+ var STALE_LOCK_MS = 9e4;
30289
+ var HEARTBEAT_INTERVAL_MS = 3e4;
30286
30290
  function defaultIsPidAlive(pid) {
30287
30291
  if (!Number.isFinite(pid) || pid <= 0) return false;
30288
30292
  try {
@@ -30300,6 +30304,9 @@ function acquireMcpSpawnLock(args) {
30300
30304
  const isPidAlive = options.isPidAlive ?? defaultIsPidAlive;
30301
30305
  const selfPid = options.selfPid ?? process.pid;
30302
30306
  const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
30307
+ const nowMs = options.nowMs ?? (() => Date.now());
30308
+ const lockMtimeMs = options.lockMtimeMs ?? defaultLockMtimeMs;
30309
+ const staleMs = options.staleMs ?? STALE_LOCK_MS;
30303
30310
  const path = join7(agentDir, basename);
30304
30311
  const existing = readLockHolder(path);
30305
30312
  if (existing) {
@@ -30307,7 +30314,11 @@ function acquireMcpSpawnLock(args) {
30307
30314
  return { kind: "acquired", path };
30308
30315
  }
30309
30316
  if (isPidAlive(existing.pid)) {
30310
- return { kind: "blocked", path, holder: existing };
30317
+ const mtime = lockMtimeMs(path);
30318
+ const fresh = mtime !== null && nowMs() - mtime <= staleMs;
30319
+ if (fresh) {
30320
+ return { kind: "blocked", path, holder: existing };
30321
+ }
30311
30322
  }
30312
30323
  }
30313
30324
  mkdirSync4(agentDir, { recursive: true, mode: 448 });
@@ -30328,6 +30339,38 @@ function releaseMcpSpawnLock(lockPath, opts = {}) {
30328
30339
  } catch {
30329
30340
  }
30330
30341
  }
30342
+ function refreshMcpSpawnLock(lockPath, opts = {}) {
30343
+ if (!lockPath) return false;
30344
+ const selfPid = opts.selfPid ?? process.pid;
30345
+ const existing = readLockHolder(lockPath);
30346
+ if (!existing || existing.pid !== selfPid) return false;
30347
+ try {
30348
+ const t = (opts.nowMs ?? (() => Date.now()))() / 1e3;
30349
+ utimesSync(lockPath, t, t);
30350
+ return true;
30351
+ } catch {
30352
+ return false;
30353
+ }
30354
+ }
30355
+ function startMcpSpawnLockHeartbeat(lockPath, opts = {}) {
30356
+ if (!lockPath) return () => {
30357
+ };
30358
+ const intervalMs = opts.intervalMs ?? HEARTBEAT_INTERVAL_MS;
30359
+ const handle = setInterval(() => {
30360
+ if (!refreshMcpSpawnLock(lockPath, { selfPid: opts.selfPid })) {
30361
+ clearInterval(handle);
30362
+ }
30363
+ }, intervalMs);
30364
+ handle.unref?.();
30365
+ return () => clearInterval(handle);
30366
+ }
30367
+ function defaultLockMtimeMs(path) {
30368
+ try {
30369
+ return statSync(path).mtimeMs;
30370
+ } catch {
30371
+ return null;
30372
+ }
30373
+ }
30331
30374
  function readLockHolder(path) {
30332
30375
  if (!existsSync5(path)) return null;
30333
30376
  try {
@@ -30355,7 +30398,7 @@ import {
30355
30398
  existsSync as existsSync6,
30356
30399
  renameSync as renameSync5,
30357
30400
  unlinkSync as unlinkSync3,
30358
- statSync,
30401
+ statSync as statSync2,
30359
30402
  createWriteStream
30360
30403
  } from "fs";
30361
30404
 
@@ -35819,7 +35862,7 @@ function scheduleDirectChatBusyAck(sessionId, messageId, arrivedWhileBusy) {
35819
35862
  let paneLogFreshAgeMs = null;
35820
35863
  if (DIRECT_CHAT_CODE_NAME_AGENT_DIR) {
35821
35864
  try {
35822
- const paneMtimeMs = statSync(join10(DIRECT_CHAT_CODE_NAME_AGENT_DIR, "pane.log")).mtimeMs;
35865
+ const paneMtimeMs = statSync2(join10(DIRECT_CHAT_CODE_NAME_AGENT_DIR, "pane.log")).mtimeMs;
35823
35866
  paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
35824
35867
  } catch {
35825
35868
  }
@@ -36045,6 +36088,7 @@ async function pollForMessages(sinceMs) {
36045
36088
  }
36046
36089
  }
36047
36090
  var acquiredLockPath = null;
36091
+ var stopLockHeartbeat = null;
36048
36092
  {
36049
36093
  const lockResult = acquireMcpSpawnLock({
36050
36094
  agentDir: DIRECT_CHAT_AGENT_DIR,
@@ -36058,6 +36102,7 @@ var acquiredLockPath = null;
36058
36102
  process.exit(0);
36059
36103
  } else if (lockResult.kind === "acquired") {
36060
36104
  acquiredLockPath = lockResult.path;
36105
+ stopLockHeartbeat = startMcpSpawnLockHeartbeat(acquiredLockPath);
36061
36106
  }
36062
36107
  }
36063
36108
  var DOORBELL_ENABLED = resolveHostBooleanFlag({
@@ -36277,6 +36322,10 @@ function shutdown(reason) {
36277
36322
  }
36278
36323
  if (safetyNetTimer) clearInterval(safetyNetTimer);
36279
36324
  if (progressTickTimer) clearInterval(progressTickTimer);
36325
+ try {
36326
+ stopLockHeartbeat?.();
36327
+ } catch {
36328
+ }
36280
36329
  try {
36281
36330
  releaseMcpSpawnLock(acquiredLockPath);
36282
36331
  } catch {
@@ -36683,7 +36683,7 @@ import {
36683
36683
  readFileSync as readFileSync17,
36684
36684
  readdirSync as readdirSync5,
36685
36685
  renameSync as renameSync5,
36686
- statSync as statSync2,
36686
+ statSync as statSync3,
36687
36687
  unlinkSync as unlinkSync7,
36688
36688
  watch,
36689
36689
  writeFileSync as writeFileSync13,
@@ -38494,10 +38494,14 @@ import {
38494
38494
  mkdirSync as mkdirSync8,
38495
38495
  readFileSync as readFileSync16,
38496
38496
  renameSync as renameSync4,
38497
+ statSync as statSync2,
38497
38498
  unlinkSync as unlinkSync6,
38499
+ utimesSync,
38498
38500
  writeFileSync as writeFileSync12
38499
38501
  } from "fs";
38500
38502
  import { join as join16 } from "path";
38503
+ var STALE_LOCK_MS = 9e4;
38504
+ var HEARTBEAT_INTERVAL_MS = 3e4;
38501
38505
  function defaultIsPidAlive(pid) {
38502
38506
  if (!Number.isFinite(pid) || pid <= 0) return false;
38503
38507
  try {
@@ -38515,6 +38519,9 @@ function acquireMcpSpawnLock(args) {
38515
38519
  const isPidAlive = options.isPidAlive ?? defaultIsPidAlive;
38516
38520
  const selfPid = options.selfPid ?? process.pid;
38517
38521
  const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
38522
+ const nowMs = options.nowMs ?? (() => Date.now());
38523
+ const lockMtimeMs = options.lockMtimeMs ?? defaultLockMtimeMs;
38524
+ const staleMs = options.staleMs ?? STALE_LOCK_MS;
38518
38525
  const path = join16(agentDir, basename2);
38519
38526
  const existing = readLockHolder(path);
38520
38527
  if (existing) {
@@ -38522,7 +38529,11 @@ function acquireMcpSpawnLock(args) {
38522
38529
  return { kind: "acquired", path };
38523
38530
  }
38524
38531
  if (isPidAlive(existing.pid)) {
38525
- return { kind: "blocked", path, holder: existing };
38532
+ const mtime = lockMtimeMs(path);
38533
+ const fresh = mtime !== null && nowMs() - mtime <= staleMs;
38534
+ if (fresh) {
38535
+ return { kind: "blocked", path, holder: existing };
38536
+ }
38526
38537
  }
38527
38538
  }
38528
38539
  mkdirSync8(agentDir, { recursive: true, mode: 448 });
@@ -38543,6 +38554,38 @@ function releaseMcpSpawnLock(lockPath, opts = {}) {
38543
38554
  } catch {
38544
38555
  }
38545
38556
  }
38557
+ function refreshMcpSpawnLock(lockPath, opts = {}) {
38558
+ if (!lockPath) return false;
38559
+ const selfPid = opts.selfPid ?? process.pid;
38560
+ const existing = readLockHolder(lockPath);
38561
+ if (!existing || existing.pid !== selfPid) return false;
38562
+ try {
38563
+ const t = (opts.nowMs ?? (() => Date.now()))() / 1e3;
38564
+ utimesSync(lockPath, t, t);
38565
+ return true;
38566
+ } catch {
38567
+ return false;
38568
+ }
38569
+ }
38570
+ function startMcpSpawnLockHeartbeat(lockPath, opts = {}) {
38571
+ if (!lockPath) return () => {
38572
+ };
38573
+ const intervalMs = opts.intervalMs ?? HEARTBEAT_INTERVAL_MS;
38574
+ const handle = setInterval(() => {
38575
+ if (!refreshMcpSpawnLock(lockPath, { selfPid: opts.selfPid })) {
38576
+ clearInterval(handle);
38577
+ }
38578
+ }, intervalMs);
38579
+ handle.unref?.();
38580
+ return () => clearInterval(handle);
38581
+ }
38582
+ function defaultLockMtimeMs(path) {
38583
+ try {
38584
+ return statSync2(path).mtimeMs;
38585
+ } catch {
38586
+ return null;
38587
+ }
38588
+ }
38546
38589
  function readLockHolder(path) {
38547
38590
  if (!existsSync9(path)) return null;
38548
38591
  try {
@@ -38858,7 +38901,7 @@ var liveAllowedUsersCache = null;
38858
38901
  function readLiveAllowedUsers() {
38859
38902
  if (!SLACK_MCP_CONFIG_PATH) return null;
38860
38903
  try {
38861
- const mtimeMs = statSync2(SLACK_MCP_CONFIG_PATH).mtimeMs;
38904
+ const mtimeMs = statSync3(SLACK_MCP_CONFIG_PATH).mtimeMs;
38862
38905
  if (liveAllowedUsersCache && liveAllowedUsersCache.mtimeMs === mtimeMs) {
38863
38906
  return liveAllowedUsersCache.value;
38864
38907
  }
@@ -38879,7 +38922,7 @@ var livePingAllowedUsersCache = null;
38879
38922
  function readLivePingAllowedUsers() {
38880
38923
  if (!SLACK_MCP_CONFIG_PATH) return null;
38881
38924
  try {
38882
- const mtimeMs = statSync2(SLACK_MCP_CONFIG_PATH).mtimeMs;
38925
+ const mtimeMs = statSync3(SLACK_MCP_CONFIG_PATH).mtimeMs;
38883
38926
  if (livePingAllowedUsersCache && livePingAllowedUsersCache.mtimeMs === mtimeMs) {
38884
38927
  return livePingAllowedUsersCache.value;
38885
38928
  }
@@ -39109,7 +39152,7 @@ function scheduleBusyAck(channel, threadTs, messageTs, isThreadReply, arrivedWhi
39109
39152
  let paneLogFreshAgeMs = null;
39110
39153
  if (SLACK_AGENT_DIR) {
39111
39154
  try {
39112
- const paneMtimeMs = statSync2(join17(SLACK_AGENT_DIR, "pane.log")).mtimeMs;
39155
+ const paneMtimeMs = statSync3(join17(SLACK_AGENT_DIR, "pane.log")).mtimeMs;
39113
39156
  paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
39114
39157
  } catch {
39115
39158
  }
@@ -39376,7 +39419,7 @@ function scanSlackRecoveryRetries() {
39376
39419
  if (!f.includes(".retry-") || f.endsWith(".poison.json")) continue;
39377
39420
  let mtimeMs;
39378
39421
  try {
39379
- mtimeMs = statSync2(join17(SLACK_RECOVERY_OUTBOX_DIR, f)).mtimeMs;
39422
+ mtimeMs = statSync3(join17(SLACK_RECOVERY_OUTBOX_DIR, f)).mtimeMs;
39380
39423
  } catch {
39381
39424
  continue;
39382
39425
  }
@@ -39433,7 +39476,7 @@ async function processSlackNoticeOutboxFile(filename) {
39433
39476
  try {
39434
39477
  let mtimeMs;
39435
39478
  try {
39436
- mtimeMs = statSync2(fullPath).mtimeMs;
39479
+ mtimeMs = statSync3(fullPath).mtimeMs;
39437
39480
  } catch {
39438
39481
  return;
39439
39482
  }
@@ -41882,7 +41925,7 @@ ${result.formatted}` : "No messages in range, or the bot is not a member of this
41882
41925
  let bytes;
41883
41926
  let size;
41884
41927
  try {
41885
- const stat2 = statSync2(resolvedPath);
41928
+ const stat2 = statSync3(resolvedPath);
41886
41929
  if (!stat2.isFile()) {
41887
41930
  return {
41888
41931
  content: [{ type: "text", text: `Upload refused: ${resolvedPath} is not a regular file.` }],
@@ -42673,7 +42716,7 @@ async function replayPendingSlackMarkers() {
42673
42716
  let paneFreshAgeMs = null;
42674
42717
  if (SLACK_AGENT_DIR) {
42675
42718
  try {
42676
- paneFreshAgeMs = Math.max(0, now - statSync2(join17(SLACK_AGENT_DIR, "pane.log")).mtimeMs);
42719
+ paneFreshAgeMs = Math.max(0, now - statSync3(join17(SLACK_AGENT_DIR, "pane.log")).mtimeMs);
42677
42720
  } catch {
42678
42721
  }
42679
42722
  }
@@ -42785,6 +42828,7 @@ async function resolveUserEmail(userId) {
42785
42828
  var currentWs = null;
42786
42829
  var isShuttingDown = false;
42787
42830
  var acquiredLockPath = null;
42831
+ var stopLockHeartbeat = null;
42788
42832
  async function seedMutedChannelsFromApi() {
42789
42833
  try {
42790
42834
  const cfg = statusRuntimeConfig();
@@ -43263,7 +43307,7 @@ async function connectSocketMode() {
43263
43307
  let paneLogFreshAgeMs = null;
43264
43308
  if (SLACK_AGENT_DIR) {
43265
43309
  try {
43266
- const paneMtimeMs = statSync2(join17(SLACK_AGENT_DIR, "pane.log")).mtimeMs;
43310
+ const paneMtimeMs = statSync3(join17(SLACK_AGENT_DIR, "pane.log")).mtimeMs;
43267
43311
  paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
43268
43312
  } catch {
43269
43313
  }
@@ -43498,6 +43542,10 @@ function shutdown(reason, exitCode = 0) {
43498
43542
  currentWs?.close();
43499
43543
  } catch {
43500
43544
  }
43545
+ try {
43546
+ stopLockHeartbeat?.();
43547
+ } catch {
43548
+ }
43501
43549
  try {
43502
43550
  releaseMcpSpawnLock(acquiredLockPath);
43503
43551
  } catch {
@@ -43527,6 +43575,7 @@ process.on("unhandledRejection", (reason) => {
43527
43575
  process.exit(0);
43528
43576
  } else if (lockResult.kind === "acquired") {
43529
43577
  acquiredLockPath = lockResult.path;
43578
+ stopLockHeartbeat = startMcpSpawnLockHeartbeat(acquiredLockPath);
43530
43579
  }
43531
43580
  }
43532
43581
  if (THREAD_STORE_PATH) {
@@ -30097,7 +30097,7 @@ import {
30097
30097
  readdirSync as readdirSync4,
30098
30098
  realpathSync,
30099
30099
  renameSync as renameSync7,
30100
- statSync as statSync2,
30100
+ statSync as statSync3,
30101
30101
  unlinkSync as unlinkSync7,
30102
30102
  watch,
30103
30103
  writeFileSync as writeFileSync11,
@@ -37295,10 +37295,14 @@ import {
37295
37295
  mkdirSync as mkdirSync8,
37296
37296
  readFileSync as readFileSync11,
37297
37297
  renameSync as renameSync6,
37298
+ statSync as statSync2,
37298
37299
  unlinkSync as unlinkSync6,
37300
+ utimesSync,
37299
37301
  writeFileSync as writeFileSync9
37300
37302
  } from "fs";
37301
37303
  import { join as join11 } from "path";
37304
+ var STALE_LOCK_MS = 9e4;
37305
+ var HEARTBEAT_INTERVAL_MS = 3e4;
37302
37306
  function defaultIsPidAlive(pid) {
37303
37307
  if (!Number.isFinite(pid) || pid <= 0) return false;
37304
37308
  try {
@@ -37316,6 +37320,9 @@ function acquireMcpSpawnLock(args) {
37316
37320
  const isPidAlive = options.isPidAlive ?? defaultIsPidAlive;
37317
37321
  const selfPid = options.selfPid ?? process.pid;
37318
37322
  const now = options.now ?? (() => (/* @__PURE__ */ new Date()).toISOString());
37323
+ const nowMs = options.nowMs ?? (() => Date.now());
37324
+ const lockMtimeMs = options.lockMtimeMs ?? defaultLockMtimeMs;
37325
+ const staleMs = options.staleMs ?? STALE_LOCK_MS;
37319
37326
  const path = join11(agentDir, basename2);
37320
37327
  const existing = readLockHolder(path);
37321
37328
  if (existing) {
@@ -37323,7 +37330,11 @@ function acquireMcpSpawnLock(args) {
37323
37330
  return { kind: "acquired", path };
37324
37331
  }
37325
37332
  if (isPidAlive(existing.pid)) {
37326
- return { kind: "blocked", path, holder: existing };
37333
+ const mtime = lockMtimeMs(path);
37334
+ const fresh = mtime !== null && nowMs() - mtime <= staleMs;
37335
+ if (fresh) {
37336
+ return { kind: "blocked", path, holder: existing };
37337
+ }
37327
37338
  }
37328
37339
  }
37329
37340
  mkdirSync8(agentDir, { recursive: true, mode: 448 });
@@ -37344,6 +37355,38 @@ function releaseMcpSpawnLock(lockPath, opts = {}) {
37344
37355
  } catch {
37345
37356
  }
37346
37357
  }
37358
+ function refreshMcpSpawnLock(lockPath, opts = {}) {
37359
+ if (!lockPath) return false;
37360
+ const selfPid = opts.selfPid ?? process.pid;
37361
+ const existing = readLockHolder(lockPath);
37362
+ if (!existing || existing.pid !== selfPid) return false;
37363
+ try {
37364
+ const t = (opts.nowMs ?? (() => Date.now()))() / 1e3;
37365
+ utimesSync(lockPath, t, t);
37366
+ return true;
37367
+ } catch {
37368
+ return false;
37369
+ }
37370
+ }
37371
+ function startMcpSpawnLockHeartbeat(lockPath, opts = {}) {
37372
+ if (!lockPath) return () => {
37373
+ };
37374
+ const intervalMs = opts.intervalMs ?? HEARTBEAT_INTERVAL_MS;
37375
+ const handle = setInterval(() => {
37376
+ if (!refreshMcpSpawnLock(lockPath, { selfPid: opts.selfPid })) {
37377
+ clearInterval(handle);
37378
+ }
37379
+ }, intervalMs);
37380
+ handle.unref?.();
37381
+ return () => clearInterval(handle);
37382
+ }
37383
+ function defaultLockMtimeMs(path) {
37384
+ try {
37385
+ return statSync2(path).mtimeMs;
37386
+ } catch {
37387
+ return null;
37388
+ }
37389
+ }
37347
37390
  function readLockHolder(path) {
37348
37391
  if (!existsSync8(path)) return null;
37349
37392
  try {
@@ -38057,7 +38100,7 @@ function scheduleBusyAck(chatId, messageId, arrivedWhileBusy) {
38057
38100
  let paneLogFreshAgeMs = null;
38058
38101
  if (AGENT_DIR) {
38059
38102
  try {
38060
- const paneMtimeMs = statSync2(join13(AGENT_DIR, "pane.log")).mtimeMs;
38103
+ const paneMtimeMs = statSync3(join13(AGENT_DIR, "pane.log")).mtimeMs;
38061
38104
  paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
38062
38105
  } catch {
38063
38106
  }
@@ -39193,7 +39236,7 @@ function scanRecoveryRetries() {
39193
39236
  if (!f.includes(".retry-") || f.endsWith(".poison.json")) continue;
39194
39237
  let mtimeMs;
39195
39238
  try {
39196
- mtimeMs = statSync2(join13(RECOVERY_OUTBOX_DIR, f)).mtimeMs;
39239
+ mtimeMs = statSync3(join13(RECOVERY_OUTBOX_DIR, f)).mtimeMs;
39197
39240
  } catch {
39198
39241
  continue;
39199
39242
  }
@@ -39250,7 +39293,7 @@ async function processNoticeOutboxFile(filename) {
39250
39293
  try {
39251
39294
  let mtimeMs;
39252
39295
  try {
39253
- mtimeMs = statSync2(fullPath).mtimeMs;
39296
+ mtimeMs = statSync3(fullPath).mtimeMs;
39254
39297
  } catch {
39255
39298
  return;
39256
39299
  }
@@ -39970,7 +40013,7 @@ mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
39970
40013
  let bytes;
39971
40014
  let size;
39972
40015
  try {
39973
- const st = statSync2(realPath);
40016
+ const st = statSync3(realPath);
39974
40017
  if (!st.isFile()) {
39975
40018
  return { content: [{ type: "text", text: `Upload refused: ${resolvedPath} is not a regular file.` }], isError: true };
39976
40019
  }
@@ -40545,7 +40588,7 @@ async function replayPendingTelegramMarkers() {
40545
40588
  let paneFreshAgeMs = null;
40546
40589
  if (AGENT_DIR) {
40547
40590
  try {
40548
- paneFreshAgeMs = Math.max(0, now - statSync2(join13(AGENT_DIR, "pane.log")).mtimeMs);
40591
+ paneFreshAgeMs = Math.max(0, now - statSync3(join13(AGENT_DIR, "pane.log")).mtimeMs);
40549
40592
  } catch {
40550
40593
  }
40551
40594
  }
@@ -40698,6 +40741,7 @@ var telegramHttp = {
40698
40741
  var nextOffset = loadPersistedOffset(TELEGRAM_OFFSET_FILE);
40699
40742
  var isShuttingDown = false;
40700
40743
  var acquiredLockPath = null;
40744
+ var stopLockHeartbeat = null;
40701
40745
  async function pollLoop() {
40702
40746
  while (!isShuttingDown) {
40703
40747
  try {
@@ -41090,7 +41134,7 @@ async function pollLoop() {
41090
41134
  let paneLogFreshAgeMs = null;
41091
41135
  if (AGENT_DIR) {
41092
41136
  try {
41093
- const paneMtimeMs = statSync2(join13(AGENT_DIR, "pane.log")).mtimeMs;
41137
+ const paneMtimeMs = statSync3(join13(AGENT_DIR, "pane.log")).mtimeMs;
41094
41138
  paneLogFreshAgeMs = Math.max(0, Date.now() - paneMtimeMs);
41095
41139
  } catch {
41096
41140
  }
@@ -41257,6 +41301,10 @@ function shutdown(reason) {
41257
41301
  recentDmPersister?.dispose();
41258
41302
  } catch {
41259
41303
  }
41304
+ try {
41305
+ stopLockHeartbeat?.();
41306
+ } catch {
41307
+ }
41260
41308
  try {
41261
41309
  releaseMcpSpawnLock(acquiredLockPath);
41262
41310
  } catch {
@@ -41281,6 +41329,7 @@ process.on("SIGHUP", () => shutdown("SIGHUP"));
41281
41329
  process.exit(0);
41282
41330
  } else if (lockResult.kind === "acquired") {
41283
41331
  acquiredLockPath = lockResult.path;
41332
+ stopLockHeartbeat = startMcpSpawnLockHeartbeat(acquiredLockPath);
41284
41333
  }
41285
41334
  }
41286
41335
  process.stderr.write(
@@ -36,7 +36,7 @@ import {
36
36
  writeDirectChatSessionState,
37
37
  writeEgressAllowlist,
38
38
  writePersistentClaudeWrapper
39
- } from "./chunk-V5CRVBVC.js";
39
+ } from "./chunk-UYBG62IQ.js";
40
40
  import "./chunk-XWVM4KPK.js";
41
41
  export {
42
42
  EGRESS_BASELINE_DOMAINS,
@@ -77,4 +77,4 @@ export {
77
77
  writeEgressAllowlist,
78
78
  writePersistentClaudeWrapper
79
79
  };
80
- //# sourceMappingURL=persistent-session-GRCJPRH5.js.map
80
+ //# sourceMappingURL=persistent-session-VMKIIW5Y.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  paneLogPath
3
- } from "./chunk-V5CRVBVC.js";
3
+ } from "./chunk-UYBG62IQ.js";
4
4
  import "./chunk-XWVM4KPK.js";
5
5
 
6
6
  // src/lib/responsiveness-probe.ts
@@ -437,4 +437,4 @@ export {
437
437
  readAndResetSlackReplyBindingClassifications,
438
438
  readAndResetSlackReplyTargetClassifications
439
439
  };
440
- //# sourceMappingURL=responsiveness-probe-DNM5APN5.js.map
440
+ //# sourceMappingURL=responsiveness-probe-ZNMY5RVO.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@integrity-labs/agt-cli",
3
- "version": "0.28.404",
3
+ "version": "0.28.405",
4
4
  "description": "Augmented Team CLI — agent provisioning and management",
5
5
  "type": "module",
6
6
  "engines": {