@integrity-labs/agt-cli 0.28.514 → 0.28.516

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.
@@ -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-RM5ZY2SB.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-3SY36KIU.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-YGKYLV4M.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-FWD7QWAR.js.map
@@ -53,7 +53,7 @@ import {
53
53
  safeWriteJsonAtomic,
54
54
  setConfigHash,
55
55
  tripClass
56
- } from "../chunk-GJ6U2XU6.js";
56
+ } from "../chunk-IBI6VSGP.js";
57
57
  import {
58
58
  getProjectDir as getProjectDir2,
59
59
  getReadyTasks,
@@ -69,6 +69,8 @@ import {
69
69
  DEFAULT_FRAMEWORK,
70
70
  FLAGS_SCHEMA_VERSION,
71
71
  FLAG_REGISTRY,
72
+ FORCED_UPDATE_HARD_DEADLINE_MS,
73
+ FORCED_UPDATE_RELAX_AFTER_MS,
72
74
  INTEGRATIONS_SECTION_END,
73
75
  INTEGRATIONS_SECTION_START,
74
76
  KANBAN_CHECK_COMMAND,
@@ -97,6 +99,7 @@ import {
97
99
  estimateActiveTasksTokens,
98
100
  execFilePromiseLong,
99
101
  extractFrontmatter,
102
+ forcedUpdatePendingForMs,
100
103
  formatActorId,
101
104
  formatCursorAdvanceShortfall,
102
105
  formatRunMarker,
@@ -117,6 +120,7 @@ import {
117
120
  isBareAck,
118
121
  isConversationFailureCategory,
119
122
  isEmptyTotals,
123
+ isForcedUpdatePastDeadline,
120
124
  isOnboardingArea,
121
125
  isOpencodeSessionHealthy,
122
126
  isParseError,
@@ -173,7 +177,7 @@ import {
173
177
  toOpencodeModel,
174
178
  transcriptActivityAgeSeconds,
175
179
  writeEgressAllowlist
176
- } from "../chunk-S5RR4UHQ.js";
180
+ } from "../chunk-UQ3TQ7M4.js";
177
181
  import {
178
182
  reapOrphanChannelMcps
179
183
  } from "../chunk-XWVM4KPK.js";
@@ -1517,11 +1521,12 @@ function shouldConsumeForcedUpdate(outcome) {
1517
1521
  return outcome !== "failed";
1518
1522
  }
1519
1523
  var FORCED_UPDATE_DEFER_ESCALATE_AFTER = 20;
1520
- function shouldRelaxForcedUpdateIdleGate(deferStreak) {
1521
- return deferStreak >= FORCED_UPDATE_DEFER_ESCALATE_AFTER;
1524
+ function shouldRelaxForcedUpdateIdleGate(deferStreak, pendingForMs) {
1525
+ if (deferStreak >= FORCED_UPDATE_DEFER_ESCALATE_AFTER) return true;
1526
+ return pendingForMs !== null && pendingForMs !== void 0 && pendingForMs >= FORCED_UPDATE_RELAX_AFTER_MS;
1522
1527
  }
1523
1528
  function decideForcedUpdate(opts) {
1524
- const { requestedAt, lastProcessedAt, hostBusy } = opts;
1529
+ const { requestedAt, lastProcessedAt, hostBusy, pastDeadline } = opts;
1525
1530
  if (!requestedAt) return "none";
1526
1531
  const requestedMs = Date.parse(requestedAt);
1527
1532
  if (Number.isNaN(requestedMs)) return "none";
@@ -1529,9 +1534,24 @@ function decideForcedUpdate(opts) {
1529
1534
  const processedMs = Date.parse(lastProcessedAt);
1530
1535
  if (!Number.isNaN(processedMs) && processedMs >= requestedMs) return "already-handled";
1531
1536
  }
1532
- if (hostBusy) return "defer-idle";
1537
+ if (hostBusy) return pastDeadline ? "consume-deadline" : "defer-idle";
1533
1538
  return "consume";
1534
1539
  }
1540
+ function decidePendingForcedUpdate(opts) {
1541
+ const pendingForMs = forcedUpdatePendingForMs({
1542
+ requestedAt: opts.requestedAt,
1543
+ nowMs: opts.nowMs
1544
+ });
1545
+ const relaxed = shouldRelaxForcedUpdateIdleGate(opts.deferStreak, pendingForMs);
1546
+ const pastDeadline = isForcedUpdatePastDeadline(pendingForMs);
1547
+ const decision = decideForcedUpdate({
1548
+ requestedAt: opts.requestedAt,
1549
+ lastProcessedAt: opts.lastProcessedAt,
1550
+ hostBusy: opts.isHostBusy(relaxed),
1551
+ pastDeadline
1552
+ });
1553
+ return { decision, pendingForMs, relaxed, pastDeadline };
1554
+ }
1535
1555
  function isUrgentUpgrade(opts) {
1536
1556
  if (!opts.urgentTarget) return false;
1537
1557
  if (opts.installed === "dev") return false;
@@ -9628,26 +9648,41 @@ function isHostBusyForForcedUpdate(opts) {
9628
9648
  }
9629
9649
  return false;
9630
9650
  }
9651
+ function describePendingFor(pendingForMs) {
9652
+ if (pendingForMs === null) return "unknown";
9653
+ const totalSeconds = Math.floor(pendingForMs / 1e3);
9654
+ if (totalSeconds < 60) return `${totalSeconds}s`;
9655
+ return `${Math.floor(totalSeconds / 60)}m${String(totalSeconds % 60).padStart(2, "0")}s`;
9656
+ }
9631
9657
  function runPendingForcedUpdate() {
9632
9658
  const requestedUpdateAt = cachedUpdateRequestedAt;
9633
- const relaxed = shouldRelaxForcedUpdateIdleGate(forcedUpdateDeferStreak);
9634
- const forcedUpdate = decideForcedUpdate({
9659
+ const {
9660
+ decision: forcedUpdate,
9661
+ pendingForMs,
9662
+ relaxed
9663
+ } = decidePendingForcedUpdate({
9635
9664
  requestedAt: requestedUpdateAt,
9636
9665
  lastProcessedAt: state6.lastUpdateRequestProcessedAt ?? null,
9637
- hostBusy: isHostBusyForForcedUpdate({ relaxed })
9666
+ deferStreak: forcedUpdateDeferStreak,
9667
+ nowMs: Date.now(),
9668
+ isHostBusy: (isRelaxed) => isHostBusyForForcedUpdate({ relaxed: isRelaxed })
9638
9669
  });
9639
- if (forcedUpdate !== "defer-idle") forcedUpdateDeferStreak = 0;
9670
+ if (forcedUpdate !== "defer-idle") {
9671
+ forcedUpdateDeferStreak = 0;
9672
+ forcedUpdateRelaxAnnounced = false;
9673
+ }
9640
9674
  if (forcedUpdate === "none" || forcedUpdate === "already-handled") return false;
9641
9675
  if (forcedUpdate === "defer-idle") {
9642
9676
  forcedUpdateDeferStreak += 1;
9643
9677
  if (forcedUpdateDeferStreak === 1 || forcedUpdateDeferStreak % 10 === 0) {
9644
9678
  log(
9645
- `[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 deferring: an agent is mid-turn / recently active (consecutive defers: ${forcedUpdateDeferStreak}). Retrying next poll.`
9679
+ `[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 deferring: an agent is mid-turn / recently active (consecutive defers: ${forcedUpdateDeferStreak}, pending ${describePendingFor(pendingForMs)}). Retrying next poll.`
9646
9680
  );
9647
9681
  }
9648
- if (forcedUpdateDeferStreak === FORCED_UPDATE_DEFER_ESCALATE_AFTER) {
9682
+ if (relaxed && !forcedUpdateRelaxAnnounced) {
9683
+ forcedUpdateRelaxAnnounced = true;
9649
9684
  log(
9650
- `[self-update] WARN "Update CLI now" has deferred ${forcedUpdateDeferStreak} consecutive polls waiting for an idle host. Relaxing the idle gate to the progress axis only (an agent actively producing tokens still defers; "received a message in the last 5 minutes" no longer does).`
9685
+ `[self-update] WARN "Update CLI now" has been pending ${describePendingFor(pendingForMs)} (${forcedUpdateDeferStreak} consecutive defers) waiting for an idle host. Relaxing the idle gate to the progress axis only (an agent actively producing tokens still defers; "received a message in the last 5 minutes" no longer does). It runs regardless once ${Math.round(FORCED_UPDATE_HARD_DEADLINE_MS / 6e4)}m have elapsed.`
9651
9686
  );
9652
9687
  }
9653
9688
  return false;
@@ -9659,7 +9694,7 @@ function runPendingForcedUpdate() {
9659
9694
  return false;
9660
9695
  }
9661
9696
  log(
9662
- `[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 running window-bypassing self-update now (host idle${relaxed ? ", relaxed gate" : ""}).`
9697
+ forcedUpdate === "consume-deadline" ? `[self-update] WARN "Update CLI now" requested at ${requestedUpdateAt} has been pending ${describePendingFor(pendingForMs)} and the host still reads busy \u2014 running the window-bypassing self-update anyway (ENG-8449 hard deadline). A live turn may be interrupted; the operator asked for this update explicitly.` : `[self-update] "Update CLI now" requested at ${requestedUpdateAt} \u2014 running window-bypassing self-update now (host idle${relaxed ? ", relaxed gate" : ""}).`
9663
9698
  );
9664
9699
  const prevProcessedAt = state6.lastUpdateRequestProcessedAt ?? null;
9665
9700
  void checkAndUpdateCli({ force: true }).then((outcome) => {
@@ -9808,11 +9843,11 @@ async function runAgentSessionToolBindProbes(agent, integrations, projectDir, op
9808
9843
  if (integrations.length === 0) return true;
9809
9844
  const intervalSec = Number(process.env.AGT_CONNECTIVITY_PROBE_INTERVAL_SECONDS) || 3600;
9810
9845
  const intervalMs = opts?.forceDue ? 0 : intervalSec * 1e3;
9811
- const sessionLoadedServerKeys = new Set(
9812
- readDirectChatSessionState(agent.agent_id)?.mcpServerKeys ?? []
9813
- );
9846
+ const dcSession = readDirectChatSessionState(agent.agent_id);
9847
+ const sessionLoadedServerKeys = new Set(dcSession?.mcpServerKeys ?? []);
9814
9848
  const result = await gatherSessionToolBindProbe(agent, integrations, projectDir, {
9815
9849
  sessionLoadedServerKeys,
9850
+ sessionStartedMs: dcSession?.startedAtMs ?? null,
9816
9851
  intervalMs,
9817
9852
  // ENG-7429 (CodeRabbit on #3063): a prompt probe must cover the WHOLE set, not
9818
9853
  // the rolling batch cap (25), so the just-added integration can't be crowded out
@@ -10071,7 +10106,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
10071
10106
  var lastVersionCheckAt = 0;
10072
10107
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10073
10108
  var lastResponsivenessProbeAt = 0;
10074
- var agtCliVersion = true ? "0.28.514" : "dev";
10109
+ var agtCliVersion = true ? "0.28.516" : "dev";
10075
10110
  function resolveBrewPath(execFileSync2) {
10076
10111
  try {
10077
10112
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -10586,6 +10621,7 @@ var pendingUpgradeVersion = null;
10586
10621
  var selfUpdateInFlight = false;
10587
10622
  var cachedUpdateRequestedAt = null;
10588
10623
  var forcedUpdateDeferStreak = 0;
10624
+ var forcedUpdateRelaxAnnounced = false;
10589
10625
  async function checkAndUpdateCli(opts) {
10590
10626
  const force = opts?.force ?? false;
10591
10627
  if (selfUpdateInFlight) return "failed";
@@ -11278,7 +11314,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
11278
11314
  if (codeNames.length === 0) return;
11279
11315
  void (async () => {
11280
11316
  try {
11281
- const { collectDiagnostics } = await import("../persistent-session-RM5ZY2SB.js");
11317
+ const { collectDiagnostics } = await import("../persistent-session-3SY36KIU.js");
11282
11318
  await api.post("/host/heartbeat", {
11283
11319
  host_id: hostId,
11284
11320
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
@@ -11385,7 +11421,7 @@ async function pollCycle() {
11385
11421
  }
11386
11422
  try {
11387
11423
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
11388
- const { collectDiagnostics } = await import("../persistent-session-RM5ZY2SB.js");
11424
+ const { collectDiagnostics } = await import("../persistent-session-3SY36KIU.js");
11389
11425
  const diagCodeNames = [...agentState.persistentSessionAgents];
11390
11426
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
11391
11427
  let tailscaleHostname;
@@ -11500,7 +11536,7 @@ async function pollCycle() {
11500
11536
  collectResponsivenessProbes,
11501
11537
  collectPanelessActivityProbes,
11502
11538
  getResponsivenessIntervalMs
11503
- } = await import("../responsiveness-probe-C4KMTKWR.js");
11539
+ } = await import("../responsiveness-probe-DSWGHXGG.js");
11504
11540
  const probeIntervalMs = getResponsivenessIntervalMs();
11505
11541
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
11506
11542
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -11564,7 +11600,7 @@ async function pollCycle() {
11564
11600
  collectResponsivenessProbes,
11565
11601
  livePendingInboundOldestAgeSeconds,
11566
11602
  parkPendingInbound
11567
- } = await import("../responsiveness-probe-C4KMTKWR.js");
11603
+ } = await import("../responsiveness-probe-DSWGHXGG.js");
11568
11604
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
11569
11605
  const wedgeNow = /* @__PURE__ */ new Date();
11570
11606
  const liveAgents = agentState.persistentSessionAgents;
@@ -15072,7 +15108,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
15072
15108
  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}`));
15073
15109
  void (async () => {
15074
15110
  try {
15075
- const { collectDiagnostics } = await import("../persistent-session-RM5ZY2SB.js");
15111
+ const { collectDiagnostics } = await import("../persistent-session-3SY36KIU.js");
15076
15112
  await api.post("/host/heartbeat", {
15077
15113
  host_id: hostId,
15078
15114
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15122,7 +15158,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
15122
15158
  }
15123
15159
  try {
15124
15160
  const hostId = await getHostId();
15125
- const { collectDiagnostics } = await import("../persistent-session-RM5ZY2SB.js");
15161
+ const { collectDiagnostics } = await import("../persistent-session-3SY36KIU.js");
15126
15162
  await api.post("/host/heartbeat", {
15127
15163
  host_id: hostId,
15128
15164
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15640,7 +15676,7 @@ async function processClaudePairSessions(agents) {
15640
15676
  killPairSession,
15641
15677
  pairTmuxSession,
15642
15678
  finalizeClaudePairOnboarding
15643
- } = await import("../claude-pair-runtime-YGKYLV4M.js");
15679
+ } = await import("../claude-pair-runtime-FWD7QWAR.js");
15644
15680
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
15645
15681
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
15646
15682
  const killed = await killPairSession(pairTmuxSession(pairId));