@adhdev/daemon-standalone 0.9.44 → 0.9.45

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
@@ -28854,6 +28854,8 @@ var require_dist2 = __commonJS({
28854
28854
  if (raw.summaryMetadata !== void 0) normalized.summaryMetadata = raw.summaryMetadata;
28855
28855
  if (Array.isArray(raw.effects)) normalized.effects = raw.effects;
28856
28856
  if (typeof raw.providerSessionId === "string") normalized.providerSessionId = raw.providerSessionId;
28857
+ if (raw.transcriptAuthority === "provider" || raw.transcriptAuthority === "daemon") normalized.transcriptAuthority = raw.transcriptAuthority;
28858
+ if (raw.coverage === "full" || raw.coverage === "tail" || raw.coverage === "current-turn") normalized.coverage = raw.coverage;
28857
28859
  return normalized;
28858
28860
  }
28859
28861
  var VALID_STATUSES;
@@ -29927,7 +29929,8 @@ var require_dist2 = __commonJS({
29927
29929
  ProviderCliAdapter: () => ProviderCliAdapter,
29928
29930
  appendBoundedText: () => appendBoundedText,
29929
29931
  normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime,
29930
- sanitizeCliStandardMessageContent: () => sanitizeCliStandardMessageContent
29932
+ sanitizeCliStandardMessageContent: () => sanitizeCliStandardMessageContent,
29933
+ trimLastAssistantEchoForCliMessages: () => trimLastAssistantEchoForCliMessages
29931
29934
  });
29932
29935
  function normalizeComparableTranscriptText(value) {
29933
29936
  return sanitizeTerminalText(String(value || "")).replace(/\s+/g, " ").trim();
@@ -30023,6 +30026,19 @@ var require_dist2 = __commonJS({
30023
30026
  if (content === message.content) return message;
30024
30027
  return { ...message, content };
30025
30028
  }
30029
+ function trimLastAssistantEchoForCliMessages(messages, prompt) {
30030
+ if (!prompt) return;
30031
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
30032
+ const message = messages[index];
30033
+ if (!message || message.role !== "assistant" || typeof message.content !== "string") continue;
30034
+ if ((message.kind || "standard") !== "standard") continue;
30035
+ message.content = trimPromptEchoPrefix(message.content, prompt);
30036
+ if (!message.content.trim()) {
30037
+ messages.splice(index, 1);
30038
+ }
30039
+ return;
30040
+ }
30041
+ }
30026
30042
  var os10;
30027
30043
  var COMMITTED_ACTIVITY_PREFIX_BLOCK_RE;
30028
30044
  var ProviderCliAdapter;
@@ -30222,7 +30238,14 @@ var require_dist2 = __commonJS({
30222
30238
  }
30223
30239
  return null;
30224
30240
  }
30241
+ providerOwnsTranscript() {
30242
+ return this.provider.transcriptAuthority === "provider";
30243
+ }
30244
+ shouldUseFullProviderTranscriptContext() {
30245
+ return this.providerOwnsTranscript() && this.provider.transcriptContext === "full";
30246
+ }
30225
30247
  selectParseBaseMessages(baseMessages) {
30248
+ if (this.shouldUseFullProviderTranscriptContext()) return baseMessages;
30226
30249
  if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
30227
30250
  return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
30228
30251
  }
@@ -30705,9 +30728,7 @@ var require_dist2 = __commonJS({
30705
30728
  );
30706
30729
  }
30707
30730
  trimLastAssistantEcho(messages, prompt) {
30708
- if (!prompt) return;
30709
- const last = [...messages].reverse().find((m) => m.role === "assistant" && typeof m.content === "string");
30710
- if (last) last.content = trimPromptEchoPrefix(last.content, prompt);
30731
+ trimLastAssistantEchoForCliMessages(messages, prompt);
30711
30732
  }
30712
30733
  clearAllTimers() {
30713
30734
  if (this.responseTimeout) {
@@ -31561,7 +31582,8 @@ var require_dist2 = __commonJS({
31561
31582
  title: parsed.title || this.cliName,
31562
31583
  messages: hydratedMessages,
31563
31584
  activeModal: parsed.activeModal ?? this.activeModal,
31564
- providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0
31585
+ providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0,
31586
+ ...this.providerOwnsTranscript() ? { transcriptAuthority: "provider", coverage: this.shouldUseFullProviderTranscriptContext() ? "full" : "tail" } : {}
31565
31587
  };
31566
31588
  } else {
31567
31589
  const messages = [...this.committedMessages];
@@ -35857,6 +35879,27 @@ ${cleanBody}`;
35857
35879
  return name.replace(/[^a-zA-Z0-9_-]/g, "_");
35858
35880
  }
35859
35881
  };
35882
+ function pageHistoryRecords(agentType, records, offset = 0, limit = 30, excludeRecentCount = 0, historyBehavior) {
35883
+ const allMessages = records.map((message) => sanitizeHistoryMessage(agentType, message)).filter(Boolean);
35884
+ allMessages.sort((a, b2) => a.receivedAt - b2.receivedAt);
35885
+ const chronological = [];
35886
+ let lastTurn = null;
35887
+ for (const message of allMessages) {
35888
+ const previous = chronological[chronological.length - 1];
35889
+ if (isAdjacentHistoryDuplicate(agentType, previous, message)) continue;
35890
+ if (message.role !== "system" && isAdjacentHistoryDuplicate(agentType, lastTurn, message)) continue;
35891
+ chronological.push(message);
35892
+ if (message.role !== "system") lastTurn = message;
35893
+ }
35894
+ const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
35895
+ const boundedLimit = Math.max(1, limit);
35896
+ const boundedOffset = Math.max(0, offset);
35897
+ const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
35898
+ const endExclusive = Math.max(0, collapsed.length - boundedExclude - boundedOffset);
35899
+ const startInclusive = Math.max(0, endExclusive - boundedLimit);
35900
+ const sliced = collapsed.slice(startInclusive, endExclusive);
35901
+ return { messages: sliced, hasMore: startInclusive > 0 };
35902
+ }
35860
35903
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
35861
35904
  try {
35862
35905
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
@@ -35882,25 +35925,7 @@ ${cleanBody}`;
35882
35925
  }
35883
35926
  }
35884
35927
  }
35885
- allMessages.sort((a, b2) => a.receivedAt - b2.receivedAt);
35886
- const chronological = [];
35887
- let lastTurn = null;
35888
- for (const message of allMessages) {
35889
- const previous = chronological[chronological.length - 1];
35890
- if (isAdjacentHistoryDuplicate(agentType, previous, message)) continue;
35891
- if (message.role !== "system" && isAdjacentHistoryDuplicate(agentType, lastTurn, message)) continue;
35892
- chronological.push(message);
35893
- if (message.role !== "system") lastTurn = message;
35894
- }
35895
- const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
35896
- const boundedLimit = Math.max(1, limit);
35897
- const boundedOffset = Math.max(0, offset);
35898
- const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
35899
- const endExclusive = Math.max(0, collapsed.length - boundedExclude - boundedOffset);
35900
- const startInclusive = Math.max(0, endExclusive - boundedLimit);
35901
- const sliced = collapsed.slice(startInclusive, endExclusive);
35902
- const hasMore = startInclusive > 0;
35903
- return { messages: sliced, hasMore };
35928
+ return pageHistoryRecords(agentType, allMessages, offset, limit, excludeRecentCount, historyBehavior);
35904
35929
  } catch {
35905
35930
  return { messages: [], hasMore: false };
35906
35931
  }
@@ -36035,6 +36060,52 @@ ${cleanBody}`;
36035
36060
  return false;
36036
36061
  }
36037
36062
  }
36063
+ function buildHermesNativeHistoryRecords(historySessionId) {
36064
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36065
+ if (!normalizedSessionId) return null;
36066
+ try {
36067
+ const sessionFilePath = path7.join(os52.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
36068
+ if (!fs32.existsSync(sessionFilePath)) return null;
36069
+ const raw = JSON.parse(fs32.readFileSync(sessionFilePath, "utf-8"));
36070
+ const canonicalMessages = Array.isArray(raw.messages) ? raw.messages : [];
36071
+ const records = [];
36072
+ let fallbackTs = Date.parse(raw.session_start || raw.last_updated || "") || Date.now();
36073
+ for (const message of canonicalMessages) {
36074
+ const role = String(message.role || "").trim();
36075
+ const content = normalizeCanonicalHermesMessageContent(message.content);
36076
+ if (!content) continue;
36077
+ const receivedAt = extractCanonicalHermesMessageTimestamp(message, fallbackTs);
36078
+ fallbackTs = receivedAt + 1;
36079
+ if (role === "user" || role === "assistant") {
36080
+ records.push({
36081
+ ts: new Date(receivedAt).toISOString(),
36082
+ receivedAt,
36083
+ role,
36084
+ content,
36085
+ kind: "standard",
36086
+ agent: "hermes-cli",
36087
+ historySessionId: normalizedSessionId
36088
+ });
36089
+ continue;
36090
+ }
36091
+ if (role === "tool") {
36092
+ records.push({
36093
+ ts: new Date(receivedAt).toISOString(),
36094
+ receivedAt,
36095
+ role: "assistant",
36096
+ content,
36097
+ kind: "tool",
36098
+ senderName: "Tool",
36099
+ agent: "hermes-cli",
36100
+ historySessionId: normalizedSessionId
36101
+ });
36102
+ }
36103
+ }
36104
+ return records;
36105
+ } catch {
36106
+ return null;
36107
+ }
36108
+ }
36038
36109
  function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
36039
36110
  const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36040
36111
  if (!normalizedSessionId) return false;
@@ -36184,6 +36255,77 @@ ${cleanBody}`;
36184
36255
  }
