@integrity-labs/agt-cli 0.27.87 → 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
  }
@@ -699,7 +728,7 @@ function prepareForRespawn(codeName) {
699
728
  const session = sessions.get(codeName);
700
729
  if (!session) return null;
701
730
  const signature = detectFailureSignature(session.lastFailureTail);
702
- if (signature === "session_id_in_use" && session.consecutiveSameUuidFailures >= 2) {
731
+ if (session.consecutiveSameUuidFailures >= 2) {
703
732
  const failureCount = session.consecutiveSameUuidFailures;
704
733
  const newId = rotateDailySession(
705
734
  codeName,
@@ -708,7 +737,7 @@ function prepareForRespawn(codeName) {
708
737
  );
709
738
  session.consecutiveSameUuidFailures = 0;
710
739
  session.lastFailureSessionId = null;
711
- 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})`;
712
741
  }
713
742
  return null;
714
743
  }
@@ -721,6 +750,27 @@ function getLastFailureContext(codeName) {
721
750
  restartCount: session?.restartCount ?? 0
722
751
  };
723
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
+ }
724
774
  function startPersistentSession(config) {
725
775
  const existing = sessions.get(config.codeName);
726
776
  if (existing && existing.status === "running") {
@@ -782,9 +832,17 @@ function spawnSession(config, session) {
782
832
  }
783
833
  }
784
834
  const args = [];
785
- const sessionId = randomUUID2();
786
- args.push("--session-id", sessionId);
787
- 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
+ );
788
846
  try {
789
847
  markDailySessionSpawn(codeName, sessionId, /* @__PURE__ */ new Date(), config.agentTimezone ?? void 0);
790
848
  } catch (err) {
@@ -804,7 +862,7 @@ function spawnSession(config, session) {
804
862
  args.push("--name", tmuxSession);
805
863
  const mcpServerNames = collectMcpServerNames(mcpConfigPath);
806
864
  args.push("--allowedTools", buildAllowedTools(mcpServerNames));
807
- 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.';
808
866
  const claudeBin = resolveClaudeBinary();
809
867
  const claudeArgsJoined = args.map((a) => a.includes(" ") || a.includes("*") ? JSON.stringify(a) : a).join(" ");
810
868
  const wrapperPath = writePersistentClaudeWrapper({
@@ -1072,6 +1130,14 @@ var _internals = {
1072
1130
  isLoginPickerVisible,
1073
1131
  isResumeModeDialogVisible,
1074
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
+ },
1075
1141
  isClaudeProcessAliveInTmux,
1076
1142
  waitForPromptReady,
1077
1143
  // ENG-5770: exported so the unit test in claude-model-alias.test.ts can
@@ -1444,6 +1510,7 @@ export {
1444
1510
  readPaneLogTail,
1445
1511
  prepareForRespawn,
1446
1512
  getLastFailureContext,
1513
+ resolveSessionSpawnDecision,
1447
1514
  startPersistentSession,
1448
1515
  SEND_KEYS_ENTER_DELAY_MS,
1449
1516
  sendToAgent,
@@ -1461,4 +1528,4 @@ export {
1461
1528
  stopAllSessionsAndWait,
1462
1529
  getProjectDir
1463
1530
  };
1464
- //# sourceMappingURL=chunk-7EKFVCGY.js.map
1531
+ //# sourceMappingURL=chunk-SI2WVUAR.js.map