@integrity-labs/agt-cli 0.28.522 → 0.28.524

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.
@@ -42,7 +42,7 @@ import {
42
42
  resolveConnectivityProbe,
43
43
  worseConnectivityOutcome,
44
44
  wrapScheduledTaskPrompt
45
- } from "./chunk-4GTDD2I5.js";
45
+ } from "./chunk-LBSV575W.js";
46
46
  import {
47
47
  parsePsRows
48
48
  } from "./chunk-XWVM4KPK.js";
@@ -5317,7 +5317,7 @@ function exchangeFailureKind(err) {
5317
5317
  }
5318
5318
 
5319
5319
  // src/lib/api-client.ts
5320
- var agtCliVersion = true ? "0.28.522" : "dev";
5320
+ var agtCliVersion = true ? "0.28.524" : "dev";
5321
5321
  var lastConfigHash = null;
5322
5322
  function setConfigHash(hash) {
5323
5323
  lastConfigHash = hash && hash.length > 0 ? hash : null;
@@ -8629,4 +8629,4 @@ export {
8629
8629
  managerInstallSystemUnitCommand,
8630
8630
  managerUninstallSystemUnitCommand
8631
8631
  };
8632
- //# sourceMappingURL=chunk-WIQCLSZY.js.map
8632
+ //# sourceMappingURL=chunk-QYQR4BWM.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-5GMZKV37.js");
103
+ const { resolveClaudeBinary } = await import("./persistent-session-OT66RBK5.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-7W7LSW73.js.map
376
+ //# sourceMappingURL=claude-pair-runtime-KEG2LDMH.js.map
@@ -53,7 +53,7 @@ import {
53
53
  safeWriteJsonAtomic,
54
54
  setConfigHash,
55
55
  tripClass
56
- } from "../chunk-WIQCLSZY.js";
56
+ } from "../chunk-QYQR4BWM.js";
57
57
  import {
58
58
  getProjectDir as getProjectDir2,
59
59
  getReadyTasks,
@@ -177,7 +177,7 @@ import {
177
177
  toOpencodeModel,
178
178
  transcriptActivityAgeSeconds,
179
179
  writeEgressAllowlist
180
- } from "../chunk-4GTDD2I5.js";
180
+ } from "../chunk-LBSV575W.js";
181
181
  import {
182
182
  reapOrphanChannelMcps
183
183
  } from "../chunk-XWVM4KPK.js";
@@ -9567,6 +9567,7 @@ var RESTART_DEFER_RECHECK_MS = 6e4;
9567
9567
  var DEFER_LOG_THROTTLE_MS = 6e5;
9568
9568
  var deferLogThrottle = /* @__PURE__ */ new Map();
9569
9569
  var lastInboundMs = /* @__PURE__ */ new Map();
9570
+ var pendingDayRolloverReset = /* @__PURE__ */ new Set();
9570
9571
  var consecutiveWedgeCycles = /* @__PURE__ */ new Map();
9571
9572
  var wedgeExemptionLogged = /* @__PURE__ */ new Set();
9572
9573
  var wedgeRestartsByCard = /* @__PURE__ */ new Map();
@@ -9578,6 +9579,66 @@ function inboundAgeSecondsFor(codeName) {
9578
9579
  if (ts === void 0) return null;
9579
9580
  return Math.max(0, Math.floor((Date.now() - ts) / 1e3));
9580
9581
  }
9582
+ function decideDayRolloverAction(i) {
9583
+ if (!i.staleForToday || !i.sessionHealthy || !i.hasCurrent) return "none";
9584
+ if (i.idle) return "defer-idle";
9585
+ return i.overdueMin >= i.graceMin ? "force-reset" : "busy-wait";
9586
+ }
9587
+ function classifyLazyDayRolloverReset(i) {
9588
+ if (!i.flagged) return "skip";
9589
+ if (!i.sessionHealthy) return "clear-stale";
9590
+ if (!i.staleForToday) return "clear-stale";
9591
+ if (!i.hasCurrent) return "skip";
9592
+ return i.idle ? "reset" : "skip";
9593
+ }
9594
+ function resolveEffectiveAgentTimezone(inputs) {
9595
+ const orgTierTz = cachedMaintenanceWindow?.timezone ?? null;
9596
+ const ownTzEffective = isAgentTimezoneOverrideExpired(inputs.agentTimezoneExpiresAt) ? null : inputs.agentTimezone;
9597
+ if (isUnsetTimezone(ownTzEffective) && isUnsetTimezone(inputs.teamTimezone) && isUnsetTimezone(orgTierTz)) {
9598
+ return void 0;
9599
+ }
9600
+ return resolveAgentTimezone(
9601
+ ownTzEffective,
9602
+ inputs.teamTimezone,
9603
+ orgTierTz,
9604
+ inputs.agentTimezoneExpiresAt
9605
+ );
9606
+ }
9607
+ function cachedAgentTimezoneFor(codeName) {
9608
+ const inputs = agentRestartTimezoneInputs.get(codeName);
9609
+ if (!inputs) return void 0;
9610
+ return resolveEffectiveAgentTimezone({
9611
+ agentTimezone: inputs.agentTimezone,
9612
+ teamTimezone: inputs.teamTimezone,
9613
+ agentTimezoneExpiresAt: inputs.agentTimezoneExpiresAt
9614
+ });
9615
+ }
9616
+ function performLazyDayRolloverReset(codeName, agentTimezone) {
9617
+ const flagged = pendingDayRolloverReset.has(codeName);
9618
+ const sessionHealthy = flagged && isSessionHealthy(codeName);
9619
+ const staleForToday = flagged ? isStaleForToday(codeName, /* @__PURE__ */ new Date(), agentTimezone ?? void 0) : false;
9620
+ const current = flagged && sessionHealthy && staleForToday ? peekCurrentSession(codeName) : null;
9621
+ const outcome = classifyLazyDayRolloverReset({
9622
+ flagged,
9623
+ staleForToday,
9624
+ sessionHealthy,
9625
+ hasCurrent: current !== null,
9626
+ idle: current ? isAgentIdle(getProjectDir(codeName), current.sessionId) : false
9627
+ });
9628
+ if (outcome === "clear-stale") {
9629
+ pendingDayRolloverReset.delete(codeName);
9630
+ return false;
9631
+ }
9632
+ if (outcome === "skip" || !current) return false;
9633
+ log(
9634
+ `[persistent-session] Day rollover for '${codeName}' (yesterday=${current.date}) \u2014 first real trigger after an idle rollover; minting a fresh session now (deferred boot, paid alongside real work) [ENG-8461]`
9635
+ );
9636
+ stopPersistentSessionAndForgetMcpBaseline(codeName, "day-rollover");
9637
+ agentState.persistentSessionAgents.delete(codeName);
9638
+ rotatePaneLogForDayRollover(codeName, log, agentTimezone);
9639
+ pendingDayRolloverReset.delete(codeName);
9640
+ return true;
9641
+ }
9581
9642
  function paneLogAgeSecondsFor(codeName) {
9582
9643
  try {
9583
9644
  const mtimeMs = statSync6(paneLogPath(codeName)).mtimeMs;
@@ -10106,7 +10167,7 @@ var agentRestartTimezoneInputs = /* @__PURE__ */ new Map();
10106
10167
  var lastVersionCheckAt = 0;
10107
10168
  var VERSION_CHECK_INTERVAL_MS = 5 * 60 * 1e3;
10108
10169
  var lastResponsivenessProbeAt = 0;
10109
- var agtCliVersion = true ? "0.28.522" : "dev";
10170
+ var agtCliVersion = true ? "0.28.524" : "dev";
10110
10171
  function resolveBrewPath(execFileSync2) {
10111
10172
  try {
10112
10173
  const out = execFileSync2("which", ["brew"], { timeout: 5e3 }).toString().trim();
@@ -11314,7 +11375,7 @@ function flushRestartedAgentDiagnostics(hostId, codeNames) {
11314
11375
  if (codeNames.length === 0) return;
11315
11376
  void (async () => {
11316
11377
  try {
11317
- const { collectDiagnostics } = await import("../persistent-session-5GMZKV37.js");
11378
+ const { collectDiagnostics } = await import("../persistent-session-OT66RBK5.js");
11318
11379
  await api.post("/host/heartbeat", {
11319
11380
  host_id: hostId,
11320
11381
  agent_diagnostics: collectDiagnostics(codeNames, quarantineEntriesFor, claudeMdSizeFor)
@@ -11421,7 +11482,7 @@ async function pollCycle() {
11421
11482
  }
11422
11483
  try {
11423
11484
  const { detectHostSecurity } = await import("../host-security-6PDFG7F5.js");
11424
- const { collectDiagnostics } = await import("../persistent-session-5GMZKV37.js");
11485
+ const { collectDiagnostics } = await import("../persistent-session-OT66RBK5.js");
11425
11486
  const diagCodeNames = [...agentState.persistentSessionAgents];
11426
11487
  const agentDiagnostics = diagCodeNames.length > 0 ? collectDiagnostics(diagCodeNames, quarantineEntriesFor, claudeMdSizeFor) : void 0;
11427
11488
  let tailscaleHostname;
@@ -11536,7 +11597,7 @@ async function pollCycle() {
11536
11597
  collectResponsivenessProbes,
11537
11598
  collectPanelessActivityProbes,
11538
11599
  getResponsivenessIntervalMs
11539
- } = await import("../responsiveness-probe-52IZOP2M.js");
11600
+ } = await import("../responsiveness-probe-KW7KQJUY.js");
11540
11601
  const probeIntervalMs = getResponsivenessIntervalMs();
11541
11602
  if (now - lastResponsivenessProbeAt > probeIntervalMs) {
11542
11603
  const probeCodeNames = [...agentState.persistentSessionAgents];
@@ -11600,7 +11661,7 @@ async function pollCycle() {
11600
11661
  collectResponsivenessProbes,
11601
11662
  livePendingInboundOldestAgeSeconds,
11602
11663
  parkPendingInbound
11603
- } = await import("../responsiveness-probe-52IZOP2M.js");
11664
+ } = await import("../responsiveness-probe-KW7KQJUY.js");
11604
11665
  const { getProjectDir: wedgeProjectDir } = await import("../scheduler-engine-NDP36U7O.js");
11605
11666
  const wedgeNow = /* @__PURE__ */ new Date();
11606
11667
  const liveAgents = agentState.persistentSessionAgents;
@@ -14505,14 +14566,13 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
14505
14566
  const ownTz = typeof ownTzRaw === "string" && ownTzRaw.trim() !== "" ? ownTzRaw.trim() : null;
14506
14567
  const tz = teamSettingsForTz?.["timezone"];
14507
14568
  const teamTz = typeof tz === "string" && tz.trim() !== "" ? tz.trim() : null;
14508
- const orgTierTz = cachedMaintenanceWindow?.timezone ?? null;
14509
14569
  const ownTzExpiresAtRaw = refreshData.agent?.timezone_expires_at;
14510
14570
  const ownTzExpiresAt = typeof ownTzExpiresAtRaw === "string" && ownTzExpiresAtRaw.trim() !== "" ? ownTzExpiresAtRaw : null;
14511
- const ownTzEffective = isAgentTimezoneOverrideExpired(ownTzExpiresAt) ? null : ownTz;
14512
- if (isUnsetTimezone(ownTzEffective) && isUnsetTimezone(teamTz) && isUnsetTimezone(orgTierTz)) {
14513
- return void 0;
14514
- }
14515
- return resolveAgentTimezone(ownTzEffective, teamTz, orgTierTz, ownTzExpiresAt);
14571
+ return resolveEffectiveAgentTimezone({
14572
+ agentTimezone: ownTz,
14573
+ teamTimezone: teamTz,
14574
+ agentTimezoneExpiresAt: ownTzExpiresAt
14575
+ });
14516
14576
  })();
14517
14577
  const frameworkId = agentFrameworkCache.get(codeName) ?? DEFAULT_FRAMEWORK;
14518
14578
  if (frameworkId === "opencode") {
@@ -14649,35 +14709,40 @@ async function ensurePersistentSession(agent, tasks, boardItems, refreshData) {
14649
14709
  agentState.persistentSessionAgents.delete(codeName);
14650
14710
  restartTrigger = "auth-tuple";
14651
14711
  }
14652
- if (isStaleForToday(codeName, /* @__PURE__ */ new Date(), agentTimezone) && isSessionHealthy(codeName)) {
14653
- const current = peekCurrentSession(codeName);
14654
- if (current) {
14655
- const idle = isAgentIdle(projectDir, current.sessionId);
14656
- if (idle) {
14657
- log(
14658
- `[persistent-session] Day rollover for '${codeName}' (yesterday=${current.date}) \u2014 agent idle, restarting to mint fresh session`
14659
- );
14660
- stopPersistentSessionAndForgetMcpBaseline(codeName, "day-rollover");
14661
- agentState.persistentSessionAgents.delete(codeName);
14662
- restartTrigger = "day-rollover";
14663
- } else {
14664
- const overdueMin = minutesSinceLocalMidnight(/* @__PURE__ */ new Date(), agentTimezone);
14665
- if (overdueMin >= DAY_ROLLOVER_FORCE_GRACE_MIN) {
14666
- log(
14667
- `[persistent-session] Day rollover FORCED for '${codeName}' (yesterday=${current.date}) \u2014 agent busy-blocked ${overdueMin}m past the day boundary (grace ${DAY_ROLLOVER_FORCE_GRACE_MIN}m), restarting anyway to reset context`
14668
- );
14669
- stopPersistentSessionAndForgetMcpBaseline(codeName, "day-rollover");
14670
- agentState.persistentSessionAgents.delete(codeName);
14671
- restartTrigger = "day-rollover";
14672
- dayRolloverForced = true;
14673
- } else {
14674
- log(
14675
- `[persistent-session] Day rollover for '${codeName}' deferred \u2014 agent still active on session ${current.sessionId} (${overdueMin}m past boundary, will force at ${DAY_ROLLOVER_FORCE_GRACE_MIN}m)`
14676
- );
14677
- dayRolloverDeferred = true;
14678
- }
14679
- }
14712
+ const staleForToday = isStaleForToday(codeName, /* @__PURE__ */ new Date(), agentTimezone);
14713
+ if (!staleForToday) pendingDayRolloverReset.delete(codeName);
14714
+ const rolloverSessionHealthy = isSessionHealthy(codeName);
14715
+ const rolloverCurrent = staleForToday && rolloverSessionHealthy ? peekCurrentSession(codeName) : null;
14716
+ const overdueMin = rolloverCurrent ? minutesSinceLocalMidnight(/* @__PURE__ */ new Date(), agentTimezone) : 0;
14717
+ const rolloverDecision = decideDayRolloverAction({
14718
+ staleForToday,
14719
+ sessionHealthy: rolloverSessionHealthy,
14720
+ hasCurrent: rolloverCurrent !== null,
14721
+ idle: rolloverCurrent ? isAgentIdle(projectDir, rolloverCurrent.sessionId) : false,
14722
+ overdueMin,
14723
+ graceMin: DAY_ROLLOVER_FORCE_GRACE_MIN
14724
+ });
14725
+ if (rolloverDecision === "defer-idle" && rolloverCurrent) {
14726
+ if (!pendingDayRolloverReset.has(codeName)) {
14727
+ pendingDayRolloverReset.add(codeName);
14728
+ log(
14729
+ `[persistent-session] Day rollover for '${codeName}' (yesterday=${rolloverCurrent.date}) \u2014 agent idle; keeping the warm session and deferring the fresh-session mint to the first real trigger (no boot booked as utilization) [ENG-8461]`
14730
+ );
14680
14731
  }
14732
+ } else if (rolloverDecision === "force-reset" && rolloverCurrent) {
14733
+ log(
14734
+ `[persistent-session] Day rollover FORCED for '${codeName}' (yesterday=${rolloverCurrent.date}) \u2014 agent busy-blocked ${overdueMin}m past the day boundary (grace ${DAY_ROLLOVER_FORCE_GRACE_MIN}m), restarting anyway to reset context`
14735
+ );
14736
+ stopPersistentSessionAndForgetMcpBaseline(codeName, "day-rollover");
14737
+ agentState.persistentSessionAgents.delete(codeName);
14738
+ pendingDayRolloverReset.delete(codeName);
14739
+ restartTrigger = "day-rollover";
14740
+ dayRolloverForced = true;
14741
+ } else if (rolloverDecision === "busy-wait" && rolloverCurrent) {
14742
+ log(
14743
+ `[persistent-session] Day rollover for '${codeName}' deferred \u2014 agent still active on session ${rolloverCurrent.sessionId} (${overdueMin}m past boundary, will force at ${DAY_ROLLOVER_FORCE_GRACE_MIN}m)`
14744
+ );
14745
+ dayRolloverDeferred = true;
14681
14746
  }
14682
14747
  if (restartTrigger === "day-rollover") {
14683
14748
  rotatePaneLogForDayRollover(codeName, log, agentTimezone);
@@ -14897,7 +14962,15 @@ ${truncateForLog(ctx.tail)}` : `; pane_tail_hash=sha256:${createHash16("sha256")
14897
14962
  deferReadyForUsageCap = true;
14898
14963
  }
14899
14964
  }
14900
- for (const task of deferReadyForUsageCap ? [] : ready) {
14965
+ let deferReadyForRollover = false;
14966
+ if (!deferReadyForUsageCap && ready.length > 0 && performLazyDayRolloverReset(codeName, agentTimezone)) {
14967
+ restartTrigger = "day-rollover";
14968
+ deferReadyForRollover = true;
14969
+ log(
14970
+ `[persistent-session] Deferring ${ready.length} ready task(s) for '${codeName}' \u2014 minting a fresh session after an idle day-rollover; schedule NOT advanced, task fires on the fresh session next tick [ENG-8461]`
14971
+ );
14972
+ }
14973
+ for (const task of deferReadyForUsageCap || deferReadyForRollover ? [] : ready) {
14901
14974
  if (KANBAN_WORK_TEMPLATES.has(task.templateId)) {
14902
14975
  const updated = markTaskFired(codeName, task.taskId, "ok");
14903
14976
  claudeSchedulerStates.set(codeName, updated);
@@ -15108,7 +15181,7 @@ async function handleRestartDoorbell(agentId, requestedAt, restartReason) {
15108
15181
  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}`));
15109
15182
  void (async () => {
15110
15183
  try {
15111
- const { collectDiagnostics } = await import("../persistent-session-5GMZKV37.js");
15184
+ const { collectDiagnostics } = await import("../persistent-session-OT66RBK5.js");
15112
15185
  await api.post("/host/heartbeat", {
15113
15186
  host_id: hostId,
15114
15187
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15158,7 +15231,7 @@ async function respawnAgentAfterMcpStop(codeName, reason) {
15158
15231
  }
15159
15232
  try {
15160
15233
  const hostId = await getHostId();
15161
- const { collectDiagnostics } = await import("../persistent-session-5GMZKV37.js");
15234
+ const { collectDiagnostics } = await import("../persistent-session-OT66RBK5.js");
15162
15235
  await api.post("/host/heartbeat", {
15163
15236
  host_id: hostId,
15164
15237
  agent_diagnostics: collectDiagnostics([codeName], quarantineEntriesFor, claudeMdSizeFor)
@@ -15485,6 +15558,12 @@ async function processDirectChatMessage(agent, msg) {
15485
15558
  await processDirectChatMessageOpencode(agent, msg);
15486
15559
  return;
15487
15560
  }
15561
+ if (performLazyDayRolloverReset(agent.codeName, cachedAgentTimezoneFor(agent.codeName))) {
15562
+ log(
15563
+ `[direct-chat] Reset '${agent.codeName}' to a fresh session on first inbound after an idle day-rollover (msg=${msg.id}) \u2014 leaving pending for durable replay on the fresh session [ENG-8461]`
15564
+ );
15565
+ return;
15566
+ }
15488
15567
  if (isSessionHealthy(agent.codeName)) {
15489
15568
  const useDoorbell = hostFlagStore().getBoolean("direct-chat-doorbell") || isolationMode(agent.codeName) === "docker";
15490
15569
  if (useDoorbell) {
@@ -15676,7 +15755,7 @@ async function processClaudePairSessions(agents) {
15676
15755
  killPairSession,
15677
15756
  pairTmuxSession,
15678
15757
  finalizeClaudePairOnboarding
15679
- } = await import("../claude-pair-runtime-7W7LSW73.js");
15758
+ } = await import("../claude-pair-runtime-KEG2LDMH.js");
15680
15759
  for (const pairId of pendingResp.cancelled_pair_ids ?? []) {
15681
15760
  log(`[claude-pair] sweeping orphan tmux session for pair ${pairId.slice(0, 8)}`);
15682
15761
  const killed = await killPairSession(pairTmuxSession(pairId));
@@ -16599,10 +16678,12 @@ export {
16599
16678
  DAY_ROLLOVER_FORCE_GRACE_MIN,
16600
16679
  applyRestartAcks,
16601
16680
  cancelKanbanNoticeOnDrain,
16681
+ classifyLazyDayRolloverReset,
16602
16682
  claudeCodeUpgradeMarkerPath,
16603
16683
  claudeCodeUpgradeThrottled,
16604
16684
  claudeManagedSettingsPath,
16605
16685
  dashboardRestartBreakerReason,
16686
+ decideDayRolloverAction,
16606
16687
  ensureClaudeManagedSettings,
16607
16688
  extractCharterSlackPeers,
16608
16689
  extractCharterTelegramPeers,