36185
36256
  return parts;
36186
36257
  }
36258
+ function buildClaudeNativeHistoryRecords(historySessionId, workspace) {
36259
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36260
+ if (!normalizedSessionId) return null;
36261
+ try {
36262
+ const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
36263
+ if (!transcriptPath) return null;
36264
+ const lines = fs32.readFileSync(transcriptPath, "utf-8").split("\n").filter(Boolean);
36265
+ const records = [];
36266
+ let fallbackTs = Date.now();
36267
+ for (const line of lines) {
36268
+ let parsed = null;
36269
+ try {
36270
+ parsed = JSON.parse(line);
36271
+ } catch {
36272
+ parsed = null;
36273
+ }
36274
+ if (!parsed) continue;
36275
+ const parsedSessionId = String(parsed.sessionId || "").trim();
36276
+ if (parsedSessionId && parsedSessionId !== normalizedSessionId) continue;
36277
+ const receivedAt = extractTimestampValue(parsed.timestamp) || fallbackTs;
36278
+ fallbackTs = receivedAt + 1;
36279
+ const parsedWorkspace = String(parsed.cwd || workspace || "").trim();
36280
+ if (records.length === 0 && parsedWorkspace) {
36281
+ records.push({
36282
+ ts: new Date(receivedAt).toISOString(),
36283
+ receivedAt,
36284
+ role: "system",
36285
+ kind: "session_start",
36286
+ content: parsedWorkspace,
36287
+ agent: "claude-cli",
36288
+ historySessionId: normalizedSessionId,
36289
+ workspace: parsedWorkspace
36290
+ });
36291
+ }
36292
+ const type = String(parsed.type || "").trim();
36293
+ const message = parsed.message && typeof parsed.message === "object" ? parsed.message : null;
36294
+ if (type === "user" && message) {
36295
+ for (const part of extractClaudeUserContentParts(message.content)) {
36296
+ records.push({
36297
+ ts: new Date(receivedAt).toISOString(),
36298
+ receivedAt,
36299
+ role: part.role,
36300
+ content: part.content,
36301
+ kind: part.kind,
36302
+ senderName: part.senderName,
36303
+ agent: "claude-cli",
36304
+ historySessionId: normalizedSessionId
36305
+ });
36306
+ }
36307
+ continue;
36308
+ }
36309
+ if (type === "assistant" && message) {
36310
+ for (const part of extractClaudeAssistantContentParts(message.content)) {
36311
+ records.push({
36312
+ ts: new Date(receivedAt).toISOString(),
36313
+ receivedAt,
36314
+ role: "assistant",
36315
+ content: part.content,
36316
+ kind: part.kind,
36317
+ senderName: part.senderName,
36318
+ agent: "claude-cli",
36319
+ historySessionId: normalizedSessionId
36320
+ });
36321
+ }
36322
+ }
36323
+ }
36324
+ return records;
36325
+ } catch {
36326
+ return null;
36327
+ }
36328
+ }
36187
36329
  function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
