@integrity-labs/agt-cli 0.27.86 → 0.27.88

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.
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  claudeModelAlias,
3
3
  isClaudeFastMode
4
- } from "./chunk-5IWPCN3V.js";
4
+ } from "./chunk-54TIJVLZ.js";
5
5
  import {
6
6
  reapOrphanChannelMcps
7
7
  } from "./chunk-XWVM4KPK.js";
@@ -199,6 +199,25 @@ function trimHistory(history, now, timezone) {
199
199
  const cutoffIso = todayLocalIso(cutoff, timezone);
200
200
  return history.filter((h) => h.date >= cutoffIso).slice(0, HISTORY_DAYS);
201
201
  }
202
+ function getOrCreateDailySession(codeName, now = /* @__PURE__ */ new Date(), timezone) {
203
+ const today = todayLocalIso(now, timezone);
204
+ const file = readFile(codeName);
205
+ if (file.current && file.current.date === today) {
206
+ return { sessionId: file.current.sessionId, isNew: false };
207
+ }
208
+ const next = {
209
+ date: today,
210
+ sessionId: randomUUID(),
211
+ startedAt: now.toISOString()
212
+ };
213
+ const history = trimHistory(
214
+ [...file.current ? [file.current] : [], ...file.history],
215
+ now,
216
+ timezone
217
+ );
218
+ writeFile(codeName, { current: next, history });
219
+ return { sessionId: next.sessionId, isNew: true };
220
+ }
202
221
  function markDailySessionSpawn(codeName, sessionId, now = /* @__PURE__ */ new Date(), timezone) {
203
222
  const today = todayLocalIso(now, timezone);
204
223
  const file = readFile(codeName);
@@ -236,6 +255,16 @@ function rotateDailySession(codeName, now = /* @__PURE__ */ new Date(), timezone
236
255
  function encodeProjectPath(projectDir) {
237
256
  return "-" + projectDir.replace(/^\//, "").replace(/[/.]/g, "-");
238
257
  }
258
+ function sessionFileExists(projectDir, sessionId) {
259
+ const path = join(
260
+ homedir(),
261
+ ".claude",
262
+ "projects",
263
+ encodeProjectPath(projectDir),
264
+ `${sessionId}.jsonl`
265
+ );
266
+ return existsSync2(path);
267
+ }
239
268
  function sessionTranscriptDir(projectDir) {
240
269
  return join(homedir(), ".claude", "projects", encodeProjectPath(projectDir));
241
270
  }
@@ -502,6 +531,10 @@ function takeWatchdogGiveUpCount(codeName) {
502
531
  giveUpCounts.delete(codeName);
503
532
  return count;
504
533
  }
534
+ function creditWatchdogGiveUpCount(codeName, count) {
535
+ if (count <= 0) return;
536
+ giveUpCounts.set(codeName, (giveUpCounts.get(codeName) ?? 0) + count);
537
+ }
505
538
 
506
539
  // src/lib/persistent-session.ts
507
540
  function syncClaudeCredsToRoot() {
@@ -695,7 +728,7 @@ function prepareForRespawn(codeName) {
695
728
  const session = sessions.get(codeName);
696
729
  if (!session) return null;
697
730
  const signature = detectFailureSignature(session.lastFailureTail);
698
- if (signature === "session_id_in_use" && session.consecutiveSameUuidFailures >= 2) {
731
+ if (session.consecutiveSameUuidFailures >= 2) {
699
732
  const failureCount = session.consecutiveSameUuidFailures;
700
733
  const newId = rotateDailySession(
701
734
  codeName,
@@ -704,7 +737,7 @@ function prepareForRespawn(codeName) {
704
737
  );
705
738
  session.consecutiveSameUuidFailures = 0;
706
739
  session.lastFailureSessionId = null;
707
- return `rotated daily-session UUID to ${newId} after ${failureCount}+ "Session ID already in use" failures`;
740
+ return `rotated daily-session UUID to ${newId} after ${failureCount} consecutive failures on the same UUID (signature=${signature})`;
708
741
  }
709
742
  return null;
710
743
  }
@@ -717,6 +750,27 @@ function getLastFailureContext(codeName) {
717
750
  restartCount: session?.restartCount ?? 0
718
751
  };
719
752
  }
753
+ function resolveSessionSpawnDecision(args) {
754
+ const { codeName, projectDir, agentTimezone } = args;
755
+ const now = args.now ?? /* @__PURE__ */ new Date();
756
+ const disableFlag = process.env["AGT_DISABLE_SESSION_RESUME"];
757
+ const resumeDisabled = disableFlag === "1" || disableFlag?.toLowerCase() === "true";
758
+ if (resumeDisabled) {
759
+ return { flag: "--session-id", sessionId: randomUUID2(), reason: "resume-disabled" };
760
+ }
761
+ const daily = getOrCreateDailySession(codeName, now, agentTimezone);
762
+ if (!daily.isNew && sessionFileExists(projectDir, daily.sessionId)) {
763
+ return { flag: "--resume", sessionId: daily.sessionId, reason: "resume-today" };
764
+ }
765
+ if (daily.isNew) {
766
+ return { flag: "--session-id", sessionId: daily.sessionId, reason: "fresh-new-day" };
767
+ }
768
+ return {
769
+ flag: "--session-id",
770
+ sessionId: rotateDailySession(codeName, now, agentTimezone),
771
+ reason: "rotated-missing-transcript"
772
+ };
773
+ }
720
774
  function startPersistentSession(config) {
721
775
  const existing = sessions.get(config.codeName);
722
776
  if (existing && existing.status === "running") {
@@ -778,9 +832,17 @@ function spawnSession(config, session) {
778
832
  }
779
833
  }
780
834
  const args = [];
781
- const sessionId = randomUUID2();
782
- args.push("--session-id", sessionId);
783
- log(`[persistent-session] Starting fresh session ${sessionId} for '${codeName}'`);
835
+ const decision = resolveSessionSpawnDecision({
836
+ codeName,
837
+ projectDir,
838
+ agentTimezone: config.agentTimezone ?? void 0
839
+ });
840
+ const sessionId = decision.sessionId;
841
+ const resuming = decision.flag === "--resume";
842
+ args.push(decision.flag, sessionId);
843
+ log(
844
+ `[persistent-session] ${resuming ? "Resuming" : "Starting"} session ${sessionId} for '${codeName}' (${decision.reason})`
845
+ );
784
846
  try {
785
847
  markDailySessionSpawn(codeName, sessionId, /* @__PURE__ */ new Date(), config.agentTimezone ?? void 0);
786
848
  } catch (err) {
@@ -800,7 +862,7 @@ function spawnSession(config, session) {
800
862
  args.push("--name", tmuxSession);
801
863
  const mcpServerNames = collectMcpServerNames(mcpConfigPath);
802
864
  args.push("--allowedTools", buildAllowedTools(mcpServerNames));
803
- const initPrompt = 'You are now online. Say "Ready." and wait for incoming messages. Do not run any tools or load any data until a message arrives.';
865
+ const initPrompt = resuming ? "" : 'You are now online. Say "Ready." and wait for incoming messages. Do not run any tools or load any data until a message arrives.';
804
866
  const claudeBin = resolveClaudeBinary();
805
867
  const claudeArgsJoined = args.map((a) => a.includes(" ") || a.includes("*") ? JSON.stringify(a) : a).join(" ");
806
868
  const wrapperPath = writePersistentClaudeWrapper({
@@ -1068,6 +1130,14 @@ var _internals = {
1068
1130
  isLoginPickerVisible,
1069
1131
  isResumeModeDialogVisible,
1070
1132
  detectFailureSignature,
1133
+ // ENG-6039 test seams: seed/clear the module-private session map so
1134
+ // prepareForRespawn's rotation gate can be exercised without tmux.
1135
+ __seedSession(session) {
1136
+ sessions.set(session.codeName, session);
1137
+ },
1138
+ __clearSessions() {
1139
+ sessions.clear();
1140
+ },
1071
1141
  isClaudeProcessAliveInTmux,
1072
1142
  waitForPromptReady,
1073
1143
  // ENG-5770: exported so the unit test in claude-model-alias.test.ts can
@@ -1433,12 +1503,14 @@ export {
1433
1503
  peekCurrentSession,
1434
1504
  checkChannelInputs,
1435
1505
  takeWatchdogGiveUpCount,
1506
+ creditWatchdogGiveUpCount,
1436
1507
  resolveClaudeBinary,
1437
1508
  writePersistentClaudeWrapper,
1438
1509
  paneLogPath,
1439
1510
  readPaneLogTail,
1440
1511
  prepareForRespawn,
1441
1512
  getLastFailureContext,
1513
+ resolveSessionSpawnDecision,
1442
1514
  startPersistentSession,
1443
1515
  SEND_KEYS_ENTER_DELAY_MS,
1444
1516
  sendToAgent,
@@ -1456,4 +1528,4 @@ export {
1456
1528
  stopAllSessionsAndWait,
1457
1529
  getProjectDir
1458
1530
  };
1459
- //# sourceMappingURL=chunk-4LHN3FAL.js.map
1531
+ //# sourceMappingURL=chunk-SI2WVUAR.js.map