@adhdev/daemon-standalone 0.9.4 → 0.9.6

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.
package/dist/index.js CHANGED
@@ -32454,27 +32454,6 @@ ${data.message || ""}`.trim();
32454
32454
  var import_fs2 = require("fs");
32455
32455
  var import_path22 = require("path");
32456
32456
  init_config();
32457
- var HERMES_SESSION_ID_RE = /^\d{8}_\d{6}_[a-z0-9]+$/i;
32458
- var CLAUDE_SESSION_ID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
32459
- function normalizeProviderSessionId(providerType, providerSessionId) {
32460
- const normalizedProviderType = typeof providerType === "string" ? providerType.trim() : "";
32461
- const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
32462
- if (!normalizedId) return "";
32463
- const lowered = normalizedId.toLowerCase();
32464
- if (lowered === "undefined" || lowered === "null") return "";
32465
- if (normalizedProviderType === "hermes-cli" && !HERMES_SESSION_ID_RE.test(normalizedId)) {
32466
- return "";
32467
- }
32468
- if (normalizedProviderType === "claude-cli" && !CLAUDE_SESSION_ID_RE.test(normalizedId)) {
32469
- return "";
32470
- }
32471
- return normalizedId;
32472
- }
32473
- function isLegacyVolatileSessionReadKey(key) {
32474
- const normalizedKey = typeof key === "string" ? key.trim() : "";
32475
- if (!normalizedKey) return false;
32476
- return normalizedKey.startsWith("provider:codex:vscode-webview://");
32477
- }
32478
32457
  var DEFAULT_STATE = {
32479
32458
  recentActivity: [],
32480
32459
  savedProviderSessions: [],
@@ -32493,31 +32472,24 @@ ${data.message || ""}`.trim();
32493
32472
  const parsed = isPlainObject22(raw) ? raw : {};
32494
32473
  const recentActivity = (Array.isArray(parsed.recentActivity) ? parsed.recentActivity : []).filter((entry) => {
32495
32474
  if (!isPlainObject22(entry)) return false;
32496
- const normalizedId = normalizeProviderSessionId(
32497
- typeof entry.providerType === "string" ? entry.providerType : "",
32498
- typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
32499
- );
32500
- if (typeof entry.providerSessionId === "string" && !normalizedId) return false;
32475
+ if (typeof entry.providerSessionId === "string" && !entry.providerSessionId.trim()) return false;
32501
32476
  return true;
32502
32477
  });
32503
32478
  const savedProviderSessions = (Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : []).filter((entry) => {
32504
32479
  if (!isPlainObject22(entry)) return false;
32505
- return !!normalizeProviderSessionId(
32506
- typeof entry.providerType === "string" ? entry.providerType : "",
32507
- typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
32508
- );
32480
+ return typeof entry.providerSessionId === "string" && !!entry.providerSessionId.trim();
32509
32481
  });