36188
36330
  const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36189
36331
  if (!normalizedSessionId) return false;
@@ -36262,6 +36404,352 @@ ${cleanBody}`;
36262
36404
  return false;
36263
36405
  }
36264
36406
  }
36407
+ function isUuidLikeSessionId(sessionId) {
36408
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(sessionId);
36409
+ }
36410
+ function readCodexSessionMeta(filePath) {
36411
+ try {
36412
+ const firstLine = fs32.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
36413
+ if (!firstLine) return null;
36414
+ const parsed = JSON.parse(firstLine);
36415
+ if (String(parsed.type || "") !== "session_meta") return null;
36416
+ const payload = parsed.payload && typeof parsed.payload === "object" ? parsed.payload : null;
36417
+ return payload;
36418
+ } catch {
36419
+ return null;
36420
+ }
36421
+ }
36422
+ function resolveCodexSessionTranscriptPath(historySessionId, workspace) {
36423
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36424
+ if (!normalizedSessionId || !isUuidLikeSessionId(normalizedSessionId)) return null;
36425
+ const sessionsDir = path7.join(os52.homedir(), ".codex", "sessions");
36426
+ if (!fs32.existsSync(sessionsDir)) return null;
36427
+ const normalizedWorkspace = typeof workspace === "string" ? workspace.trim() : "";
36428
+ const candidates = [];
36429
+ const stack = [sessionsDir];
36430
+ while (stack.length > 0) {
36431
+ const current = stack.pop();
36432
+ if (!current) continue;
36433
+ let entries = [];
36434
+ try {
36435
+ entries = fs32.readdirSync(current, { withFileTypes: true });
36436
+ } catch {
36437
+ continue;
36438
+ }
36439
+ for (const entry of entries) {
36440
+ const entryPath = path7.join(current, entry.name);
36441
+ if (entry.isDirectory()) {
36442
+ stack.push(entryPath);
36443
+ continue;
36444
+ }
36445
+ if (!entry.isFile() || !entry.name.endsWith(".jsonl") || !entry.name.includes(normalizedSessionId)) continue;
36446
+ const meta3 = readCodexSessionMeta(entryPath);
36447
+ const metaSessionId = String(meta3?.id || "").trim();
36448
+ if (metaSessionId && metaSessionId !== normalizedSessionId) continue;
36449
+ const metaWorkspace = String(meta3?.cwd || "").trim();
36450
+ let mtimeMs = 0;
36451
+ try {
36452
+ mtimeMs = fs32.statSync(entryPath).mtimeMs;
36453
+ } catch {
36454
+ }
36455
+ candidates.push({
36456
+ path: entryPath,
36457
+ mtimeMs,
36458
+ workspaceMatches: !!normalizedWorkspace && metaWorkspace === normalizedWorkspace,
36459
+ metaMatches: metaSessionId === normalizedSessionId
36460
+ });
36461
+ }
36462
+ }
36463
+ candidates.sort((a, b2) => Number(b2.workspaceMatches) - Number(a.workspaceMatches) || Number(b2.metaMatches) - Number(a.metaMatches) || b2.mtimeMs - a.mtimeMs);
36464
+ return candidates[0]?.path || null;
36465
+ }
36466
+ function flattenCodexContent(content) {
36467
+ if (typeof content === "string") return content.trim();
36468
+ if (content == null) return "";
36469
+ if (Array.isArray(content)) {
36470
+ return content.map((entry) => flattenCodexContent(entry)).filter(Boolean).join("\n").trim();
36471
+ }
36472
+ if (typeof content === "object") {
36473
+ const record2 = content;
36474
+ if (typeof record2.text === "string") return record2.text.trim();
36475
+ if (typeof record2.content === "string" || Array.isArray(record2.content)) return flattenCodexContent(record2.content);
36476
+ if (typeof record2.output === "string") return record2.output.trim();
36477
+ if (typeof record2.message === "string") return record2.message.trim();
36478
+ }
36479
+ return "";
36480
+ }
36481
+ function summarizeCodexToolCall(payload) {
36482
+ const name = String(payload.name || payload.type || "tool").trim() || "tool";
36483
+ const rawArguments = payload.arguments ?? payload.input;
36484
+ let argumentValue = "";
36485
+ if (typeof rawArguments === "string") {
36486
+ const trimmed = rawArguments.trim();
36487
+ try {
36488
+ const parsed = JSON.parse(trimmed);
36489
+ argumentValue = summarizeCodexToolArguments(parsed);
36490
+ } catch {
36491
+ argumentValue = trimmed;
36492
+ }
36493
+ } else {
36494
+ argumentValue = summarizeCodexToolArguments(rawArguments);
36495
+ }
36496
+ return argumentValue ? `${name}: ${argumentValue}` : name;
36497
+ }
36498
+ function summarizeCodexToolArguments(value) {
36499
+ if (typeof value === "string") return value.trim();
36500
+ if (Array.isArray(value)) return value.map((entry) => String(entry)).join(" ").trim();
36501
+ if (!value || typeof value !== "object") return "";
36502
+ const record2 = value;
36503
+ const direct = record2.command || record2.cmd || record2.query || record2.path || record2.prompt;
36504
+ if (typeof direct === "string") return direct.trim();
36505
+ if (Array.isArray(direct)) return direct.map((entry) => String(entry)).join(" ").trim();
36506
+ try {
36507
+ return JSON.stringify(record2).trim();
36508
+ } catch {
36509
+ return "";
36510
+ }
36511
+ }
36512
+ function codexToolOutputContent(payload) {
36513
+ const output = payload.output ?? payload.result ?? payload.content;
36514
+ const text = flattenCodexContent(output);
36515
+ if (text) return text;
36516
+ if (output && typeof output === "object") {
36517
+ try {
36518
+ return JSON.stringify(output).trim();
36519
+ } catch {
36520
+ return "";
36521
+ }
36522
+ }
36523
+ return "";
36524
+ }
36525
+ function buildCodexNativeHistoryRecords(historySessionId, workspace) {
36526
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36527
+ if (!normalizedSessionId || !isUuidLikeSessionId(normalizedSessionId)) return null;
36528
+ try {
36529
+ const transcriptPath = resolveCodexSessionTranscriptPath(normalizedSessionId, workspace);
36530
+ if (!transcriptPath) return null;
36531
+ const lines = fs32.readFileSync(transcriptPath, "utf-8").split("\n").filter(Boolean);
36532
+ const records = [];
36533
+ let fallbackTs = Date.now();
36534
+ for (const line of lines) {
36535
+ let parsed = null;
36536
+ try {
36537
+ parsed = JSON.parse(line);
36538
+ } catch {
36539
+ parsed = null;
36540
+ }
36541
+ if (!parsed) continue;
36542
+ const receivedAt = extractTimestampValue(parsed.timestamp) || fallbackTs;
36543
+ fallbackTs = receivedAt + 1;
36544
+ const type = String(parsed.type || "").trim();
36545
+ const payload = parsed.payload && typeof parsed.payload === "object" ? parsed.payload : null;
36546
+ if (!payload) continue;
36547
+ if (type === "session_meta") {
36548
+ const parsedSessionId = String(payload.id || "").trim();
36549
+ if (parsedSessionId && parsedSessionId !== normalizedSessionId) return null;
36550
+ const parsedWorkspace = String(payload.cwd || workspace || "").trim();
36551
+ if (records.length === 0 && parsedWorkspace) {
36552
+ records.push({
36553
+ ts: new Date(receivedAt).toISOString(),
36554
+ receivedAt,
36555
+ role: "system",
36556
+ kind: "session_start",
36557
+ content: parsedWorkspace,
36558
+ agent: "codex-cli",
36559
+ historySessionId: normalizedSessionId,
36560
+ workspace: parsedWorkspace
36561
+ });
36562
+ }
36563
+ continue;
36564
+ }
36565
+ if (type !== "response_item") continue;
36566
+ const payloadType = String(payload.type || "").trim();
36567
+ if (payloadType === "message") {
36568
+ const role = String(payload.role || "").trim();
36569
+ if (role !== "user" && role !== "assistant") continue;
36570
+ const content = flattenCodexContent(payload.content);
36571
+ if (!content) continue;
36572
+ records.push({
36573
+ ts: new Date(receivedAt).toISOString(),
36574
+ receivedAt,
36575
+ role,
36576
+ content,
36577
+ kind: "standard",
36578
+ agent: "codex-cli",
36579
+ historySessionId: normalizedSessionId
36580
+ });
36581
+ continue;
36582
+ }
36583
+ if (payloadType === "function_call" || payloadType === "custom_tool_call") {
36584
+ const content = summarizeCodexToolCall(payload);
36585
+ if (!content) continue;
36586
+ records.push({
36587
+ ts: new Date(receivedAt).toISOString(),
36588
+ receivedAt,
36589
+ role: "assistant",
36590
+ content,
36591
+ kind: "tool",
36592
+ senderName: "Tool",
36593
+ agent: "codex-cli",
36594
+ historySessionId: normalizedSessionId
36595
+ });
36596
+ continue;
36597
+ }
36598
+ if (payloadType === "function_call_output" || payloadType === "custom_tool_call_output") {
36599
+ const content = codexToolOutputContent(payload);
36600
+ if (!content) continue;
36601
+ records.push({
36602
+ ts: new Date(receivedAt).toISOString(),
36603
+ receivedAt,
36604
+ role: "assistant",
36605
+ content,
36606
+ kind: "tool",
36607
+ senderName: "Tool",
36608
+ agent: "codex-cli",
36609
+ historySessionId: normalizedSessionId
36610
+ });
36611
+ }
36612
+ }
36613
+ return records;
36614
+ } catch {
36615
+ return null;
36616
+ }
36617
+ }
36618
+ function rebuildCodexSavedHistoryFromNativeSession(historySessionId, workspace) {
36619
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36620
+ if (!normalizedSessionId || !isUuidLikeSessionId(normalizedSessionId)) return false;
36621
+ const records = buildCodexNativeHistoryRecords(normalizedSessionId, workspace);
36622
+ if (!records || records.length === 0) return false;
36623
+ const existingSessionStart = readExistingSessionStartRecord("codex-cli", normalizedSessionId);
36624
+ const recordsToWrite = existingSessionStart && records[0]?.kind !== "session_start" ? [{ ...existingSessionStart, historySessionId: normalizedSessionId }, ...records] : records;
36625
+ return rewriteCanonicalSavedHistory("codex-cli", normalizedSessionId, recordsToWrite);
36626
+ }
36627
+ function isNativeSourceCanonicalHistory(canonicalHistory) {
36628
+ if (!canonicalHistory) return false;
36629
+ if (canonicalHistory.mode === "disabled") return false;
36630
+ if (canonicalHistory.mode === "materialized-mirror") return false;
36631
+ return true;
36632
+ }
36633
+ function buildNativeHistoryRecords(canonicalHistory, historySessionId, workspace) {
36634
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || "");
36635
+ if (!canonicalHistory || !normalizedSessionId || !isNativeSourceCanonicalHistory(canonicalHistory)) return null;
36636
+ if (canonicalHistory.format === "hermes-json") return buildHermesNativeHistoryRecords(normalizedSessionId);
36637
+ if (canonicalHistory.format === "claude-jsonl") return buildClaudeNativeHistoryRecords(normalizedSessionId, workspace);
36638
+ if (canonicalHistory.format === "codex-jsonl") return buildCodexNativeHistoryRecords(normalizedSessionId, workspace);
36639
+ return null;
36640
+ }
36641
+ function readProviderChatHistory(agentType, options = {}) {
36642
+ if (isNativeSourceCanonicalHistory(options.canonicalHistory) && options.historySessionId) {
36643
+ const records = buildNativeHistoryRecords(options.canonicalHistory, options.historySessionId, options.workspace);
36644
+ if (!records) return { messages: [], hasMore: false, source: "native-unavailable" };
36645
+ return {
36646
+ ...pageHistoryRecords(agentType, records, options.offset || 0, options.limit || 30, options.excludeRecentCount || 0, options.historyBehavior),
36647
+ source: "provider-native"
36648
+ };
36649
+ }
36650
+ return {
36651
+ ...readChatHistory(agentType, options.offset || 0, options.limit || 30, options.historySessionId, options.excludeRecentCount || 0, options.historyBehavior),
36652
+ source: "adhdev-mirror"
36653
+ };
36654
+ }
36655
+ function buildNativeSessionSummary(agentType, historySessionId, records, sourcePath) {
36656
+ const visible = pageHistoryRecords(agentType, records, 0, Number.MAX_SAFE_INTEGER).messages;
36657
+ if (visible.length === 0) return null;
36658
+ let sourceMtimeMs = 0;
36659
+ try {
36660
+ sourceMtimeMs = fs32.statSync(sourcePath).mtimeMs;
36661
+ } catch {
36662
+ }
36663
+ const firstMessageAt = visible[0]?.receivedAt || sourceMtimeMs || Date.now();
36664
+ const lastMessageAt = visible[visible.length - 1]?.receivedAt || firstMessageAt;
36665
+ const lastNonSystem = [...visible].reverse().find((message) => message.role !== "system") || visible[visible.length - 1];
36666
+ const firstSystem = visible.find((message) => message.kind === "session_start");
36667
+ return {
36668
+ historySessionId,
36669
+ sessionTitle: lastNonSystem?.content,
36670
+ messageCount: visible.length,
36671
+ firstMessageAt,
36672
+ lastMessageAt,
36673
+ preview: lastNonSystem?.content,
36674
+ workspace: firstSystem?.workspace || (firstSystem?.kind === "session_start" ? firstSystem.content : void 0),
36675
+ source: "provider-native",
36676
+ sourcePath,
36677
+ sourceMtimeMs
36678
+ };
36679
+ }
36680
+ function listFilesRecursive(root, predicate) {
36681
+ if (!fs32.existsSync(root)) return [];
36682
+ const results = [];
36683
+ const stack = [root];
36684
+ while (stack.length > 0) {
36685
+ const current = stack.pop();
36686
+ if (!current) continue;
36687
+ let entries = [];
36688
+ try {
36689
+ entries = fs32.readdirSync(current, { withFileTypes: true });
36690
+ } catch {
36691
+ continue;
36692
+ }
36693
+ for (const entry of entries) {
36694
+ const entryPath = path7.join(current, entry.name);
36695
+ if (entry.isDirectory()) {
36696
+ stack.push(entryPath);
36697
+ continue;
36698
+ }
36699
+ if (predicate(entryPath, entry)) results.push(entryPath);
36700
+ }
36701
+ }
36702
+ return results;
36703
+ }
36704
+ function collectNativeHistorySessionSummaries(agentType, canonicalHistory) {
36705
+ const summaries = [];
36706
+ if (canonicalHistory.format === "hermes-json") {
36707
+ const root = path7.join(os52.homedir(), ".hermes", "sessions");
36708
+ for (const filePath of listFilesRecursive(root, (_entryPath, entry) => entry.isFile() && /^session_.+\.json$/.test(entry.name))) {
36709
+ const fileName = path7.basename(filePath);
36710
+ const historySessionId = fileName.replace(/^session_/, "").replace(/\.json$/, "");
36711
+ const records = buildHermesNativeHistoryRecords(historySessionId);
36712
+ const summary = records ? buildNativeSessionSummary(agentType, historySessionId, records, filePath) : null;
36713
+ if (summary) summaries.push(summary);
36714
+ }
36715
+ } else if (canonicalHistory.format === "claude-jsonl") {
36716
+ const root = path7.join(os52.homedir(), ".claude", "projects");
36717
+ for (const filePath of listFilesRecursive(root, (_entryPath, entry) => entry.isFile() && entry.name.endsWith(".jsonl"))) {
36718
+ const historySessionId = path7.basename(filePath, ".jsonl");
36719
+ const records = buildClaudeNativeHistoryRecords(historySessionId);
36720
+ const summary = records ? buildNativeSessionSummary(agentType, historySessionId, records, filePath) : null;
36721
+ if (summary) summaries.push(summary);
36722
+ }
36723
+ } else if (canonicalHistory.format === "codex-jsonl") {
36724
+ const root = path7.join(os52.homedir(), ".codex", "sessions");
36725
+ const uuidPattern = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
36726
+ for (const filePath of listFilesRecursive(root, (_entryPath, entry) => entry.isFile() && entry.name.endsWith(".jsonl"))) {
36727
+ const meta3 = readCodexSessionMeta(filePath);
36728
+ const historySessionId = String(meta3?.id || path7.basename(filePath).match(uuidPattern)?.[1] || "").trim();
36729
+ if (!historySessionId) continue;
36730
+ const records = buildCodexNativeHistoryRecords(historySessionId, String(meta3?.cwd || "").trim() || void 0);
36731
+ const summary = records ? buildNativeSessionSummary(agentType, historySessionId, records, filePath) : null;
36732
+ if (summary) summaries.push(summary);
36733
+ }
36734
+ }
36735
+ return sortSavedHistorySessionSummaries(summaries);
36736
+ }
36737
+ function listProviderHistorySessions(agentType, options = {}) {
36738
+ if (isNativeSourceCanonicalHistory(options.canonicalHistory)) {
36739
+ const offset = Math.max(0, options.offset || 0);
36740
+ const limit = Math.max(1, options.limit || 30);
36741
+ const summaries = collectNativeHistorySessionSummaries(agentType, options.canonicalHistory);
36742
+ return {
36743
+ sessions: summaries.slice(offset, offset + limit),
36744
+ hasMore: offset + limit < summaries.length,
36745
+ source: "provider-native"
36746
+ };
36747
+ }
36748
+ return {
36749
+ ...listSavedHistorySessions(agentType, { offset: options.offset, limit: options.limit }, options.historyBehavior),
36750
+ source: "adhdev-mirror"
36751
+ };
36752
+ }
36265
36753
  function isControlValue(value) {
36266
36754
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
36267
36755
  }
@@ -38829,7 +39317,16 @@ ${effect.notification.body || ""}`.trim();
38829
39317
  const visibleCount = Array.isArray(status?.messages) ? status.messages.length : 0;
