@adhdev/daemon-core 0.9.4 → 0.9.5

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.mjs CHANGED
@@ -4451,31 +4451,6 @@ function getSavedProviderSessions(state, filters) {
4451
4451
  init_config();
4452
4452
  import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
4453
4453
  import { join as join3 } from "path";
4454
-
4455
- // src/providers/provider-session-id.ts
4456
- var HERMES_SESSION_ID_RE = /^\d{8}_\d{6}_[a-z0-9]+$/i;
4457
- 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;
4458
- function normalizeProviderSessionId(providerType, providerSessionId) {
4459
- const normalizedProviderType = typeof providerType === "string" ? providerType.trim() : "";
4460
- const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
4461
- if (!normalizedId) return "";
4462
- const lowered = normalizedId.toLowerCase();
4463
- if (lowered === "undefined" || lowered === "null") return "";
4464
- if (normalizedProviderType === "hermes-cli" && !HERMES_SESSION_ID_RE.test(normalizedId)) {
4465
- return "";
4466
- }
4467
- if (normalizedProviderType === "claude-cli" && !CLAUDE_SESSION_ID_RE.test(normalizedId)) {
4468
- return "";
4469
- }
4470
- return normalizedId;
4471
- }
4472
- function isLegacyVolatileSessionReadKey(key) {
4473
- const normalizedKey = typeof key === "string" ? key.trim() : "";
4474
- if (!normalizedKey) return false;
4475
- return normalizedKey.startsWith("provider:codex:vscode-webview://");
4476
- }
4477
-
4478
- // src/config/state-store.ts
4479
4454
  var DEFAULT_STATE = {
4480
4455
  recentActivity: [],
4481
4456
  savedProviderSessions: [],
@@ -4494,31 +4469,24 @@ function normalizeState(raw) {
4494
4469
  const parsed = isPlainObject2(raw) ? raw : {};
4495
4470
  const recentActivity = (Array.isArray(parsed.recentActivity) ? parsed.recentActivity : []).filter((entry) => {
4496
4471
  if (!isPlainObject2(entry)) return false;
4497
- const normalizedId = normalizeProviderSessionId(
4498
- typeof entry.providerType === "string" ? entry.providerType : "",
4499
- typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
4500
- );
4501
- if (typeof entry.providerSessionId === "string" && !normalizedId) return false;
4472
+ if (typeof entry.providerSessionId === "string" && !entry.providerSessionId.trim()) return false;
4502
4473
  return true;
4503
4474
  });
4504
4475
  const savedProviderSessions = (Array.isArray(parsed.savedProviderSessions) ? parsed.savedProviderSessions : []).filter((entry) => {
4505
4476
  if (!isPlainObject2(entry)) return false;
4506
- return !!normalizeProviderSessionId(
4507
- typeof entry.providerType === "string" ? entry.providerType : "",
4508
- typeof entry.providerSessionId === "string" ? entry.providerSessionId : ""
4509
- );
4477
+ return typeof entry.providerSessionId === "string" && !!entry.providerSessionId.trim();
4510
4478
  });
4511
4479
  const sessionReads = Object.fromEntries(
4512
- Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "number" && Number.isFinite(value))
4480
+ Object.entries(isPlainObject2(parsed.sessionReads) ? parsed.sessionReads : {}).filter(([, value]) => typeof value === "number" && Number.isFinite(value))
4513
4481
  );
4514
4482
  const sessionReadMarkers = Object.fromEntries(
4515
- Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string")
4483
+ Object.entries(isPlainObject2(parsed.sessionReadMarkers) ? parsed.sessionReadMarkers : {}).filter(([, value]) => typeof value === "string")
4516
4484
  );
4517
4485
  const sessionNotificationDismissals = Object.fromEntries(
4518
- Object.entries(isPlainObject2(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
4486
+ Object.entries(isPlainObject2(parsed.sessionNotificationDismissals) ? parsed.sessionNotificationDismissals : {}).filter(([, value]) => typeof value === "string" && value.length > 0)
4519
4487
  );
4520
4488
  const sessionNotificationUnreadOverrides = Object.fromEntries(
4521
- Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([key, value]) => !isLegacyVolatileSessionReadKey(key) && typeof value === "string" && value.length > 0)
4489
+ Object.entries(isPlainObject2(parsed.sessionNotificationUnreadOverrides) ? parsed.sessionNotificationUnreadOverrides : {}).filter(([, value]) => typeof value === "string" && value.length > 0)
4522
4490
  );
4523
4491
  return {
4524
4492
  recentActivity,
@@ -6610,16 +6578,24 @@ var savedHistorySessionCache = /* @__PURE__ */ new Map();
6610
6578
  var savedHistoryFileSummaryCache = /* @__PURE__ */ new Map();
6611
6579
  var savedHistoryBackgroundRefresh = /* @__PURE__ */ new Set();
6612
6580
  var savedHistoryRollupInFlight = /* @__PURE__ */ new Set();
6613
- 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;
6614
6581
  function normalizeHistoryComparable(text) {
6615
6582
  return String(text || "").replace(/\s+/g, " ").trim();
6616
6583
  }
6617
- function cleanupHistoryContent(agentType, role, content) {
6584
+ function cleanupHistoryContent(agentType, role, content, historyBehavior) {
6618
6585
  let value = String(content || "").replace(/\r\n/g, "\n").trim();
6619
6586
  if (!value) return "";
6620
- if (agentType === "codex-cli" && role === "assistant") {
6621
- const filtered = value.split("\n").filter((line) => !CODEX_STARTER_PROMPT_RE.test(line.trim())).join("\n").replace(/\n{3,}/g, "\n\n").trim();
6622
- value = filtered;
6587
+ if (role === "assistant" && historyBehavior?.filterAssistantPatterns?.length) {
6588
+ const filters = historyBehavior.filterAssistantPatterns.map((p) => {
6589
+ try {
6590
+ return new RegExp(p, "i");
6591
+ } catch {
6592
+ return null;
6593
+ }
6594
+ }).filter(Boolean);
6595
+ if (filters.length > 0) {
6596
+ const filtered = value.split("\n").filter((line) => !filters.some((re) => re.test(line.trim()))).join("\n").replace(/\n{3,}/g, "\n\n").trim();
6597
+ value = filtered;
6598
+ }
6623
6599
  }
6624
6600
  return value;
6625
6601
  }
@@ -6636,8 +6612,8 @@ function isAdjacentHistoryDuplicate(agentType, previous, next) {
6636
6612
  if (!previous || !next) return false;
6637
6613
  return buildHistoryMessageSignature(agentType, previous) === buildHistoryMessageSignature(agentType, next);
6638
6614
  }
6639
- function collapseReplayAssistantTurns(agentType, messages) {
6640
- if (agentType !== "codex-cli") return messages;
6615
+ function collapseReplayAssistantTurns(messages, historyBehavior) {
6616
+ if (!historyBehavior?.collapseConsecutiveAssistantTurns) return messages;
6641
6617
  const collapsed = [];
6642
6618
  let sawAssistantSinceLastUser = false;
6643
6619
  for (const message of messages) {
@@ -6742,16 +6718,12 @@ function listHistoryFiles(dir, historySessionId) {
6742
6718
  return true;
6743
6719
  }).sort().reverse();
6744
6720
  }
6745
- function normalizeSavedHistorySessionId(agentType, historySessionId) {
6746
- const normalizedId = String(historySessionId || "").trim();
6747
- if (!normalizedId) return "";
6748
- const strictProviderId = normalizeProviderSessionId(agentType, normalizedId);
6749
- if (strictProviderId) return strictProviderId;
6750
- return agentType === "hermes-cli" ? "" : normalizedId;
6721
+ function normalizeSavedHistorySessionId(historySessionId) {
6722
+ return String(historySessionId || "").trim();
6751
6723
  }
6752
- function extractSavedHistorySessionIdFromFile(agentType, file) {
6724
+ function extractSavedHistorySessionIdFromFile(file) {
6753
6725
  const match = file.match(/^([A-Za-z0-9_-]+)_\d{4}-\d{2}-\d{2}\.jsonl$/);
6754
- return normalizeSavedHistorySessionId(agentType, match?.[1] || "");
6726
+ return normalizeSavedHistorySessionId(match?.[1] || "");
6755
6727
  }
6756
6728
  function buildSavedHistoryFileSignatureMap(dir, files) {
6757
6729
  return new Map(files.map((file) => {
@@ -6930,7 +6902,7 @@ function persistSavedHistoryFileSummaryEntry(agentType, dir, file, updater) {
6930
6902
  }
6931
6903
  }
6932
6904
  function updateSavedHistoryIndexForSessionStart(agentType, dir, file, historySessionId, workspace) {
6933
- const normalizedSessionId = normalizeSavedHistorySessionId(agentType, historySessionId);
6905
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
6934
6906
  const normalizedWorkspace = String(workspace || "").trim();
6935
6907
  if (!normalizedSessionId || !normalizedWorkspace) return;
6936
6908
  persistSavedHistoryFileSummaryEntry(agentType, dir, file, (currentSummary) => ({
@@ -6945,7 +6917,7 @@ function updateSavedHistoryIndexForSessionStart(agentType, dir, file, historySes
6945
6917
  }));
6946
6918
  }
6947
6919
  function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, historySessionId, messages) {
6948
- const normalizedSessionId = normalizeSavedHistorySessionId(agentType, historySessionId || "");
6920
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || "");
6949
6921
  if (!normalizedSessionId || messages.length === 0) return;
6950
6922
  persistSavedHistoryFileSummaryEntry(agentType, dir, file, (currentSummary) => {
6951
6923
  const nextSummary = {
@@ -6982,8 +6954,8 @@ function updateSavedHistoryIndexForAppendedMessages(agentType, dir, file, histor
6982
6954
  return nextSummary;
6983
6955
  });
6984
6956
  }
6985
- function computeSavedHistoryFileSummary(agentType, dir, file) {
6986
- const historySessionId = extractSavedHistorySessionIdFromFile(agentType, file);
6957
+ function computeSavedHistoryFileSummary(dir, file) {
6958
+ const historySessionId = extractSavedHistorySessionIdFromFile(file);
6987
6959
  if (!historySessionId) return null;
6988
6960
  const filePath = path7.join(dir, file);
6989
6961
  const content = fs3.readFileSync(filePath, "utf-8");
@@ -7077,7 +7049,7 @@ function computeSavedHistorySessionSummaries(agentType, dir, files, fileSignatur
7077
7049
  const cached = savedHistoryFileSummaryCache.get(filePath);
7078
7050
  const persisted = persistedEntries.get(file);
7079
7051
  const reusableEntry = cached?.signature === signature ? cached : persisted?.signature === signature ? persisted : null;
7080
- const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(agentType, dir, file);
7052
+ const fileSummary = reusableEntry?.summary || computeSavedHistoryFileSummary(dir, file);
7081
7053
  const nextEntry = reusableEntry || {
7082
7054
  signature,
7083
7055
  summary: fileSummary
@@ -7375,7 +7347,7 @@ var ChatHistoryWriter = class {
7375
7347
  } catch {
7376
7348
  }
7377
7349
  }
7378
- compactHistorySession(agentType, historySessionId) {
7350
+ compactHistorySession(agentType, historySessionId, historyBehavior) {
7379
7351
  const sessionId = String(historySessionId || "").trim();
7380
7352
  if (!sessionId) return;
7381
7353
  try {
@@ -7413,7 +7385,7 @@ var ChatHistoryWriter = class {
7413
7385
  dedupedAdjacent.push(entry);
7414
7386
  if (entry.role !== "system") lastTurn = entry;
7415
7387
  }
7416
- const collapsed = collapseReplayAssistantTurns(agentType, dedupedAdjacent);
7388
+ const collapsed = collapseReplayAssistantTurns(dedupedAdjacent, historyBehavior);
7417
7389
  if (collapsed.length === 0) {
7418
7390
  fs3.unlinkSync(filePath);
7419
7391
  continue;
@@ -7462,7 +7434,7 @@ var ChatHistoryWriter = class {
7462
7434
  return name.replace(/[^a-zA-Z0-9_-]/g, "_");
7463
7435
  }
7464
7436
  };
7465
- function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0) {
7437
+ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
7466
7438
  try {
7467
7439
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
7468
7440
  const dir = path7.join(HISTORY_DIR, sanitized);
@@ -7497,7 +7469,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
7497
7469
  chronological.push(message);
7498
7470
  if (message.role !== "system") lastTurn = message;
7499
7471
  }
7500
- const collapsed = collapseReplayAssistantTurns(agentType, chronological);
7472
+ const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
7501
7473
  const boundedLimit = Math.max(1, limit);
7502
7474
  const boundedOffset = Math.max(0, offset);
7503
7475
  const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
@@ -7510,7 +7482,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
7510
7482
  return { messages: [], hasMore: false };
7511
7483
  }
7512
7484
  }
7513
- function listSavedHistorySessions(agentType, options = {}) {
7485
+ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
7514
7486
  try {
7515
7487
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
7516
7488
  const dir = path7.join(HISTORY_DIR, sanitized);
@@ -7641,7 +7613,7 @@ function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
7641
7613
  }
7642
7614
  }
7643
7615
  function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
7644
- const normalizedSessionId = normalizeSavedHistorySessionId("hermes-cli", historySessionId);
7616
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
7645
7617
  if (!normalizedSessionId) return false;
7646
7618
  try {
7647
7619
  const sessionFilePath = path7.join(os5.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
@@ -7790,7 +7762,7 @@ function extractClaudeUserContentParts(content) {
7790
7762
  return parts;
7791
7763
  }
7792
7764
  function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
7793
- const normalizedSessionId = normalizeSavedHistorySessionId("claude-cli", historySessionId);
7765
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
7794
7766
  if (!normalizedSessionId) return false;
7795
7767
  try {
7796
7768
  const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
@@ -11956,7 +11928,8 @@ async function executeProviderScript(h, args, scriptName) {
11956
11928
  }
11957
11929
  const managed = runtimeSessionId ? h.agentStream?.getManagedSession(runtimeSessionId) : null;
11958
11930
  const targetSessionId = managed?.cdpSessionId || null;
11959
- const IDE_LEVEL_SCRIPTS = provider.type === "claude-code-vscode" ? ["listModes", "setMode", "listModels", "setModel", "setModelGui"] : ["listModes", "setMode", "listModels", "setModel"];
11931
+ const DEFAULT_IDE_LEVEL_SCRIPTS = ["listModes", "setMode", "listModels", "setModel"];
11932
+ const IDE_LEVEL_SCRIPTS = provider.ideLevelScripts ?? DEFAULT_IDE_LEVEL_SCRIPTS;
11960
11933
  if (IDE_LEVEL_SCRIPTS.includes(scriptName)) {
11961
11934
  if (targetSessionId) {
11962
11935
  try {
@@ -12681,6 +12654,25 @@ import * as fs5 from "fs";
12681
12654
  import { createRequire } from "module";
12682
12655
  init_provider_cli_adapter();
12683
12656
  init_logger();
12657
+
12658
+ // src/providers/provider-session-id.ts
12659
+ function normalizeProviderSessionId(provider, providerSessionId) {
12660
+ const normalizedId = typeof providerSessionId === "string" ? providerSessionId.trim() : "";
12661
+ if (!normalizedId) return "";
12662
+ const lowered = normalizedId.toLowerCase();
12663
+ if (lowered === "undefined" || lowered === "null") return "";
12664
+ const sessionIdPattern = provider?.sessionIdPattern;
12665
+ if (sessionIdPattern) {
12666
+ try {
12667
+ const re = new RegExp(sessionIdPattern, "i");
12668
+ if (!re.test(normalizedId)) return "";
12669
+ } catch {
12670
+ }
12671
+ }
12672
+ return normalizedId;
12673
+ }
12674
+
12675
+ // src/providers/cli-provider-instance.ts
12684
12676
  init_chat_message_normalization();
12685
12677
  function normalizePersistableCliHistoryContent(content) {
12686
12678
  return flattenContent(content).replace(/\s+/g, " ").trim();
@@ -12837,32 +12829,10 @@ var CliProviderInstance = class {
12837
12829
  }
12838
12830
  async onTick() {
12839
12831
  if (this.providerSessionId) return;
12840
- if (this.type === "hermes-cli" && this.launchMode === "new") return;
12841
- let probedSessionId = null;
12832
+ if (this.provider.resume?.skipProbeOnNewSession && this.launchMode === "new") return;
12842
12833
  const probeConfig = this.provider.sessionProbe;
12843
- if (probeConfig) {
12844
- probedSessionId = this.probeSessionIdFromConfig(probeConfig);
12845
- } else {
12846
- if (this.type === "opencode-cli") {
12847
- probedSessionId = this.probeSessionIdFromConfig({
12848
- dbPath: "~/.local/share/opencode/opencode.db",
12849
- query: "select id from session where directory in ({dirs}) and time_created >= ? and time_archived is null order by time_updated desc limit 1",
12850
- timestampFormat: "unix_ms"
12851
- });
12852
- } else if (this.type === "codex-cli") {
12853
- probedSessionId = this.probeSessionIdFromConfig({
12854
- dbPath: "~/.codex/state_5.sqlite",
12855
- query: "select id from threads where cwd in ({dirs}) and updated_at >= ? and archived = 0 order by updated_at desc limit 1",
12856
- timestampFormat: "unix_s"
12857
- });
12858
- } else if (this.type === "goose-cli") {
12859
- probedSessionId = this.probeSessionIdFromConfig({
12860
- dbPath: "~/.local/share/goose/sessions/sessions.db",
12861
- query: "select id from sessions where working_dir in ({dirs}) and created_at >= ? order by updated_at desc limit 1",
12862
- timestampFormat: "iso"
12863
- });
12864
- }
12865
- }
12834
+ if (!probeConfig) return;
12835
+ const probedSessionId = this.probeSessionIdFromConfig(probeConfig);
12866
12836
  if (probedSessionId) {
12867
12837
  this.promoteProviderSessionId(probedSessionId);
12868
12838
  }
@@ -12914,7 +12884,7 @@ var CliProviderInstance = class {
12914
12884
  const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
12915
12885
  const visibleStatus = parseErrorMessage ? "error" : autoApproveActive ? "generating" : adapterStatus.status;
12916
12886
  const parsedProviderSessionId = normalizeProviderSessionId(
12917
- this.type,
12887
+ this.provider,
12918
12888
  typeof parsedStatus?.providerSessionId === "string" ? parsedStatus.providerSessionId : ""
12919
12889
  );
12920
12890
  if (parsedProviderSessionId) {
@@ -13204,7 +13174,7 @@ var CliProviderInstance = class {
13204
13174
  applyProviderResponse(data, options) {
13205
13175
  if (!data || typeof data !== "object") return;
13206
13176
  const patchedProviderSessionId = normalizeProviderSessionId(
13207
- this.type,
13177
+ this.provider,
13208
13178
  typeof data.providerSessionId === "string" ? data.providerSessionId : ""
13209
13179
  );
13210
13180
  if (patchedProviderSessionId) {
@@ -13442,52 +13412,39 @@ ${effect.notification.body || ""}`.trim();
13442
13412
  }
13443
13413
  syncCanonicalSavedHistoryIfNeeded() {
13444
13414
  if (!this.providerSessionId) return false;
13445
- if (this.type === "hermes-cli") {
13446
- try {
13447
- const canonicalPath = path11.join(os11.homedir(), ".hermes", "sessions", `session_${this.providerSessionId}.json`);
13448
- if (!fs5.existsSync(canonicalPath)) return false;
13449
- const stat = fs5.statSync(canonicalPath);
13415
+ const canonicalHistory = this.provider.canonicalHistory;
13416
+ if (!canonicalHistory) return false;
13417
+ try {
13418
+ let rebuilt = false;
13419
+ if (canonicalHistory.format === "hermes-json") {
13420
+ const watchPath = canonicalHistory.watchPath.replace(/^~/, os11.homedir()).replace("{{sessionId}}", this.providerSessionId);
13421
+ if (!fs5.existsSync(watchPath)) return false;
13422
+ const stat = fs5.statSync(watchPath);
13450
13423
  if (stat.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
13451
- const rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
13452
- if (!rebuilt) return false;
13453
- this.lastCanonicalHermesSyncMtimeMs = stat.mtimeMs;
13454
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
13455
- this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
13456
- role: message.role,
13457
- content: message.content,
13458
- kind: message.kind,
13459
- senderName: message.senderName,
13460
- receivedAt: message.receivedAt
13461
- }));
13462
- return true;
13463
- } catch {
13464
- return false;
13465
- }
13466
- }
13467
- if (this.type === "claude-cli") {
13468
- try {
13469
- const rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
13470
- if (!rebuilt) return false;
13471
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
13472
- this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
13473
- role: message.role,
13474
- content: message.content,
13475
- kind: message.kind,
13476
- senderName: message.senderName,
13477
- receivedAt: message.receivedAt
13478
- }));
13479
- return true;
13480
- } catch {
13481
- return false;
13482
- }
13424
+ rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
13425
+ if (rebuilt) this.lastCanonicalHermesSyncMtimeMs = stat.mtimeMs;
13426
+ } else if (canonicalHistory.format === "claude-jsonl") {
13427
+ rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
13428
+ }
13429
+ if (!rebuilt) return false;
13430
+ const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
13431
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
13432
+ role: message.role,
13433
+ content: message.content,
13434
+ kind: message.kind,
13435
+ senderName: message.senderName,
13436
+ receivedAt: message.receivedAt
13437
+ }));
13438
+ return true;
13439
+ } catch {
13440
+ return false;
13483
13441
  }
13484
- return false;
13485
13442
  }
13486
13443
  restorePersistedHistoryFromCurrentSession() {
13487
13444
  if (!this.providerSessionId) return;
13488
13445
  this.syncCanonicalSavedHistoryIfNeeded();
13489
- this.historyWriter.compactHistorySession(this.type, this.providerSessionId);
13490
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId);
13446
+ this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
13447
+ const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
13491
13448
  this.historyWriter.seedSessionHistory(
13492
13449
  this.type,
13493
13450
  restoredHistory.messages,
@@ -14733,14 +14690,15 @@ function expandResumeArgs(template, sessionId) {
14733
14690
  if (!Array.isArray(template) || template.length === 0) return void 0;
14734
14691
  return template.map((part) => part === "{{id}}" ? sessionId : part);
14735
14692
  }
14736
- function readCodexResumeSessionId(args) {
14737
- const resumeIndex = args.findIndex((arg) => arg === "resume" || arg === "fork");
14693
+ function readSubcommandSessionId(args, subcommands) {
14694
+ const resumeIndex = args.findIndex((arg) => subcommands.includes(arg));
14738
14695
  if (resumeIndex < 0) return void 0;
14739
14696
  const candidate = args[resumeIndex + 1];
14740
14697
  if (!candidate || candidate.startsWith("-")) return void 0;
14741
14698
  return candidate;
14742
14699
  }
14743
- function detectExplicitProviderSessionId(normalizedType, args) {
14700
+ function detectExplicitProviderSessionId(provider, args) {
14701
+ const resume = provider?.resume;
14744
14702
  const explicitResumeId = readArgValue(args, ["--resume", "-r"]);
14745
14703
  if (explicitResumeId) {
14746
14704
  return { providerSessionId: explicitResumeId, launchMode: "resume" };
@@ -14754,19 +14712,20 @@ function detectExplicitProviderSessionId(normalizedType, args) {
14754
14712
  }
14755
14713
  const explicitSessionId = readArgValue(args, ["--session-id"]);
14756
14714
  if (explicitSessionId) {
14757
- if (normalizedType === "goose-cli" && !hasArg(args, ["--resume", "-r"])) {
14715
+ if (resume?.sessionIdIsNewByDefault && !hasArg(args, ["--resume", "-r"])) {
14758
14716
  return { launchMode: "manual" };
14759
14717
  }
14760
- const isResume = normalizedType === "goose-cli" ? hasArg(args, ["--resume", "-r"]) : hasArg(args, ["--continue"]) || hasArg(args, ["--resume", "-r"]);
14718
+ const isResume = resume?.sessionIdIsNewByDefault ? hasArg(args, ["--resume", "-r"]) : hasArg(args, ["--continue"]) || hasArg(args, ["--resume", "-r"]);
14761
14719
  return {
14762
14720
  providerSessionId: explicitSessionId,
14763
14721
  launchMode: isResume ? "resume" : "new"
14764
14722
  };
14765
14723
  }
14766
- if (normalizedType === "codex-cli") {
14767
- const codexSessionId = readCodexResumeSessionId(args);
14768
- if (codexSessionId) {
14769
- return { providerSessionId: codexSessionId, launchMode: "resume" };
14724
+ const subcommands = resume?.sessionIdFromSubcommand;
14725
+ if (Array.isArray(subcommands) && subcommands.length > 0) {
14726
+ const subcommandSessionId = readSubcommandSessionId(args, subcommands);
14727
+ if (subcommandSessionId) {
14728
+ return { providerSessionId: subcommandSessionId, launchMode: "resume" };
14770
14729
  }
14771
14730
  }
14772
14731
  return { launchMode: "manual" };
@@ -14783,7 +14742,7 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
14783
14742
  if (!resume?.supported) {
14784
14743
  return { cliArgs: baseArgs, launchMode: "manual" };
14785
14744
  }
14786
- const explicit = detectExplicitProviderSessionId(normalizedType, baseArgs || []);
14745
+ const explicit = detectExplicitProviderSessionId(provider, baseArgs || []);
14787
14746
  if (explicit.providerSessionId) {
14788
14747
  return {
14789
14748
  cliArgs: baseArgs,
@@ -14791,6 +14750,12 @@ function resolveCliSessionBinding(provider, normalizedType, cliArgs, requestedRe
14791
14750
  launchMode: explicit.launchMode
14792
14751
  };
14793
14752
  }
14753
+ if (explicit.launchMode === "manual" && hasArg(baseArgs || [], ["--session-id"])) {
14754
+ return {
14755
+ cliArgs: baseArgs,
14756
+ launchMode: "manual"
14757
+ };
14758
+ }
14794
14759
  if (requestedResumeSessionId) {
14795
14760
  if (resume.sessionIdFormat === "uuid" && !isUuid(requestedResumeSessionId)) {
14796
14761
  throw new Error(`Invalid ${provider?.displayName || provider?.name || normalizedType} session ID: ${requestedResumeSessionId}`);
@@ -15495,6 +15460,11 @@ var KNOWN_PROVIDER_FIELDS = /* @__PURE__ */ new Set([
15495
15460
  "resume",
15496
15461
  "sessionProbe",
15497
15462
  "approvalPositiveHints",
15463
+ "sessionIdPattern",
15464
+ "historyBehavior",
15465
+ "canonicalHistory",
15466
+ "autoFixProfile",
15467
+ "ideLevelScripts",
15498
15468
  "scripts",
15499
15469
  "vscodeCommands",
15500
15470
  "inputMethod",
@@ -22824,20 +22794,13 @@ function tryKillAutoImplProcess(processRef, signal) {
22824
22794
  } catch {
22825
22795
  }
22826
22796
  }
22797
+ function shouldScheduleAutoStopOnQuiet(options) {
22798
+ return !!options.verification && options.autoImpl?.autoStopOnQuiet === true;
22799
+ }
22827
22800
  function getDefaultAutoImplReference(ctx, category, type) {
22828
- if (category === "cli") {
22829
- return type === "codex-cli" ? "claude-cli" : "codex-cli";
22830
- }
22831
- if (category === "extension") {
22832
- const preferred = ["claude-code-vscode", "codex", "cline", "roo-code"];
22833
- for (const ref of preferred) {
22834
- if (ref === type) continue;
22835
- if (ctx.providerLoader.resolve(ref) || ctx.providerLoader.getMeta(ref)) return ref;
22836
- }
22837
- const all = ctx.providerLoader.getAll();
22838
- const fb = all.find((p) => p.category === "extension" && p.type !== type);
22839
- if (fb?.type) return fb.type;
22840
- }
22801
+ const all = ctx.providerLoader.getAll();
22802
+ const sameCategoryOther = all.find((p) => p.category === category && p.type !== type);
22803
+ if (sameCategoryOther?.type) return sameCategoryOther.type;
22841
22804
  return "antigravity";
22842
22805
  }
22843
22806
  function resolveAutoImplReference(ctx, category, requestedReference, targetType) {
@@ -23155,37 +23118,33 @@ async function handleAutoImplement(ctx, type, req, res) {
23155
23118
  return;
23156
23119
  }
23157
23120
  const command = spawn4.command;
23121
+ const autoImpl = spawn4.autoImpl;
23158
23122
  const interactiveFlags = ["--yolo", "--interactive", "-i"];
23159
23123
  const baseArgs = [...spawn4.args || []].filter((a) => !interactiveFlags.includes(a));
23160
23124
  let shellCmd;
23161
23125
  const isWin = os19.platform() === "win32";
23162
23126
  const escapeArg = (a) => isWin ? `"${a.replace(/"/g, '""')}"` : `'${a.replace(/'/g, "'\\''")}'`;
23163
- if (command === "claude") {
23164
- const args = [...baseArgs, "--dangerously-skip-permissions"];
23127
+ const promptMode = autoImpl?.promptMode ?? "stdin";
23128
+ const extraArgs = autoImpl?.extraArgs ?? [];
23129
+ 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.`;
23130
+ if (promptMode === "flag") {
23131
+ const flag = autoImpl?.promptFlag ?? "-p";
23132
+ const args = [...baseArgs, ...extraArgs];
23165
23133
  if (model) args.push("--model", model);
23166
23134
  const escapedArgs = args.map(escapeArg).join(" ");
23167
- 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.`;
23168
- shellCmd = `${command} ${escapedArgs} -p ${escapeArg(metaPrompt)}`;
23169
- } else if (command === "gemini") {
23170
- const args = [...baseArgs, "-y", "-s", "false"];
23171
- if (model) args.push("-m", model);
23172
- const escapedArgs = args.map(escapeArg).join(" ");
23173
- const metaPrompt = `Read the file at ${promptFile} and follow ALL the instructions in it exactly. Do not ask questions, just execute.`;
23174
- shellCmd = `${command} ${escapedArgs} -p ${escapeArg(metaPrompt)}`;
23175
- } else if (command === "codex") {
23176
- const args = ["exec", ...baseArgs];
23177
- if (!args.includes("--dangerously-bypass-approvals-and-sandbox")) {
23178
- args.push("--dangerously-bypass-approvals-and-sandbox");
23179
- }
23180
- if (!args.includes("--skip-git-repo-check")) {
23181
- args.push("--skip-git-repo-check");
23135
+ shellCmd = `${command} ${escapedArgs} ${flag} ${escapeArg(rawMetaPrompt)}`;
23136
+ } else if (promptMode === "subcommand") {
23137
+ const subcommand = autoImpl?.subcommand ?? "";
23138
+ const args = subcommand ? [subcommand, ...baseArgs] : [...baseArgs];
23139
+ for (const extra of extraArgs) {
23140
+ if (!args.includes(extra)) args.push(extra);
23182
23141
  }
23183
23142
  if (model) args.push("--model", model);
23184
23143
  const escapedArgs = args.map(escapeArg).join(" ");
23185
- 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.`;
23186
- shellCmd = `${command} ${escapedArgs} ${escapeArg(metaPrompt)}`;
23144
+ shellCmd = `${command} ${escapedArgs} ${escapeArg(rawMetaPrompt)}`;
23187
23145
  } else {
23188
- const escapedArgs = baseArgs.map(escapeArg).join(" ");
23146
+ const args = [...baseArgs, ...extraArgs];
23147
+ const escapedArgs = args.map(escapeArg).join(" ");
23189
23148
  if (isWin) {
23190
23149
  shellCmd = `type "${promptFile}" | ${command} ${escapedArgs}`;
23191
23150
  } else {
@@ -23220,8 +23179,7 @@ async function handleAutoImplement(ctx, type, req, res) {
23220
23179
  stdio: ["pipe", "pipe", "pipe"],
23221
23180
  env: {
23222
23181
  ...process.env,
23223
- ...spawn4.env || {},
23224
- ...command === "gemini" ? { SANDBOX: "1", GEMINI_CLI_NO_RELAUNCH: "1" } : {}
23182
+ ...spawn4.env || {}
23225
23183
  }
23226
23184
  });
23227
23185
  child.on("error", (err2) => {
@@ -23283,7 +23241,7 @@ async function handleAutoImplement(ctx, type, req, res) {
23283
23241
  }
23284
23242
  };
23285
23243
  const scheduleAutoStopForVerification = () => {
23286
- if (!verification || command !== "codex" || completionSignalSeen || autoStopIssued) return;
23244
+ if (!shouldScheduleAutoStopOnQuiet({ verification, autoImpl }) || completionSignalSeen || autoStopIssued) return;
23287
23245
  const elapsed = Date.now() - spawnedAt;
23288
23246
  if (elapsed < 3e4) return;
23289
23247
  clearAutoStopTimer();