32510
32482
  const sessionReads = Object.fromEntries(
32511
- Object.entries(isPlainObject22(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "number" && Number.isFinite(value))
32483
+ Object.entries(isPlainObject22(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
32512
32484
  );
32513
32485
  const sessionReadMarkers = Object.fromEntries(
32514
- Object.entries(isPlainObject22(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string")
32486
+ Object.entries(isPlainObject22(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
32515
32487
  );
32516
32488
  const sessionNotificationDismissals = Object.fromEntries(
32517
- Object.entries(isPlainObject22(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
32489
+ Object.entries(isPlainObject22(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([, value]) => typeof value === "string" && value.length > 0)
32518
32490
  );
32519
32491
  const sessionNotificationUnreadOverrides = Object.fromEntries(
32520
- Object.entries(isPlainObject22(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
32492
+ Object.entries(isPlainObject22(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([, value]) => typeof value === "string" && value.length > 0)
32521
32493
  );
32522
32494
  return {
32523
32495
  recentActivity,
@@ -34585,16 +34557,24 @@ ${cleanBody}`;
34585
34557
  var savedHistoryFileSummaryCache = /* @__PURE__ */ new Map();
34586
34558
  var savedHistoryBackgroundRefresh = /* @__PURE__ */ new Set();
34587
34559
  var savedHistoryRollupInFlight = /* @__PURE__ */ new Set();
34588
- var CODEX_STARTER_PROMPT_RE = /^(?:[›❯]\s*)?(?:Find and fix a bug in @filename|Improve documentation in @filename|Write tests for @filename|Explain this codebase|Summarize recent commits|Implement \{feature\}|Use \/skills(?: to list available skills)?|Run \/review on my current changes)$/i;
34589
34560
  function normalizeHistoryComparable(text) {
34590
34561
  return String(text || "").replace(/\s+/g, " ").trim();
34591
34562
  }
34592
- function cleanupHistoryContent(agentType, role, content) {
34563
+ function cleanupHistoryContent(agentType, role, content, historyBehavior) {
34593
34564
  let value = String(content || "").replace(/\r\n/g, "\n").trim();
34594
34565
  if (!value) return "";
34595
- if (agentType === "codex-cli" && role === "assistant") {
34596
- const filtered = value.split("\n").filter((line) => !CODEX_STARTER_PROMPT_RE.test(line.trim())).join("\n").replace(/\n{3,}/g, "\n\n").trim();
34597
- value = filtered;
34566
+ if (role === "assistant" && historyBehavior?.filterAssistantPatterns?.length) {
34567
+ const filters = historyBehavior.filterAssistantPatterns.map((p) => {
34568
+ try {
34569
+ return new RegExp(p, "i");
34570
+ } catch {
34571
+ return null;
34572
+ }
34573
+ }).filter(Boolean);
34574
+ if (filters.length > 0) {
34575
+ const filtered = value.split("\n").filter((line) => !filters.some((re2) => re2.test(line.trim()))).join("\n").replace(/\n{3,}/g, "\n\n").trim();
34576
+ value = filtered;
34577
+ }
34598
34578
  }
34599
34579
  return value;
34600
34580
  }
@@ -34611,8 +34591,8 @@ ${cleanBody}`;
34611
34591
  if (!previous || !next) return false;
34612
34592
  return buildHistoryMessageSignature(agentType, previous) === buildHistoryMessageSignature(agentType, next);
34613
34593
  }
34614
- function collapseReplayAssistantTurns(agentType, messages) {
34615
- if (agentType !== "codex-cli") return messages;
34594
+ function collapseReplayAssistantTurns(messages, historyBehavior) {
34595
+ if (!historyBehavior?.collapseConsecutiveAssistantTurns) return messages;
34616
34596
  const collapsed = [];
34617
34597
  let sawAssistantSinceLastUser = false;
34618
34598
  for (const message of messages) {
@@ -34717,16 +34697,12 @@ ${cleanBody}`;
34717
34697
  return true;
34718
34698
  }).sort().reverse();
34719
34699
  }
34720
- function normalizeSavedHistorySessionId(agentType, historySessionId) {
34721
- const normalizedId = String(historySessionId || "").trim();
34722
- if (!normalizedId) return "";
34723
- const strictProviderId = normalizeProviderSessionId(agentType, normalizedId);
34724
- if (strictProviderId) return strictProviderId;
34725
- return agentType === "hermes-cli" ? "" : normalizedId;
34700
+ function normalizeSavedHistorySessionId(historySessionId) {
34701
+ return String(historySessionId || "").trim();
34726
34702
  }
34727
- function extractSavedHistorySessionIdFromFile(agentType, file2) {
34703
+ function extractSavedHistorySessionIdFromFile(file2) {
34728
34704
  const match = file2.match(/^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/);
34729
- return normalizeSavedHistorySessionId(agentType, match?.[1] || "");
34705
+ return normalizeSavedHistorySessionId(match?.[1] || "");
34730
34706
  }
34731
34707
  function buildSavedHistoryFileSignatureMap(dir, files) {
34732
34708
  return new Map(files.map((file2) => {
@@ -34905,7 +34881,7 @@ ${cleanBody}`;
34905
34881
  }
34906
34882
  }
34907
34883
  function updateSavedHistoryIndexForSessionStart(agentType, dir, file2, historySessionId, workspace) {
34908
- const normalizedSessionId = normalizeSavedHistorySessionId(agentType, historySessionId);
34884
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
34909
34885
  const normalizedWorkspace = String(workspace || "").trim();
34910
34886
  if (!normalizedSessionId || !normalizedWorkspace) return;
34911
34887
  persistSavedHistoryFileSummaryEntry(agentType, dir, file2, (currentSummary) => ({
@@ -34920,7 +34896,7 @@ ${cleanBody}`;
34920
34896
  }));
34921
34897
  }
34922
34898
  function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file2, historySessionId, messages) {
34923
- const normalizedSessionId = normalizeSavedHistorySessionId(agentType, historySessionId || "");
34899
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || "");
34924
34900
  if (!normalizedSessionId || messages.length === 0) return;
34925
34901
  persistSavedHistoryFileSummaryEntry(agentType, dir, file2, (currentSummary) => {
34926
34902
  const nextSummary = {
@@ -34957,8 +34933,8 @@ ${cleanBody}`;
34957
34933
  return nextSummary;
34958
34934
  });
34959
34935
  }
34960
- function computeSavedHistoryFileSummary(agentType, dir, file2) {
34961
- const historySessionId = extractSavedHistorySessionIdFromFile(agentType, file2);
34936
+ function computeSavedHistoryFileSummary(dir, file2) {
34937
+ const historySessionId = extractSavedHistorySessionIdFromFile(file2);
34962
34938
  if (!historySessionId) return null;
34963
34939
  const filePath = path7.join(dir, file2);
34964
34940
  const content = fs32.readFileSync(filePath, "utf-8");
@@ -35052,7 +35028,7 @@ ${cleanBody}`;
35052
35028
  const cached2 = savedHistoryFileSummaryCache.get(filePath);
35053
35029
  const persisted = persistedEntries.get(file2);
35054
35030
  const reusableEntry = cached2?.signature === signature ? cached2 : persisted?.signature === signature ? persisted : null;
35055
- const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(agentType, dir, file2);
35031
+ const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(dir, file2);
35056
35032
  const nextEntry = reusableEntry || {
35057
35033
  signature,
35058
35034
  summary: fileSummary
@@ -35350,7 +35326,7 @@ ${cleanBody}`;
35350
35326
  } catch {
35351
35327
  }
35352
35328
  }
35353
- compactHistorySession(agentType, historySessionId) {
35329
+ compactHistorySession(agentType, historySessionId, historyBehavior) {
35354
35330
  const sessionId = String(historySessionId || "").trim();
35355
35331
  if (!sessionId) return;
35356
35332
  try {
@@ -35388,7 +35364,7 @@ ${cleanBody}`;
35388
35364
  dedupedAdjacent.push(entry);
35389
35365
  if (entry.role !== "system") lastTurn = entry;
35390
35366
  }
35391
- const collapsed = collapseReplayAssistantTurns(agentType, dedupedAdjacent);
35367
+ const collapsed = collapseReplayAssistantTurns(dedupedAdjacent, historyBehavior);
35392
35368
  if (collapsed.length === 0) {
35393
35369
  fs32.unlinkSync(filePath);
35394
35370
  continue;
@@ -35437,7 +35413,7 @@ ${cleanBody}`;
35437
35413
  return name.replace(/[^a-zA-Z0-9_-]/g, "_");
35438
35414
  }
35439
35415
  };
35440
- function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0) {
35416
+ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
35441
35417
  try {
35442
35418
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
35443
35419
  const dir = path7.join(HISTORY_DIR, sanitized);
@@ -35472,7 +35448,7 @@ ${cleanBody}`;
35472
35448
  chronological.push(message);
35473
35449
  if (message.role !== "system") lastTurn = message;
35474
35450
  }
35475
- const collapsed = collapseReplayAssistantTurns(agentType, chronological);
35451
+ const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
35476
35452
  const boundedLimit = Math.max(1, limit);
35477
35453
  const boundedOffset = Math.max(0, offset);
35478
35454
  const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
@@ -35485,7 +35461,7 @@ ${cleanBody}`;
35485
35461
  return { messages: [], hasMore: false };
35486
35462
  }
35487
35463
  }
35488
- function listSavedHistorySessions(agentType, options = {}) {
35464
+ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
35489
35465
  try {
35490
35466
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
35491
35467
  const dir = path7.join(HISTORY_DIR, sanitized);
@@ -35616,7 +35592,7 @@ ${cleanBody}`;
35616
35592
  }
35617
35593
  }
35618
35594
  function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
35619
- const normalizedSessionId = normalizeSavedHistorySessionId("hermes-cli", historySessionId);
35595
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
35620
35596
  if (!normalizedSessionId) return false;
35621
35597
  try {
35622
35598
  const sessionFilePath = path7.join(os52.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
@@ -35765,7 +35741,7 @@ ${cleanBody}`;
35765
35741
  return parts;
35766
35742
  }
35767
35743
  function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
35768
- const normalizedSessionId = normalizeSavedHistorySessionId("claude-cli", historySessionId);
35744
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
35769
35745
  if (!normalizedSessionId) return false;
35770
35746
  try {
35771
35747
  const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
@@ -39875,7 +39851,8 @@ ${effect.notification.body || ""}`.trim();
39875
39851
  }
39876
39852
  const managed = runtimeSessionId ? h.agentStream?.getManagedSession(runtimeSessionId) : null;
39877
39853
  const targetSessionId = managed?.cdpSessionId || null;
39878
- const IDE_LEVEL_SCRIPTS = provider.type === "claude-code-vscode" ? ["listModes", "setMode", "listModels", "setModel", "setModelGui"] : ["listModes", "setMode", "listModels", "setModel"];
39854
+ const DEFAULT_IDE_LEVEL_SCRIPTS = ["listModes", "setMode", "listModels", "setModel"];
39855
+ const IDE_LEVEL_SCRIPTS = provider.ideLevelScripts ?? DEFAULT_IDE_LEVEL_SCRIPTS;
39879
39856
  if (IDE_LEVEL_SCRIPTS.includes(scriptName)) {
39880
39857
  if (targetSessionId) {
39881
39858
  try {
@@ -40592,6 +40569,21 @@ ${effect.notification.body || ""}`.trim();
40592
40569
  init_contracts();
40593
40570
  init_provider_cli_adapter();
40594
40571
  init_logger();
40572
+ function normalizeProviderSessionId(provider, providerSessionId) {
40573
+ const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
40574
+ if (!normalizedId) return "";
40575
+ const lowered = normalizedId.toLowerCase();
40576
+ if (lowered === "undefined" || lowered === "null") return "";
40577
+ const sessionIdPattern = provider?.sessionIdPattern;
40578
+ if (sessionIdPattern) {
40579
+ try {
40580
+ const re2 = new RegExp(sessionIdPattern, "i");
40581
+ if (!re2.test(normalizedId)) return "";
40582
+ } catch {
40583
+ }
40584
+ }
40585
+ return normalizedId;
40586
+ }
40595
40587
  init_chat_message_normalization();
40596
40588
  function normalizePersistableCliHistoryContent(content) {
40597
40589
  return flattenContent(content).replace(/\s+/g, " ").trim();
@@ -40698,6 +40690,13 @@ ${effect.notification.body || ""}`.trim();
40698
40690
  runtimeMessages = [];
40699
40691
  lastPersistedHistoryMessages = [];
40700
40692
  lastCanonicalHermesSyncMtimeMs = 0;
40693
+ lastCanonicalHermesExistCheckAt = 0;
40694
+ lastCanonicalHermesWatchPath = void 0;
40695
+ lastCanonicalClaudeRebuildMtimeMs = 0;
40696
+ lastCanonicalClaudeCheckAt = 0;
40697
+ cachedSqliteDb = null;
40698
+ cachedSqliteDbPath = null;
40699
+ cachedSqliteDbMissingUntil = 0;
40701
40700
  instanceId;
40702
40701
  suppressIdleHistoryReplay = false;
40703
40702
  errorMessage = void 0;
@@ -40748,32 +40747,10 @@ ${effect.notification.body || ""}`.trim();
40748
40747
  }
40749
40748
  async onTick() {
40750
40749
  if (this.providerSessionId) return;
40751
- if (this.type === "hermes-cli" && this.launchMode === "new") return;
40752
- let probedSessionId = null;
40750
+ if (this.provider.resume?.skipProbeOnNewSession && this.launchMode === "new") return;
40753
40751
  const probeConfig = this.provider.sessionProbe;
40754
- if (probeConfig) {
40755
- probedSessionId = this.probeSessionIdFromConfig(probeConfig);
40756
- } else {
40757
- if (this.type === "opencode-cli") {
40758
- probedSessionId = this.probeSessionIdFromConfig({
40759
- dbPath: "~/.local/share/opencode/opencode.db",
40760
- query: "select id from session where directory in ({dirs}) and time_created >= ? and time_archived is null order by time_updated desc limit 1",
40761
- timestampFormat: "unix_ms"
40762
- });
40763
- } else if (this.type === "codex-cli") {
40764
- probedSessionId = this.probeSessionIdFromConfig({
40765
- dbPath: "~/.codex/state_5.sqlite",
40766
- query: "select id from threads where cwd in ({dirs}) and updated_at >= ? and archived = 0 order by updated_at desc limit 1",
40767
- timestampFormat: "unix_s"
40768
- });
40769
- } else if (this.type === "goose-cli") {
40770
- probedSessionId = this.probeSessionIdFromConfig({
40771
- dbPath: "~/.local/share/goose/sessions/sessions.db",
40772
- query: "select id from sessions where working_dir in ({dirs}) and created_at >= ? order by updated_at desc limit 1",
40773
- timestampFormat: "iso"
40774
- });
40775
- }
40776
- }
40752
+ if (!probeConfig) return;
40753
+ const probedSessionId = this.probeSessionIdFromConfig(probeConfig);
40777
40754
  if (probedSessionId) {
40778
40755
  this.promoteProviderSessionId(probedSessionId);
40779
40756
  }
@@ -40784,7 +40761,12 @@ ${effect.notification.body || ""}`.trim();
40784
40761
  */
40785
40762
  probeSessionIdFromConfig(probe) {
40786
40763
  const resolvedDbPath = probe.dbPath.replace(/^~/, os11.homedir());
40787
- if (!fs52.existsSync(resolvedDbPath)) return null;
40764
+ const now = Date.now();
40765
+ if (this.cachedSqliteDbMissingUntil > now) return null;
40766
+ if (!fs52.existsSync(resolvedDbPath)) {
40767
+ this.cachedSqliteDbMissingUntil = now + 1e4;
40768
+ return null;
40769
+ }
40788
40770
  const directories = this.getProbeDirectories();
40789
40771
  const minCreatedAt = Math.max(0, this.startedAt - 6e4);
40790
40772
  const tsFormat = probe.timestampFormat || "unix_ms";
@@ -40825,7 +40807,7 @@ ${effect.notification.body || ""}`.trim();
40825
40807
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
40826
40808
  const visibleStatus = parseErrorMessage ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
40827
40809
  const parsedProviderSessionId = normalizeProviderSessionId(
40828
- this.type,
40810
+ this.provider,
40829
40811
  typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
40830
40812
  );
40831
40813
  if (parsedProviderSessionId) {
@@ -40955,6 +40937,12 @@ ${effect.notification.body || ""}`.trim();
40955
40937
  this.adapter.shutdown();
40956
40938
  this.monitor.reset();
40957
40939
  this.appliedEffectKeys.clear();
40940
+ try {
40941
+ this.cachedSqliteDb?.close();
40942
+ } catch {
40943
+ }
40944
+ this.cachedSqliteDb = null;
40945
+ this.cachedSqliteDbPath = null;
40958
40946
  }
40959
40947
  completedDebounceTimer = null;
40960
40948
  completedDebouncePending = null;
@@ -41115,7 +41103,7 @@ ${effect.notification.body || ""}`.trim();
41115
41103
  applyProviderResponse(data, options) {
41116
41104
  if (!data || typeof data !== "object") return;
41117
41105
  const patchedProviderSessionId = normalizeProviderSessionId(
41118
- this.type,
41106
+ this.provider,
41119
41107
  typeof data.providerSessionId === "string" ? data.providerSessionId : ""
41120
41108
  );
41121
41109
  if (patchedProviderSessionId) {
@@ -41353,52 +41341,61 @@ ${effect.notification.body || ""}`.trim();
41353
41341
  }
41354
41342
  syncCanonicalSavedHistoryIfNeeded() {
41355
41343
  if (!this.providerSessionId) return false;
41356
- if (this.type === "hermes-cli") {
41357
- try {
41358
- const canonicalPath = path11.join(os11.homedir(), ".hermes", "sessions", `session_${this.providerSessionId}.json`);
41359
- if (!fs52.existsSync(canonicalPath)) return false;
41360
- const stat4 = fs52.statSync(canonicalPath);
41344
+ const canonicalHistory = this.provider.canonicalHistory;
41345
+ if (!canonicalHistory) return false;
41346
+ try {
41347
+ let rebuilt = false;
41348
+ if (canonicalHistory.format === "hermes-json") {
41349
+ const watchPath = canonicalHistory.watchPath.replace(/^~/, os11.homedir()).replace("{{sessionId}}", this.providerSessionId);
41350
+ const now = Date.now();
41351
+ if (watchPath !== this.lastCanonicalHermesWatchPath || now - this.lastCanonicalHermesExistCheckAt >= 2e3) {
41352
+ this.lastCanonicalHermesWatchPath = watchPath;
41353
+ this.lastCanonicalHermesExistCheckAt = now;
41354
+ if (!fs52.existsSync(watchPath)) return false;
41355
+ } else if (this.lastCanonicalHermesSyncMtimeMs === 0) {
41356
+ if (!fs52.existsSync(watchPath)) return false;
41357
+ }
41358
+ const stat4 = fs52.statSync(watchPath);
41361
41359
  if (stat4.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
41362
- const rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
41363
- if (!rebuilt) return false;
41364
- this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
41365
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
41366
- this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
41367
- role: message.role,
41368
- content: message.content,
41369
- kind: message.kind,
41370
- senderName: message.senderName,
41371
- receivedAt: message.receivedAt
41372
- }));
41373
- return true;
41374
- } catch {
41375
- return false;
41376
- }
41377
- }
41378
- if (this.type === "claude-cli") {
41379
- try {
41380
- const rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
41381
- if (!rebuilt) return false;
41382
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
41383
- this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
41384
- role: message.role,
41385
- content: message.content,
41386
- kind: message.kind,
41387
- senderName: message.senderName,
41388
- receivedAt: message.receivedAt
41389
- }));
41390
- return true;
41391
- } catch {
41392
- return false;
41360
+ rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
41361
+ if (rebuilt) this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
41362
+ } else if (canonicalHistory.format === "claude-jsonl") {
41363
+ const now = Date.now();
41364
+ if (now - this.lastCanonicalClaudeCheckAt < 2e3 && this.lastCanonicalClaudeRebuildMtimeMs !== 0) {
41365
+ return true;
41366
+ }
41367
+ this.lastCanonicalClaudeCheckAt = now;
41368
+ const claudeProjectsDir = path11.join(os11.homedir(), ".claude", "projects");
41369
+ const workspaceSegment = typeof this.workingDir === "string" ? this.workingDir.replace(/[\\/]/g, "-").replace(/^-+/, "") : "";
41370
+ const transcriptFile = path11.join(claudeProjectsDir, workspaceSegment, `${this.providerSessionId}.jsonl`);
41371
+ let transcriptMtime = 0;
41372
+ try {
41373
+ transcriptMtime = fs52.statSync(transcriptFile).mtimeMs;
41374
+ } catch {
41375
+ }
41376
+ if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalClaudeRebuildMtimeMs) return true;
41377
+ rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
41378
+ if (rebuilt) this.lastCanonicalClaudeRebuildMtimeMs = transcriptMtime || Date.now();
41393
41379
  }
41380
+ if (!rebuilt) return false;
41381
+ const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
41382
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
41383
+ role: message.role,
41384
+ content: message.content,
41385
+ kind: message.kind,
41386
+ senderName: message.senderName,
41387
+ receivedAt: message.receivedAt
41388
+ }));
41389
+ return true;
41390
+ } catch {
41391
+ return false;
41394
41392
  }
41395
- return false;
41396
41393
  }
41397
41394
  restorePersistedHistoryFromCurrentSession() {
41398
41395
  if (!this.providerSessionId) return;
41399
41396
  this.syncCanonicalSavedHistoryIfNeeded();
41400
- this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
41401
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
41397
+ this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
41398
+ const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
41402
41399
  this.historyWriter.seedSessionHistory(
41403
41400
  this.type,
41404
41401
  restoredHistory.messages,
@@ -41443,20 +41440,29 @@ ${effect.notification.body || ""}`.trim();
41443
41440
  return Array.from({ length: count }, () => "?").join(", ");
41444
41441
  }
41445
41442
  querySqliteText(dbPath, query, params) {
41446
- let db = null;
41447
41443
  try {
41448
- const DatabaseSync = getDatabaseSync();
41449
- db = new DatabaseSync(dbPath, { readOnly: true });
41450
- const row = db.prepare(query).get(...params);
41444
+ if (this.cachedSqliteDb === null || this.cachedSqliteDbPath !== dbPath) {
41445
+ try {
41446
+ this.cachedSqliteDb?.close();
41447
+ } catch {
41448
+ }
41449
+ this.cachedSqliteDb = null;
41450
+ this.cachedSqliteDbPath = null;
41451
+ const DatabaseSync = getDatabaseSync();
41452
+ this.cachedSqliteDb = new DatabaseSync(dbPath, { readOnly: true });
41453
+ this.cachedSqliteDbPath = dbPath;
41454
+ }
41455
+ const row = this.cachedSqliteDb.prepare(query).get(...params);
41451
41456
  const sessionId = typeof row?.id === "string" ? row.id.trim() : "";
41452
41457
  return sessionId || null;
41453
41458
  } catch {
41454
- return null;
41455
- } finally {
41456
41459
  try {
41457
- db?.close();
41460
+ this.cachedSqliteDb?.close();
41458
41461
  } catch {
41459
41462
  }
41463
+ this.cachedSqliteDb = null;
41464
+ this.cachedSqliteDbPath = null;
41465
+ return null;
41460
41466
  }
41461
41467
  }
41462
41468
  };
@@ -42631,14 +42637,15 @@ ${rawInput}` : rawInput;
42631
42637
  if (!Array.isArray(template) || template.length === 0) return void 0;
42632
42638
  return template.map((part) => part === "{{id}}" ? sessionId : part);
42633
42639
  }
42634
- function readCodexResumeSessionId(args) {
42635
- const resumeIndex = args.findIndex((arg) => arg === "resume" || arg === "fork");
42640
+ function readSubcommandSessionId(args, subcommands) {
42641
+ const resumeIndex = args.findIndex((arg) => subcommands.includes(arg));
42636
42642
  if (resumeIndex < 0) return void 0;
42637
42643
  const candidate = args[resumeIndex + 1];
42638
42644
  if (!candidate || candidate.startsWith("-")) return void 0;
42639
42645
  return candidate;
42640
42646
  }
42641
- function detectExplicitProviderSessionId(normalizedType, args) {
42647
+ function detectExplicitProviderSessionId(provider, args) {
42648
+ const resume = provider?.resume;
42642
42649
  const explicitResumeId = readArgValue(args, ["--resume", "-r"]);
42643
42650
  if (explicitResumeId) {
42644
42651
  return { providerSessionId: explicitResumeId, launchMode: "resume" };
@@ -42652,19 +42659,20 @@ ${rawInput}` : rawInput;
42652
42659
  }
42653
42660
  const explicitSessionId = readArgValue(args, ["--session-id"]);
42654
42661
  if (explicitSessionId) {
42655
- if (normalizedType === "goose-cli" && !hasArg(args, ["--resume", "-r"])) {
42662
+ if (resume?.sessionIdIsNewByDefault && !hasArg(args, ["--resume", "-r"])) {
42656
42663
  return { launchMode: "manual" };
42657
42664
  }
42658
- const isResume = normalizedType === "goose-cli" ? hasArg(args, ["--resume", "-r"]) : hasArg(args, ["--continue"]) || hasArg(args, ["--resume", "-r"]);
42665
+ const isResume = resume?.sessionIdIsNewByDefault ? hasArg(args, ["--resume", "-r"]) : hasArg(args, ["--continue"]) || hasArg(args, ["--resume", "-r"]);
42659
42666
  return {
42660
42667
  providerSessionId: explicitSessionId,
42661
42668
  launchMode: isResume ? "resume" : "new"
42662
42669
  };
42663
42670
  }
42664
- if (normalizedType === "codex-cli") {
42665
- const codexSessionId = readCodexResumeSessionId(args);
42666
- if (codexSessionId) {
42667
- return { providerSessionId: codexSessionId, launchMode: "resume" };
42671
+ const subcommands = resume?.sessionIdFromSubcommand;
42672
+ if (Array.isArray(subcommands) && subcommands.length > 0) {
42673
+ const subcommandSessionId = readSubcommandSessionId(args, subcommands);
42674
+ if (subcommandSessionId) {
42675
+ return { providerSessionId: subcommandSessionId, launchMode: "resume" };
42668
42676
  }
42669
42677
  }
42670
42678
  return { launchMode: "manual" };
@@ -42681,7 +42689,7 @@ ${rawInput}` : rawInput;
42681
42689
  if (!resume?.supported) {
42682
42690
  return { cliArgs: baseArgs, launchMode: "manual" };
42683
42691
  }
42684
- const explicit = detectExplicitProviderSessionId(normalizedType, baseArgs || []);
42692
+ const explicit = detectExplicitProviderSessionId(provider, baseArgs || []);
42685
42693
  if (explicit.providerSessionId) {
42686
42694
  return {
42687
42695
  cliArgs: baseArgs,
@@ -42689,6 +42697,12 @@ ${rawInput}` : rawInput;
42689
42697
  launchMode: explicit.launchMode
42690
42698
  };
42691
42699
  }
42700
+ if (explicit.launchMode === "manual" && hasArg(baseArgs || [], ["--session-id"])) {
42701
+ return {
42702
+ cliArgs: baseArgs,
42703
+ launchMode: "manual"
42704
+ };
42705
+ }
42692
42706
  if (requestedResumeSessionId) {
42693
42707
  if (resume.sessionIdFormat === "uuid" && !isUuid(requestedResumeSessionId)) {
42694
42708
  throw new Error(`Invalid ${provider?.displayName || provider?.name || normalizedType} session ID: ${requestedResumeSessionId}`);
@@ -43387,6 +43401,12 @@ Run 'adhdev doctor' for detailed diagnostics.`
43387
43401
  "resume",
43388
43402
  "sessionProbe",
43389
43403
  "approvalPositiveHints",
43404
+ "sessionIdPattern",
43405
+ "historyBehavior",
43406
+ "canonicalHistory",
43407
+ "autoFixProfile",
43408
+ "ideLevelScripts",
43409
+ "allowInputDuringGeneration",
43390
43410
  "scripts",
43391
43411
  "vscodeCommands",
43392
43412
  "inputMethod",
@@ -50664,20 +50684,13 @@ async (params) => {
50664
50684
  } catch {
50665
50685
  }
50666
50686
  }
50687
+ function shouldScheduleAutoStopOnQuiet(options) {
50688
+ return !!options.verification && options.autoImpl?.autoStopOnQuiet === true;
50689
+ }
50667
50690
  function getDefaultAutoImplReference(ctx, category, type) {
50668
- if (category === "cli") {
50669
- return type === "codex-cli" ? "claude-cli" : "codex-cli";
50670
- }
50671
- if (category === "extension") {
50672
- const preferred = ["claude-code-vscode", "codex", "cline", "roo-code"];
50673
- for (const ref of preferred) {
50674
- if (ref === type) continue;
50675
- if (ctx.providerLoader.resolve(ref) || ctx.providerLoader.getMeta(ref)) return ref;
50676
- }
50677
- const all = ctx.providerLoader.getAll();
50678
- const fb = all.find((p) => p.category === "extension" && p.type !== type);
50679
- if (fb?.type) return fb.type;
50680
- }
50691
+ const all = ctx.providerLoader.getAll();
50692
+ const sameCategoryOther = all.find((p) => p.category === category && p.type !== type);
50693
+ if (sameCategoryOther?.type) return sameCategoryOther.type;
50681
50694
  return "antigravity";
50682
50695
  }
50683
50696
  function resolveAutoImplReference(ctx, category, requestedReference, targetType) {
@@ -50995,37 +51008,33 @@ async (params) => {
50995
51008
  return;
50996
51009
  }
50997
51010
  const command = spawn4.command;
51011
+ const autoImpl = spawn4.autoImpl;
50998
51012
  const interactiveFlags = ["--yolo", "--interactive", "-i"];
50999
51013
  const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
51000
51014
  let shellCmd;
51001
51015
  const isWin = os19.platform() === "win32";
51002
51016
  const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
51003
- if (command === "claude") {
51004
- const args = [...baseArgs, "--dangerously-skip-permissions"];
51017
+ const promptMode = autoImpl?.promptMode ?? "stdin";
51018
+ const extraArgs = autoImpl?.extraArgs ?? [];
51019
+ const rawMetaPrompt = autoImpl?.metaPrompt ? autoImpl.metaPrompt.replace("{{promptFile}}", promptFile) : `Read the file at ${promptFile} and follow ALL the instructions in it exactly. Do not ask questions, just execute.`;
51020
+ if (promptMode === "flag") {
51021
+ const flag = autoImpl?.promptFlag ?? "-p";
51022
+ const args = [...baseArgs, ...extraArgs];
51005
51023
  if (model) args.push("--model", model);
51006
51024
  const escapedArgs = args.map(escapeArg).join(" ");
51007
- const metaPrompt = `Read the file at ${promptFile} and follow ALL the instructions. Implement the specific function requested, then test it via CDP curl targeting 127.0.0.1:19280, wait for confirmation of success, and then close. DO NOT start working on other features not listed in the prompt constraint.`;
51008
- shellCmd = `${command} ${escapedArgs} -p ${escapeArg(metaPrompt)}`;
51009
- } else if (command === "gemini") {
51010
- const args = [...baseArgs, "-y", "-s", "false"];
51011
- if (model) args.push("-m", model);
51012
- const escapedArgs = args.map(escapeArg).join(" ");
51013
- const metaPrompt = `Read the file at ${promptFile} and follow ALL the instructions in it exactly. Do not ask questions, just execute.`;
51014
- shellCmd = `${command} ${escapedArgs} -p ${escapeArg(metaPrompt)}`;
51015
- } else if (command === "codex") {
51016
- const args = ["exec", ...baseArgs];
51017
- if (!args.includes("--dangerously-bypass-approvals-and-sandbox")) {
51018
- args.push("--dangerously-bypass-approvals-and-sandbox");
51019
- }
51020
- if (!args.includes("--skip-git-repo-check")) {
51021
- args.push("--skip-git-repo-check");
51025
+ shellCmd = `${command} ${escapedArgs} ${flag} ${escapeArg(rawMetaPrompt)}`;
51026
+ } else if (promptMode === "subcommand") {
51027
+ const subcommand = autoImpl?.subcommand ?? "";
51028
+ const args = subcommand ? [subcommand, ...baseArgs] : [...baseArgs];
51029
+ for (const extra of extraArgs) {
51030
+ if (!args.includes(extra)) args.push(extra);
51022
51031
  }
51023
51032
  if (model) args.push("--model", model);
51024
51033
  const escapedArgs = args.map(escapeArg).join(" ");
51025
- const metaPrompt = `Read the file at ${promptFile} and follow ALL instructions strictly. DO NOT spend time exploring the filesystem or other providers. You have full authority to implement ALL required script files and independently test them against 127.0.0.1:19280 via CDP CURL. Upon complete validation of ALL assigned files, print exactly "_PIPELINE_COMPLETE_SIGNAL_" to gracefully close the pipeline. DO NOT WAIT FOR APPROVAL, execute completely autonomously.`;
51026
- shellCmd = `${command} ${escapedArgs} ${escapeArg(metaPrompt)}`;
51034
+ shellCmd = `${command} ${escapedArgs} ${escapeArg(rawMetaPrompt)}`;
51027
51035
  } else {
51028
- const escapedArgs = baseArgs.map(escapeArg).join(" ");
51036
+ const args = [...baseArgs, ...extraArgs];
51037
+ const escapedArgs = args.map(escapeArg).join(" ");
51029
51038
  if (isWin) {
51030
51039
  shellCmd = `type "${promptFile}" | ${command} ${escapedArgs}`;
51031
51040
  } else {
@@ -51060,8 +51069,7 @@ async (params) => {
51060
51069
  stdio: ["pipe", "pipe", "pipe"],
51061
51070
  env: {
51062
51071
  ...process.env,
51063
- ...spawn4.env || {},
51064
- ...command === "gemini" ? { SANDBOX: "1", GEMINI_CLI_NO_RELAUNCH: "1" } : {}
51072
+ ...spawn4.env || {}
51065
51073
  }
51066
51074
  });
51067
51075
  child.on("error", (err2) => {
@@ -51123,7 +51131,7 @@ async (params) => {
51123
51131
  }
51124
51132
  };
51125
51133
  const scheduleAutoStopForVerification = () => {
51126
- if (!verification || command !== "codex" || completionSignalSeen || autoStopIssued) return;
51134
+ if (!shouldScheduleAutoStopOnQuiet({ verification, autoImpl }) || completionSignalSeen || autoStopIssued) return;
51127
51135
  const elapsed = Date.now() - spawnedAt;
51128
51136
  if (elapsed < 3e4) return;
51129
51137
  clearAutoStopTimer();