38830
39318
  if (visibleCount > excludeRecentCount) excludeRecentCount = visibleCount;
38831
39319
  }
38832
- const result = readChatHistory(agentStr, offset || 0, limit || 30, historySessionId, excludeRecentCount);
39320
+ const workspace = typeof args?.workspace === "string" ? args.workspace : typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : void 0;
39321
+ const result = readProviderChatHistory(agentStr, {
39322
+ canonicalHistory: provider?.canonicalHistory,
39323
+ historySessionId,
39324
+ workspace,
39325
+ offset: offset || 0,
39326
+ limit: limit || 30,
39327
+ excludeRecentCount,
39328
+ historyBehavior: provider?.historyBehavior
39329
+ });
38833
39330
  return { success: true, ...result, agent: agentStr };
38834
39331
  } catch (e) {
38835
39332
  return { success: false, error: e.message };
@@ -38854,7 +39351,8 @@ ${effect.notification.body || ""}`.trim();
38854
39351
  }
38855
39352
  const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
38856
39353
  const adapterStatus = adapter.getStatus();
38857
- const shouldPreferAdapterMessages = Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
39354
+ const parsedIsProviderAuthoritative = parsedRecord?.transcriptAuthority === "provider" || parsedRecord?.coverage === "full";
39355
+ const shouldPreferAdapterMessages = !parsedIsProviderAuthoritative && Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
38858
39356
  const parsedShowsApproval = hasNonEmptyModalButtons(parsedRecord?.activeModal) && parsedRecord?.status === "waiting_approval";
38859
39357
  const status = parsedRecord ? {
38860
39358
  ...parsedRecord,
@@ -38864,6 +39362,8 @@ ${effect.notification.body || ""}`.trim();
38864
39362
  } : adapterStatus;
38865
39363
  const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
38866
39364
  const providerSessionId = typeof parsedRecord?.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
39365
+ const transcriptAuthority = parsedRecord?.transcriptAuthority === "provider" || parsedRecord?.transcriptAuthority === "daemon" ? parsedRecord.transcriptAuthority : void 0;
39366
+ const coverage = parsedRecord?.coverage === "full" || parsedRecord?.coverage === "tail" || parsedRecord?.coverage === "current-turn" ? parsedRecord.coverage : void 0;
38867
39367
  if (status) {
38868
39368
  LOG2.debug("Command", `[read_chat] cli-like resolved provider=${adapter.cliType} target=${String(args?.targetSessionId || "")} adapterStatus=${String(adapterStatus.status || "")} parsedStatus=${String(parsedRecord?.status || "")} shouldPreferAdapterMessages=${String(shouldPreferAdapterMessages)} adapterMsgCount=${Array.isArray(adapterStatus.messages) ? adapterStatus.messages.length : 0} parsedMsgCount=${Array.isArray(parsedRecord?.messages) ? parsedRecord.messages.length : 0} returnedMsgCount=${Array.isArray(status.messages) ? status.messages.length : 0}`);
38869
39369
  return buildReadChatCommandResult({
@@ -38882,7 +39382,9 @@ ${effect.notification.body || ""}`.trim();
38882
39382
  returnedMsgCount: Array.isArray(status.messages) ? status.messages.length : 0
38883
39383
  },
38884
39384
  ...title ? { title } : {},
38885
- ...providerSessionId ? { providerSessionId } : {}
39385
+ ...providerSessionId ? { providerSessionId } : {},
39386
+ ...transcriptAuthority ? { transcriptAuthority } : {},
39387
+ ...coverage ? { coverage } : {}
38886
39388
  }, args);
38887
39389
  }
38888
39390
  }
@@ -41280,6 +41782,8 @@ ${effect.notification.body || ""}`.trim();
41280
41782
  lastCanonicalHermesWatchPath = void 0;
41281
41783
  lastCanonicalClaudeRebuildMtimeMs = 0;
41282
41784
  lastCanonicalClaudeCheckAt = 0;
41785
+ lastCanonicalCodexRebuildMtimeMs = 0;
41786
+ lastCanonicalCodexCheckAt = 0;
41283
41787
  cachedSqliteDb = null;
41284
41788
  cachedSqliteDbPath = null;
41285
41789
  cachedSqliteDbMissingUntil = 0;
@@ -41979,6 +42483,25 @@ ${effect.notification.body || ""}`.trim();
41979
42483
  if (!this.providerSessionId) return false;
41980
42484
  const canonicalHistory = this.provider.canonicalHistory;
41981
42485
  if (!canonicalHistory) return false;
42486
+ if (isNativeSourceCanonicalHistory(canonicalHistory)) {
42487
+ const restoredHistory = readProviderChatHistory(this.type, {
42488
+ canonicalHistory,
42489
+ historySessionId: this.providerSessionId,
42490
+ workspace: this.workingDir,
42491
+ offset: 0,
42492
+ limit: Number.MAX_SAFE_INTEGER,
42493
+ historyBehavior: this.provider.historyBehavior
42494
+ });
42495
+ if (restoredHistory.source !== "provider-native") return false;
42496
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
42497
+ role: message.role,
42498
+ content: message.content,
42499
+ kind: message.kind,
42500
+ senderName: message.senderName,
42501
+ receivedAt: message.receivedAt
42502
+ }));
42503
+ return true;
42504
+ }
41982
42505
  try {
41983
42506
  let rebuilt = false;
41984
42507
  if (canonicalHistory.format === "hermes-json") {
@@ -42012,6 +42535,23 @@ ${effect.notification.body || ""}`.trim();
42012
42535
  if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalClaudeRebuildMtimeMs) return true;
42013
42536
  rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
42014
42537
  if (rebuilt) this.lastCanonicalClaudeRebuildMtimeMs = transcriptMtime || Date.now();
42538
+ } else if (canonicalHistory.format === "codex-jsonl") {
42539
+ const now = Date.now();
42540
+ if (now - this.lastCanonicalCodexCheckAt < 2e3 && this.lastCanonicalCodexRebuildMtimeMs !== 0) {
42541
+ return true;
42542
+ }
42543
+ this.lastCanonicalCodexCheckAt = now;
42544
+ const transcriptFile = resolveCodexSessionTranscriptPath(this.providerSessionId, this.workingDir);
42545
+ let transcriptMtime = 0;
42546
+ if (transcriptFile) {
42547
+ try {
42548
+ transcriptMtime = fs52.statSync(transcriptFile).mtimeMs;
42549
+ } catch {
42550
+ }
42551
+ }
42552
+ if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalCodexRebuildMtimeMs) return true;
42553
+ rebuilt = rebuildCodexSavedHistoryFromNativeSession(this.providerSessionId, this.workingDir);
42554
+ if (rebuilt) this.lastCanonicalCodexRebuildMtimeMs = transcriptMtime || Date.now();
42015
42555
  }
42016
42556
  if (!rebuilt) return false;
42017
42557
  const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
@@ -42030,8 +42570,17 @@ ${effect.notification.body || ""}`.trim();
42030
42570
  restorePersistedHistoryFromCurrentSession() {
42031
42571
  if (!this.providerSessionId) return;
42032
42572
  this.syncCanonicalSavedHistoryIfNeeded();
42033
- this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
42034
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
42573
+ const restoredHistory = isNativeSourceCanonicalHistory(this.provider.canonicalHistory) ? readProviderChatHistory(this.type, {
42574
+ canonicalHistory: this.provider.canonicalHistory,
42575
+ historySessionId: this.providerSessionId,
42576
+ workspace: this.workingDir,
42577
+ offset: 0,
42578
+ limit: Number.MAX_SAFE_INTEGER,
42579
+ historyBehavior: this.provider.historyBehavior
42580
+ }) : (() => {
42581
+ this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
42582
+ return readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
42583
+ })();
42035
42584
  this.historyWriter.seedSessionHistory(
42036
42585
  this.type,
42037
42586
  restoredHistory.messages,
@@ -45744,6 +46293,36 @@ Run 'adhdev doctor' for detailed diagnostics.`
45744
46293
  return 0;
45745
46294
  }
45746
46295
  };
46296
+ function normalizeMacAppPath(appPath) {
46297
+ const trimmed = String(appPath || "").trim();
46298
+ if (!trimmed) return null;
46299
+ return trimmed.replace(/\/+$/, "");
46300
+ }
46301
+ function parsePsLine(line) {
46302
+ const match = line.match(/^\s*(\d+)\s+(.+)$/);
46303
+ if (!match) return null;
46304
+ const pid = Number.parseInt(match[1], 10);
46305
+ if (!Number.isFinite(pid)) return null;
46306
+ return { pid, args: match[2] };
46307
+ }
46308
+ function isMacAppProcessArgs(args, appPath) {
46309
+ const normalized = normalizeMacAppPath(appPath);
46310
+ if (!normalized) return false;
46311
+ return String(args || "").startsWith(`${normalized}/`);
46312
+ }
46313
+ function findMacAppProcessPids(psOutput, appPaths) {
46314
+ const normalizedPaths = appPaths.map(normalizeMacAppPath).filter((value) => !!value);
46315
+ if (normalizedPaths.length === 0) return [];
46316
+ const pids = [];
46317
+ for (const line of String(psOutput || "").split(/\r?\n/)) {
46318
+ const parsed = parsePsLine(line);
46319
+ if (!parsed) continue;
46320
+ if (normalizedPaths.some((appPath) => isMacAppProcessArgs(parsed.args, appPath))) {
46321
+ pids.push(parsed.pid);
46322
+ }
46323
+ }
46324
+ return pids;
46325
+ }
45747
46326
  var _providerLoader = null;
45748
46327
  function getProviderLoader() {
45749
46328
  if (!_providerLoader) {
@@ -45779,6 +46358,35 @@ Run 'adhdev doctor' for detailed diagnostics.`
45779
46358
  function escapeForAppleScript(value) {
45780
46359
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
45781
46360
  }
46361
+ function getIdePathCandidates(ideId) {
46362
+ return getProviderLoader().getIdePathCandidates(ideId);
46363
+ }
46364
+ function getMacAppProcessPids(ideId) {
46365
+ const appPaths = getIdePathCandidates(ideId);
46366
+ if (appPaths.length === 0) return [];
46367
+ try {
46368
+ const output = (0, import_child_process7.execSync)("ps axww -o pid=,args=", {
46369
+ encoding: "utf-8",
46370
+ timeout: 3e3,
46371
+ stdio: ["pipe", "pipe", "pipe"]
46372
+ });
46373
+ return findMacAppProcessPids(output, appPaths);
46374
+ } catch {
46375
+ return [];
46376
+ }
46377
+ }
46378
+ function killMacAppPathProcesses(ideId, signal) {
46379
+ const pids = getMacAppProcessPids(ideId);
46380
+ let signalled = false;
46381
+ for (const pid of pids) {
46382
+ try {
46383
+ process.kill(pid, signal);
46384
+ signalled = true;
46385
+ } catch {
46386
+ }
46387
+ }
46388
+ return signalled;
46389
+ }
45782
46390
  async function findFreePort(ports) {
45783
46391
  for (const port2 of ports) {
45784
46392
  const free = await checkPortFree(port2);
@@ -45840,6 +46448,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
45840
46448
  } catch {
45841
46449
  }
45842
46450
  }
46451
+ killMacAppPathProcesses(ideId, "SIGTERM");
45843
46452
  } else if (plat === "win32" && winProcesses) {
45844
46453
  for (const proc of winProcesses) {
45845
46454
  try {
@@ -45869,6 +46478,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
45869
46478
  (0, import_child_process7.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
45870
46479
  } catch {
45871
46480
  }
46481
+ killMacAppPathProcesses(ideId, "SIGKILL");
45872
46482
  } else if (plat === "win32" && winProcesses) {
45873
46483
  for (const proc of winProcesses) {
45874
46484
  try {
@@ -45888,14 +46498,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
45888
46498
  try {
45889
46499
  if (plat === "darwin") {
45890
46500
  const appName = getMacAppIdentifiers()[ideId];
45891
- if (!appName) return false;
46501
+ if (!appName) return getMacAppProcessPids(ideId).length > 0;
45892
46502
  try {
45893
46503
  const result = (0, import_child_process7.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
45894
46504
  encoding: "utf-8",
45895
46505
  timeout: 3e3
45896
46506
  });
45897
- return result.trim().length > 0;
46507
+ if (result.trim().length > 0) return true;
45898
46508
  } catch {
46509
+ }
46510
+ try {
45899
46511
  const result = (0, import_child_process7.execSync)(
45900
46512
  `osascript -e 'tell application "System Events" to count (every process whose name is "${escapeForAppleScript(appName)}")'`,
45901
46513
  {
@@ -45904,8 +46516,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
45904
46516
  stdio: ["pipe", "pipe", "pipe"]
45905
46517
  }
45906
46518
  );
45907
- return Number.parseInt(result.trim() || "0", 10) > 0;
46519
+ if (Number.parseInt(result.trim() || "0", 10) > 0) return true;
46520
+ } catch {
45908
46521
  }
46522
+ return getMacAppProcessPids(ideId).length > 0;
45909
46523
  } else if (plat === "win32") {
45910
46524
  const winProcesses = getWinProcessNames()[ideId];
45911
46525
  if (!winProcesses) return false;
@@ -47260,13 +47874,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
47260
47874
  const wantsAll = args?.all === true;
47261
47875
  const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
47262
47876
  const limit = wantsAll ? Number.MAX_SAFE_INTEGER : Math.max(1, Math.min(100, Number(args?.limit) || 30));
47263
- const { sessions: historySessions, hasMore } = listSavedHistorySessions(providerType, { offset, limit });
47877
+ const providerMeta = this.deps.providerLoader.getMeta(providerType);
47878
+ const { sessions: historySessions, hasMore, source } = listProviderHistorySessions(providerType, {
47879
+ canonicalHistory: providerMeta?.canonicalHistory,
47880
+ offset,
47881
+ limit,
47882
+ historyBehavior: providerMeta?.historyBehavior
47883
+ });
47264
47884
  const state = loadState();
47265
47885
  const savedSessions = getSavedProviderSessions(state, { providerType, kind });
47266
47886
  const recentSessions = getRecentActivity(state, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
47267
47887
  const savedSessionById = new Map(savedSessions.map((entry) => [entry.providerSessionId, entry]));
47268
47888
  const recentSessionById = new Map(recentSessions.map((entry) => [entry.providerSessionId, entry]));
47269
- const providerMeta = this.deps.providerLoader.getMeta(providerType);
47270
47889
  const canResumeById = supportsExplicitSessionResume(providerMeta?.resume);
47271
47890
  return {
47272
47891
  success: true,
@@ -47289,7 +47908,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
47289
47908
  canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById
47290
47909
  };
47291
47910
  }),
47292
- hasMore
47911
+ hasMore,
47912
+ source
47293
47913
  };
47294
47914
  }
47295
47915
  // ─── restart_session: IDE / CLI / ACP unified ───