@adhdev/daemon-standalone 0.9.44 → 0.9.46

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
  }
@@ -35967,29 +35992,6 @@ ${cleanBody}`;
35967
35992
  return { sessions: [], hasMore: false };
35968
35993
  }
35969
35994
  }
35970
- function normalizeCanonicalHermesMessageContent(content) {
35971
- if (typeof content === "string") return content.trim();
35972
- if (content == null) return "";
35973
- try {
35974
- return JSON.stringify(content).trim();
35975
- } catch {
35976
- return String(content).trim();
35977
- }
35978
- }
35979
- function extractCanonicalHermesMessageTimestamp(message, fallbackTs) {
35980
- const numericTimestamp = Number(message.receivedAt || message.timestamp || message.ts || 0);
35981
- if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
35982
- const stringTimestamp = typeof message.ts === "string" ? Date.parse(message.ts) : typeof message.timestamp === "string" ? Date.parse(message.timestamp) : NaN;
35983
- if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
35984
- return fallbackTs;
35985
- }
35986
- function extractTimestampValue(value) {
35987
- const numericTimestamp = Number(value || 0);
35988
- if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
35989
- const stringTimestamp = typeof value === "string" ? Date.parse(value) : NaN;
35990
- if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
35991
- return 0;
35992
- }
35993
35995
  function readExistingSessionStartRecord(agentType, historySessionId) {
35994
35996
  try {
35995
35997
  const dir = path7.join(HISTORY_DIR, agentType);
@@ -36035,232 +36037,193 @@ ${cleanBody}`;
36035
36037
  return false;
36036
36038
  }
36037
36039
  }
36038
- function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
36040
+ function getNativeHistoryScriptName(canonicalHistory, key) {
36041
+ const configured = canonicalHistory?.scripts?.[key];
36042
+ if (typeof configured === "string" && configured.trim()) return configured.trim();
36043
+ return key === "readSession" ? "readNativeHistory" : "listNativeHistory";
36044
+ }
36045
+ function getProviderNativeHistoryScript(scripts, canonicalHistory, key) {
36046
+ if (!canonicalHistory?.scripts) return null;
36047
+ const fn2 = scripts?.[getNativeHistoryScriptName(canonicalHistory, key)];
36048
+ return typeof fn2 === "function" ? fn2 : null;
36049
+ }
36050
+ function normalizeProviderNativeHistoryRecords(agentType, historySessionId, records) {
36051
+ if (!Array.isArray(records)) return [];
36052
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36053
+ return records.map((record2) => sanitizeHistoryMessage(agentType, {
36054
+ ts: typeof record2?.ts === "string" ? record2.ts : new Date(Number(record2?.receivedAt) || Date.now()).toISOString(),
36055
+ receivedAt: Number(record2?.receivedAt) || Date.parse(record2?.ts || "") || Date.now(),
36056
+ role: record2?.role,
36057
+ content: String(record2?.content || ""),
36058
+ kind: record2?.kind || (record2?.role === "system" ? "session_start" : "standard"),
36059
+ senderName: record2?.senderName,
36060
+ agent: agentType,
36061
+ instanceId: record2?.instanceId,
36062
+ historySessionId: normalizeSavedHistorySessionId(record2?.historySessionId || normalizedSessionId),
36063
+ sessionTitle: record2?.sessionTitle,
36064
+ workspace: record2?.workspace
36065
+ })).filter(Boolean);
36066
+ }
36067
+ function callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, historySessionId, workspace) {
36068
+ const fn2 = getProviderNativeHistoryScript(scripts, canonicalHistory, "readSession");
36069
+ if (!fn2) return null;
36070
+ const result = fn2({
36071
+ agentType,
36072
+ sessionId: historySessionId,
36073
+ historySessionId,
36074
+ workspace,
36075
+ format: canonicalHistory?.format,
36076
+ watchPath: canonicalHistory?.watchPath,
36077
+ args: { sessionId: historySessionId, historySessionId, workspace }
36078
+ });
36079
+ if (!result || typeof result !== "object") return null;
36080
+ const records = normalizeProviderNativeHistoryRecords(agentType, historySessionId, result.messages || result.records);
36081
+ if (records.length === 0) return null;
36082
+ return {
36083
+ records,
36084
+ sourcePath: typeof result.sourcePath === "string" ? result.sourcePath : "",
36085
+ sourceMtimeMs: Number(result.sourceMtimeMs) || 0
36086
+ };
36087
+ }
36088
+ function buildNativeHistoryReadResult(agentType, canonicalHistory, scripts, historySessionId, workspace) {
36089
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || "");
36090
+ if (!canonicalHistory || !normalizedSessionId || !isNativeSourceCanonicalHistory(canonicalHistory)) return null;
36091
+ return callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace);
36092
+ }
36093
+ function materializeNativeHistoryToMirror(agentType, canonicalHistory, historySessionId, workspace, scripts) {
36039
36094
  const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36040
36095
  if (!normalizedSessionId) return false;
36096
+ const nativeResult = callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace);
36097
+ const nativeRecords = nativeResult?.records || [];
36098
+ if (nativeRecords.length === 0) return false;
36099
+ const normalizedRecords = nativeRecords.map((record2) => ({
36100
+ ...record2,
36101
+ agent: agentType,
36102
+ historySessionId: normalizedSessionId
36103
+ }));
36104
+ const existingSessionStart = readExistingSessionStartRecord(agentType, normalizedSessionId);
36105
+ const records = existingSessionStart && normalizedRecords[0]?.kind !== "session_start" ? [{ ...existingSessionStart, historySessionId: normalizedSessionId, agent: agentType }, ...normalizedRecords] : normalizedRecords;
36106
+ return rewriteCanonicalSavedHistory(agentType, normalizedSessionId, records);
36107
+ }
36108
+ function materializeProviderNativeHistory(agentType, canonicalHistory, historySessionId, workspace, scripts) {
36109
+ if (!canonicalHistory || canonicalHistory.mode !== "materialized-mirror") return false;
36110
+ return materializeNativeHistoryToMirror(agentType, canonicalHistory, historySessionId, workspace, scripts);
36111
+ }
36112
+ function isNativeSourceCanonicalHistory(canonicalHistory) {
36113
+ if (!canonicalHistory) return false;
36114
+ if (canonicalHistory.mode === "disabled") return false;
36115
+ if (canonicalHistory.mode === "materialized-mirror") return false;
36116
+ return true;
36117
+ }
36118
+ function readProviderChatHistory(agentType, options = {}) {
36119
+ if (isNativeSourceCanonicalHistory(options.canonicalHistory) && options.historySessionId) {
36120
+ const nativeResult = buildNativeHistoryReadResult(agentType, options.canonicalHistory, options.scripts, options.historySessionId, options.workspace);
36121
+ if (!nativeResult) return { messages: [], hasMore: false, source: "native-unavailable" };
36122
+ return {
36123
+ ...pageHistoryRecords(agentType, nativeResult.records, options.offset || 0, options.limit || 30, options.excludeRecentCount || 0, options.historyBehavior),
36124
+ source: "provider-native",
36125
+ sourcePath: nativeResult.sourcePath,
36126
+ sourceMtimeMs: nativeResult.sourceMtimeMs
36127
+ };
36128
+ }
36129
+ return {
36130
+ ...readChatHistory(agentType, options.offset || 0, options.limit || 30, options.historySessionId, options.excludeRecentCount || 0, options.historyBehavior),
36131
+ source: "adhdev-mirror"
36132
+ };
36133
+ }
36134
+ function buildNativeSessionSummary(agentType, historySessionId, records, sourcePath) {
36135
+ const visible = pageHistoryRecords(agentType, records, 0, Number.MAX_SAFE_INTEGER).messages;
36136
+ if (visible.length === 0) return null;
36137
+ let sourceMtimeMs = 0;
36041
36138
  try {
36042
- const sessionFilePath = path7.join(os52.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
36043
- if (!fs32.existsSync(sessionFilePath)) return false;
36044
- const raw = JSON.parse(fs32.readFileSync(sessionFilePath, "utf-8"));
36045
- const canonicalMessages = Array.isArray(raw.messages) ? raw.messages : [];
36046
- const dir = path7.join(HISTORY_DIR, "hermes-cli");
36047
- fs32.mkdirSync(dir, { recursive: true });
36048
- const existingSessionStart = readExistingSessionStartRecord("hermes-cli", normalizedSessionId);
36049
- const records = [];
36050
- if (existingSessionStart) {
36051
- records.push({
36052
- ...existingSessionStart,
36053
- historySessionId: normalizedSessionId
36054
- });
36055
- }
36056
- let fallbackTs = Date.parse(raw.session_start || raw.last_updated || "") || Date.now();
36057
- for (const message of canonicalMessages) {
36058
- const role = String(message.role || "").trim();
36059
- const content = normalizeCanonicalHermesMessageContent(message.content);
36060
- if (!content) continue;
36061
- const receivedAt = extractCanonicalHermesMessageTimestamp(message, fallbackTs);
36062
- fallbackTs = receivedAt + 1;
36063
- if (role === "user") {
36064
- records.push({
36065
- ts: new Date(receivedAt).toISOString(),
36066
- receivedAt,
36067
- role: "user",
36068
- content,
36069
- kind: "standard",
36070
- agent: "hermes-cli",
36071
- historySessionId: normalizedSessionId
36072
- });
36073
- continue;
36074
- }
36075
- if (role === "assistant") {
36076
- records.push({
36077
- ts: new Date(receivedAt).toISOString(),
36078
- receivedAt,
36079
- role: "assistant",
36080
- content,
36081
- kind: "standard",
36082
- agent: "hermes-cli",
36083
- historySessionId: normalizedSessionId
36084
- });
36085
- continue;
36086
- }
36087
- if (role === "tool") {
36088
- records.push({
36089
- ts: new Date(receivedAt).toISOString(),
36090
- receivedAt,
36091
- role: "assistant",
36092
- content,
36093
- kind: "tool",
36094
- senderName: "Tool",
36095
- agent: "hermes-cli",
36096
- historySessionId: normalizedSessionId
36097
- });
36098
- }
36099
- }
36100
- return rewriteCanonicalSavedHistory("hermes-cli", normalizedSessionId, records);
36139
+ sourceMtimeMs = fs32.statSync(sourcePath).mtimeMs;
36101
36140
  } catch {
36102
- return false;
36103
36141
  }
36142
+ const firstMessageAt = visible[0]?.receivedAt || sourceMtimeMs || Date.now();
36143
+ const lastMessageAt = visible[visible.length - 1]?.receivedAt || firstMessageAt;
36144
+ const lastNonSystem = [...visible].reverse().find((message) => message.role !== "system") || visible[visible.length - 1];
36145
+ const firstSystem = visible.find((message) => message.kind === "session_start");
36146
+ return {
36147
+ historySessionId,
36148
+ sessionTitle: lastNonSystem?.content,
36149
+ messageCount: visible.length,
36150
+ firstMessageAt,
36151
+ lastMessageAt,
36152
+ preview: lastNonSystem?.content,
36153
+ workspace: firstSystem?.workspace || (firstSystem?.kind === "session_start" ? firstSystem.content : void 0),
36154
+ source: "provider-native",
36155
+ sourcePath,
36156
+ sourceMtimeMs
36157
+ };
36104
36158
  }
36105
- function resolveClaudeProjectTranscriptPath(historySessionId, workspace) {
36106
- const claudeProjectsDir = path7.join(os52.homedir(), ".claude", "projects");
36107
- if (!fs32.existsSync(claudeProjectsDir)) return null;
36108
- const normalizedWorkspace = typeof workspace === "string" ? workspace.trim() : "";
36109
- if (normalizedWorkspace) {
36110
- const directPath = path7.join(claudeProjectsDir, normalizedWorkspace.replace(/[\\/]/g, "-"), `${historySessionId}.jsonl`);
36111
- if (fs32.existsSync(directPath)) return directPath;
36112
- }
36113
- const stack = [claudeProjectsDir];
36114
- while (stack.length > 0) {
36115
- const current = stack.pop();
36116
- if (!current) continue;
36117
- for (const entry of fs32.readdirSync(current, { withFileTypes: true })) {
36118
- const entryPath = path7.join(current, entry.name);
36119
- if (entry.isDirectory()) {
36120
- stack.push(entryPath);
36121
- continue;
36122
- }
36123
- if (entry.isFile() && entry.name === `${historySessionId}.jsonl`) {
36124
- return entryPath;
36159
+ function normalizeProviderNativeHistorySessionSummary(agentType, item) {
36160
+ const historySessionId = normalizeSavedHistorySessionId(item?.historySessionId || item?.sessionId || "");
36161
+ if (!historySessionId) return null;
36162
+ const sourcePath = typeof item?.sourcePath === "string" ? item.sourcePath : "";
36163
+ const sourceMtimeMs = Number(item?.sourceMtimeMs) || 0;
36164
+ const firstMessageAt = Number(item?.firstMessageAt) || sourceMtimeMs || Date.now();
36165
+ const lastMessageAt = Number(item?.lastMessageAt) || firstMessageAt;
36166
+ const messageCount = Math.max(0, Number(item?.messageCount) || 0);
36167
+ return {
36168
+ historySessionId,
36169
+ sessionTitle: typeof item?.sessionTitle === "string" ? item.sessionTitle : void 0,
36170
+ messageCount,
36171
+ firstMessageAt,
36172
+ lastMessageAt,
36173
+ preview: typeof item?.preview === "string" ? item.preview : void 0,
36174
+ workspace: typeof item?.workspace === "string" ? item.workspace : void 0,
36175
+ source: "provider-native",
36176
+ sourcePath,
36177
+ sourceMtimeMs
36178
+ };
36179
+ }
36180
+ function collectProviderScriptNativeHistorySessionSummaries(agentType, canonicalHistory, scripts) {
36181
+ const fn2 = getProviderNativeHistoryScript(scripts, canonicalHistory, "listSessions");
36182
+ if (!fn2) return null;
36183
+ const result = fn2({
36184
+ agentType,
36185
+ format: canonicalHistory.format,
36186
+ watchPath: canonicalHistory.watchPath,
36187
+ args: {}
36188
+ });
36189
+ if (!result || typeof result !== "object") return [];
36190
+ const sessions = Array.isArray(result.sessions) ? result.sessions : [];
36191
+ const summaries = [];
36192
+ for (const item of sessions) {
36193
+ if (Array.isArray(item?.messages || item?.records)) {
36194
+ const historySessionId = normalizeSavedHistorySessionId(item?.historySessionId || item?.sessionId || "");
36195
+ if (!historySessionId) continue;
36196
+ const records = normalizeProviderNativeHistoryRecords(agentType, historySessionId, item.messages || item.records);
36197
+ const summary2 = buildNativeSessionSummary(agentType, historySessionId, records, typeof item?.sourcePath === "string" ? item.sourcePath : "");
36198
+ if (summary2) {
36199
+ if (Number(item?.sourceMtimeMs)) summary2.sourceMtimeMs = Number(item.sourceMtimeMs);
36200
+ summaries.push(summary2);
36125
36201
  }
36126
- }
36127
- }
36128
- return null;
36129
- }
36130
- function extractClaudeAssistantContentParts(content) {
36131
- if (typeof content === "string") {
36132
- const trimmed = content.trim();
36133
- return trimmed ? [{ content: trimmed, kind: "standard", role: "assistant" }] : [];
36134
- }
36135
- if (!Array.isArray(content)) return [];
36136
- const parts = [];
36137
- for (const block of content) {
36138
- if (!block || typeof block !== "object") continue;
36139
- const record2 = block;
36140
- const type = String(record2.type || "").trim();
36141
- if (type === "text") {
36142
- const text = String(record2.text || "").trim();
36143
- if (text) parts.push({ content: text, kind: "standard", role: "assistant" });
36144
36202
  continue;
36145
36203
  }
36146
- if (type === "tool_use") {
36147
- const name = String(record2.name || "").trim() || "Tool";
36148
- const input = record2.input && typeof record2.input === "object" ? record2.input : null;
36149
- const command = input ? String(input.command || "").trim() : "";
36150
- const summary = command ? `${name}: ${command}` : name;
36151
- if (summary) parts.push({ content: summary, kind: "tool", senderName: "Tool", role: "assistant" });
36152
- }
36204
+ const summary = normalizeProviderNativeHistorySessionSummary(agentType, item);
36205
+ if (summary) summaries.push(summary);
36153
36206
  }
36154
- return parts;
36207
+ return sortSavedHistorySessionSummaries(summaries);
36155
36208
  }
36156
- function extractClaudeUserContentParts(content) {
36157
- if (typeof content === "string") {
36158
- const trimmed = content.trim();
36159
- return trimmed ? [{ role: "user", content: trimmed, kind: "standard" }] : [];
36160
- }
36161
- if (!Array.isArray(content)) return [];
36162
- const parts = [];
36163
- for (const block of content) {
36164
- if (!block || typeof block !== "object") continue;
36165
- const record2 = block;
36166
- const type = String(record2.type || "").trim();
36167
- if (type === "text") {
36168
- const text = String(record2.text || "").trim();
36169
- if (text) parts.push({ role: "user", content: text, kind: "standard" });
36170
- continue;
36171
- }
36172
- if (type === "tool_result") {
36173
- const rawContent = record2.content;
36174
- const text = typeof rawContent === "string" ? rawContent.trim() : Array.isArray(rawContent) ? rawContent.map((entry) => {
36175
- if (typeof entry === "string") return entry.trim();
36176
- if (!entry || typeof entry !== "object") return "";
36177
- const nested = entry;
36178
- if (typeof nested.text === "string") return nested.text.trim();
36179
- if (typeof nested.content === "string") return nested.content.trim();
36180
- return "";
36181
- }).filter(Boolean).join("\n") : "";
36182
- if (text) parts.push({ role: "assistant", content: text, kind: "tool", senderName: "Tool" });
36183
- }
36184
- }
36185
- return parts;
36209
+ function collectNativeHistorySessionSummaries(agentType, canonicalHistory, scripts) {
36210
+ return collectProviderScriptNativeHistorySessionSummaries(agentType, canonicalHistory, scripts) || [];
36186
36211
  }
36187
- function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
36188
- const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
36189
- if (!normalizedSessionId) return false;
36190
- try {
36191
- const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
36192
- if (!transcriptPath) return false;
36193
- const lines = fs32.readFileSync(transcriptPath, "utf-8").split("\n").filter(Boolean);
36194
- const records = [];
36195
- const existingSessionStart = readExistingSessionStartRecord("claude-cli", normalizedSessionId);
36196
- if (existingSessionStart) {
36197
- records.push({
36198
- ...existingSessionStart,
36199
- historySessionId: normalizedSessionId
36200
- });
36201
- }
36202
- let fallbackTs = Date.now();
36203
- for (const line of lines) {
36204
- let parsed = null;
36205
- try {
36206
- parsed = JSON.parse(line);
36207
- } catch {
36208
- parsed = null;
36209
- }
36210
- if (!parsed) continue;
36211
- const parsedSessionId = String(parsed.sessionId || "").trim();
36212
- if (parsedSessionId && parsedSessionId !== normalizedSessionId) continue;
36213
- const receivedAt = extractTimestampValue(parsed.timestamp) || fallbackTs;
36214
- fallbackTs = receivedAt + 1;
36215
- const parsedWorkspace = String(parsed.cwd || workspace || "").trim();
36216
- if (records.length === 0 && parsedWorkspace) {
36217
- records.push({
36218
- ts: new Date(receivedAt).toISOString(),
36219
- receivedAt,
36220
- role: "system",
36221
- kind: "session_start",
36222
- content: parsedWorkspace,
36223
- agent: "claude-cli",
36224
- historySessionId: normalizedSessionId,
36225
- workspace: parsedWorkspace
36226
- });
36227
- }
36228
- const type = String(parsed.type || "").trim();
36229
- const message = parsed.message && typeof parsed.message === "object" ? parsed.message : null;
36230
- if (type === "user" && message) {
36231
- for (const part of extractClaudeUserContentParts(message.content)) {
36232
- records.push({
36233
- ts: new Date(receivedAt).toISOString(),
36234
- receivedAt,
36235
- role: part.role,
36236
- content: part.content,
36237
- kind: part.kind,
36238
- senderName: part.senderName,
36239
- agent: "claude-cli",
36240
- historySessionId: normalizedSessionId
36241
- });
36242
- }
36243
- continue;
36244
- }
36245
- if (type === "assistant" && message) {
36246
- for (const part of extractClaudeAssistantContentParts(message.content)) {
36247
- records.push({
36248
- ts: new Date(receivedAt).toISOString(),
36249
- receivedAt,
36250
- role: "assistant",
36251
- content: part.content,
36252
- kind: part.kind,
36253
- senderName: part.senderName,
36254
- agent: "claude-cli",
36255
- historySessionId: normalizedSessionId
36256
- });
36257
- }
36258
- }
36259
- }
36260
- return rewriteCanonicalSavedHistory("claude-cli", normalizedSessionId, records);
36261
- } catch {
36262
- return false;
36212
+ function listProviderHistorySessions(agentType, options = {}) {
36213
+ if (isNativeSourceCanonicalHistory(options.canonicalHistory)) {
36214
+ const offset = Math.max(0, options.offset || 0);
36215
+ const limit = Math.max(1, options.limit || 30);
36216
+ const summaries = collectNativeHistorySessionSummaries(agentType, options.canonicalHistory, options.scripts);
36217
+ return {
36218
+ sessions: summaries.slice(offset, offset + limit),
36219
+ hasMore: offset + limit < summaries.length,
36220
+ source: "provider-native"
36221
+ };
36263
36222
  }
36223
+ return {
36224
+ ...listSavedHistorySessions(agentType, { offset: options.offset, limit: options.limit }, options.historyBehavior),
36225
+ source: "adhdev-mirror"
36226
+ };
36264
36227
  }
36265
36228
  function isControlValue(value) {
36266
36229
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
@@ -38829,7 +38792,17 @@ ${effect.notification.body || ""}`.trim();
38829
38792
  const visibleCount = Array.isArray(status?.messages) ? status.messages.length : 0;
38830
38793
  if (visibleCount > excludeRecentCount) excludeRecentCount = visibleCount;
38831
38794
  }
38832
- const result = readChatHistory(agentStr, offset || 0, limit || 30, historySessionId, excludeRecentCount);
38795
+ const workspace = typeof args?.workspace === "string" ? args.workspace : typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : void 0;
38796
+ const result = readProviderChatHistory(agentStr, {
38797
+ canonicalHistory: provider?.canonicalHistory,
38798
+ historySessionId,
38799
+ workspace,
38800
+ offset: offset || 0,
38801
+ limit: limit || 30,
38802
+ excludeRecentCount,
38803
+ historyBehavior: provider?.historyBehavior,
38804
+ scripts: provider?.scripts
38805
+ });
38833
38806
  return { success: true, ...result, agent: agentStr };
38834
38807
  } catch (e) {
38835
38808
  return { success: false, error: e.message };
@@ -38854,7 +38827,8 @@ ${effect.notification.body || ""}`.trim();
38854
38827
  }
38855
38828
  const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
38856
38829
  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;
38830
+ const parsedIsProviderAuthoritative = parsedRecord?.transcriptAuthority === "provider" || parsedRecord?.coverage === "full";
38831
+ const shouldPreferAdapterMessages = !parsedIsProviderAuthoritative && Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
38858
38832
  const parsedShowsApproval = hasNonEmptyModalButtons(parsedRecord?.activeModal) && parsedRecord?.status === "waiting_approval";
38859
38833
  const status = parsedRecord ? {
38860
38834
  ...parsedRecord,
@@ -38864,6 +38838,8 @@ ${effect.notification.body || ""}`.trim();
38864
38838
  } : adapterStatus;
38865
38839
  const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
38866
38840
  const providerSessionId = typeof parsedRecord?.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
38841
+ const transcriptAuthority = parsedRecord?.transcriptAuthority === "provider" || parsedRecord?.transcriptAuthority === "daemon" ? parsedRecord.transcriptAuthority : void 0;
38842
+ const coverage = parsedRecord?.coverage === "full" || parsedRecord?.coverage === "tail" || parsedRecord?.coverage === "current-turn" ? parsedRecord.coverage : void 0;
38867
38843
  if (status) {
38868
38844
  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
38845
  return buildReadChatCommandResult({
@@ -38882,7 +38858,9 @@ ${effect.notification.body || ""}`.trim();
38882
38858
  returnedMsgCount: Array.isArray(status.messages) ? status.messages.length : 0
38883
38859
  },
38884
38860
  ...title ? { title } : {},
38885
- ...providerSessionId ? { providerSessionId } : {}
38861
+ ...providerSessionId ? { providerSessionId } : {},
38862
+ ...transcriptAuthority ? { transcriptAuthority } : {},
38863
+ ...coverage ? { coverage } : {}
38886
38864
  }, args);
38887
38865
  }
38888
38866
  }
@@ -41275,11 +41253,8 @@ ${effect.notification.body || ""}`.trim();
41275
41253
  historyWriter;
41276
41254
  runtimeMessages = [];
41277
41255
  lastPersistedHistoryMessages = [];
41278
- lastCanonicalHermesSyncMtimeMs = 0;
41279
- lastCanonicalHermesExistCheckAt = 0;
41280
- lastCanonicalHermesWatchPath = void 0;
41281
- lastCanonicalClaudeRebuildMtimeMs = 0;
41282
- lastCanonicalClaudeCheckAt = 0;
41256
+ lastNativeSourceCanonicalCheckAt = 0;
41257
+ lastNativeSourceCanonicalCacheKey = void 0;
41283
41258
  cachedSqliteDb = null;
41284
41259
  cachedSqliteDbPath = null;
41285
41260
  cachedSqliteDbMissingUntil = 0;
@@ -41979,41 +41954,45 @@ ${effect.notification.body || ""}`.trim();
41979
41954
  if (!this.providerSessionId) return false;
41980
41955
  const canonicalHistory = this.provider.canonicalHistory;
41981
41956
  if (!canonicalHistory) return false;
41957
+ if (isNativeSourceCanonicalHistory(canonicalHistory)) {
41958
+ const cacheKey = [this.type, this.providerSessionId, this.workingDir].join("\0");
41959
+ const now = Date.now();
41960
+ if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
41961
+ return true;
41962
+ }
41963
+ this.lastNativeSourceCanonicalCacheKey = cacheKey;
41964
+ this.lastNativeSourceCanonicalCheckAt = now;
41965
+ const restoredHistory = readProviderChatHistory(this.type, {
41966
+ canonicalHistory,
41967
+ historySessionId: this.providerSessionId,
41968
+ workspace: this.workingDir,
41969
+ offset: 0,
41970
+ limit: Number.MAX_SAFE_INTEGER,
41971
+ historyBehavior: this.provider.historyBehavior,
41972
+ scripts: this.provider.scripts
41973
+ });
41974
+ if (restoredHistory.source === "provider-native") {
41975
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
41976
+ role: message.role,
41977
+ content: message.content,
41978
+ kind: message.kind,
41979
+ senderName: message.senderName,
41980
+ receivedAt: message.receivedAt
41981
+ }));
41982
+ }
41983
+ return true;
41984
+ }
41982
41985
  try {
41983
- let rebuilt = false;
41984
- if (canonicalHistory.format === "hermes-json") {
41985
- const watchPath = canonicalHistory.watchPath.replace(/^~/, os11.homedir()).replace("{{sessionId}}", this.providerSessionId);
41986
- const now = Date.now();
41987
- if (watchPath !== this.lastCanonicalHermesWatchPath || now - this.lastCanonicalHermesExistCheckAt >= 2e3) {
41988
- this.lastCanonicalHermesWatchPath = watchPath;
41989
- this.lastCanonicalHermesExistCheckAt = now;
41990
- if (!fs52.existsSync(watchPath)) return false;
41991
- } else if (this.lastCanonicalHermesSyncMtimeMs === 0) {
41992
- if (!fs52.existsSync(watchPath)) return false;
41993
- }
41994
- const stat4 = fs52.statSync(watchPath);
41995
- if (stat4.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
41996
- rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
41997
- if (rebuilt) this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
41998
- } else if (canonicalHistory.format === "claude-jsonl") {
41999
- const now = Date.now();
42000
- if (now - this.lastCanonicalClaudeCheckAt < 2e3 && this.lastCanonicalClaudeRebuildMtimeMs !== 0) {
42001
- return true;
42002
- }
42003
- this.lastCanonicalClaudeCheckAt = now;
42004
- const claudeProjectsDir = path11.join(os11.homedir(), ".claude", "projects");
42005
- const workspaceSegment = typeof this.workingDir === "string" ? this.workingDir.replace(/[\\/]/g, "-").replace(/^-+/, "") : "";
42006
- const transcriptFile = path11.join(claudeProjectsDir, workspaceSegment, `${this.providerSessionId}.jsonl`);
42007
- let transcriptMtime = 0;
42008
- try {
42009
- transcriptMtime = fs52.statSync(transcriptFile).mtimeMs;
42010
- } catch {
42011
- }
42012
- if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalClaudeRebuildMtimeMs) return true;
42013
- rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
42014
- if (rebuilt) this.lastCanonicalClaudeRebuildMtimeMs = transcriptMtime || Date.now();
41986
+ const cacheKey = [this.type, this.providerSessionId, this.workingDir, canonicalHistory.mode || "materialized-mirror"].join("\0");
41987
+ const now = Date.now();
41988
+ if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
41989
+ return true;
41990
+ }
41991
+ this.lastNativeSourceCanonicalCacheKey = cacheKey;
41992
+ this.lastNativeSourceCanonicalCheckAt = now;
41993
+ if (!materializeProviderNativeHistory(this.type, canonicalHistory, this.providerSessionId, this.workingDir, this.provider.scripts)) {
41994
+ return false;
42015
41995
  }
42016
- if (!rebuilt) return false;
42017
41996
  const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
42018
41997
  this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
42019
41998
  role: message.role,
@@ -42030,8 +42009,18 @@ ${effect.notification.body || ""}`.trim();
42030
42009
  restorePersistedHistoryFromCurrentSession() {
42031
42010
  if (!this.providerSessionId) return;
42032
42011
  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);
42012
+ const restoredHistory = isNativeSourceCanonicalHistory(this.provider.canonicalHistory) ? readProviderChatHistory(this.type, {
42013
+ canonicalHistory: this.provider.canonicalHistory,
42014
+ historySessionId: this.providerSessionId,
42015
+ workspace: this.workingDir,
42016
+ offset: 0,
42017
+ limit: Number.MAX_SAFE_INTEGER,
42018
+ historyBehavior: this.provider.historyBehavior,
42019
+ scripts: this.provider.scripts
42020
+ }) : (() => {
42021
+ this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
42022
+ return readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
42023
+ })();
42035
42024
  this.historyWriter.seedSessionHistory(
42036
42025
  this.type,
42037
42026
  restoredHistory.messages,
@@ -44148,6 +44137,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
44148
44137
  warnings.push("Extension providers should have extensionId");
44149
44138
  }
44150
44139
  validateCapabilities(provider, controls, errors);
44140
+ validateCanonicalHistory(provider.canonicalHistory, errors);
44151
44141
  for (const control of controls) {
44152
44142
  validateControl(control, errors);
44153
44143
  }
@@ -44205,6 +44195,39 @@ Run 'adhdev doctor' for detailed diagnostics.`
44205
44195
  errors.push("providers declaring controls must set capabilities.controls.typedResults=true");
44206
44196
  }
44207
44197
  }
44198
+ function validateCanonicalHistory(raw, errors) {
44199
+ if (raw === void 0) return;
44200
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
44201
+ errors.push("canonicalHistory must be an object");
44202
+ return;
44203
+ }
44204
+ const canonicalHistory = raw;
44205
+ const format = canonicalHistory.format;
44206
+ if (format !== void 0 && (typeof format !== "string" || !format.trim())) {
44207
+ errors.push("canonicalHistory.format must be a non-empty string when provided");
44208
+ }
44209
+ const watchPath = canonicalHistory.watchPath;
44210
+ if (watchPath !== void 0 && (typeof watchPath !== "string" || !watchPath.trim())) {
44211
+ errors.push("canonicalHistory.watchPath must be a non-empty string when provided");
44212
+ }
44213
+ const mode = canonicalHistory.mode;
44214
+ if (mode !== void 0 && !["native-source", "materialized-mirror", "disabled"].includes(String(mode))) {
44215
+ errors.push("canonicalHistory.mode must be one of: native-source, materialized-mirror, disabled");
44216
+ }
44217
+ const scripts = canonicalHistory.scripts;
44218
+ if (scripts === void 0) return;
44219
+ if (!scripts || typeof scripts !== "object" || Array.isArray(scripts)) {
44220
+ errors.push("canonicalHistory.scripts must be an object");
44221
+ return;
44222
+ }
44223
+ const scriptConfig = scripts;
44224
+ for (const key of ["readSession", "listSessions"]) {
44225
+ const value = scriptConfig[key];
44226
+ if (typeof value !== "string" || !value.trim()) {
44227
+ errors.push(`canonicalHistory.scripts.${key} must be a non-empty string`);
44228
+ }
44229
+ }
44230
+ }
44208
44231
  function validateControl(control, errors) {
44209
44232
  if (!control || typeof control !== "object") {
44210
44233
  errors.push("controls: each control must be an object");
@@ -45744,6 +45767,36 @@ Run 'adhdev doctor' for detailed diagnostics.`
45744
45767
  return 0;
45745
45768
  }
45746
45769
  };
45770
+ function normalizeMacAppPath(appPath) {
45771
+ const trimmed = String(appPath || "").trim();
45772
+ if (!trimmed) return null;
45773
+ return trimmed.replace(/\/+$/, "");
45774
+ }
45775
+ function parsePsLine(line) {
45776
+ const match = line.match(/^\s*(\d+)\s+(.+)$/);
45777
+ if (!match) return null;
45778
+ const pid = Number.parseInt(match[1], 10);
45779
+ if (!Number.isFinite(pid)) return null;
45780
+ return { pid, args: match[2] };
45781
+ }
45782
+ function isMacAppProcessArgs(args, appPath) {
45783
+ const normalized = normalizeMacAppPath(appPath);
45784
+ if (!normalized) return false;
45785
+ return String(args || "").startsWith(`${normalized}/`);
45786
+ }
45787
+ function findMacAppProcessPids(psOutput, appPaths) {
45788
+ const normalizedPaths = appPaths.map(normalizeMacAppPath).filter((value) => !!value);
45789
+ if (normalizedPaths.length === 0) return [];
45790
+ const pids = [];
45791
+ for (const line of String(psOutput || "").split(/\r?\n/)) {
45792
+ const parsed = parsePsLine(line);
45793
+ if (!parsed) continue;
45794
+ if (normalizedPaths.some((appPath) => isMacAppProcessArgs(parsed.args, appPath))) {
45795
+ pids.push(parsed.pid);
45796
+ }
45797
+ }
45798
+ return pids;
45799
+ }
45747
45800
  var _providerLoader = null;
45748
45801
  function getProviderLoader() {
45749
45802
  if (!_providerLoader) {
@@ -45779,6 +45832,35 @@ Run 'adhdev doctor' for detailed diagnostics.`
45779
45832
  function escapeForAppleScript(value) {
45780
45833
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
45781
45834
  }
45835
+ function getIdePathCandidates(ideId) {
45836
+ return getProviderLoader().getIdePathCandidates(ideId);
45837
+ }
45838
+ function getMacAppProcessPids(ideId) {
45839
+ const appPaths = getIdePathCandidates(ideId);
45840
+ if (appPaths.length === 0) return [];
45841
+ try {
45842
+ const output = (0, import_child_process7.execSync)("ps axww -o pid=,args=", {
45843
+ encoding: "utf-8",
45844
+ timeout: 3e3,
45845
+ stdio: ["pipe", "pipe", "pipe"]
45846
+ });
45847
+ return findMacAppProcessPids(output, appPaths);
45848
+ } catch {
45849
+ return [];
45850
+ }
45851
+ }
45852
+ function killMacAppPathProcesses(ideId, signal) {
45853
+ const pids = getMacAppProcessPids(ideId);
45854
+ let signalled = false;
45855
+ for (const pid of pids) {
45856
+ try {
45857
+ process.kill(pid, signal);
45858
+ signalled = true;
45859
+ } catch {
45860
+ }
45861
+ }
45862
+ return signalled;
45863
+ }
45782
45864
  async function findFreePort(ports) {
45783
45865
  for (const port2 of ports) {
45784
45866
  const free = await checkPortFree(port2);
@@ -45840,6 +45922,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
45840
45922
  } catch {
45841
45923
  }
45842
45924
  }
45925
+ killMacAppPathProcesses(ideId, "SIGTERM");
45843
45926
  } else if (plat === "win32" && winProcesses) {
45844
45927
  for (const proc of winProcesses) {
45845
45928
  try {
@@ -45869,6 +45952,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
45869
45952
  (0, import_child_process7.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
45870
45953
  } catch {
45871
45954
  }
45955
+ killMacAppPathProcesses(ideId, "SIGKILL");
45872
45956
  } else if (plat === "win32" && winProcesses) {
45873
45957
  for (const proc of winProcesses) {
45874
45958
  try {
@@ -45888,14 +45972,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
45888
45972
  try {
45889
45973
  if (plat === "darwin") {
45890
45974
  const appName = getMacAppIdentifiers()[ideId];
45891
- if (!appName) return false;
45975
+ if (!appName) return getMacAppProcessPids(ideId).length > 0;
45892
45976
  try {
45893
45977
  const result = (0, import_child_process7.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
45894
45978
  encoding: "utf-8",
45895
45979
  timeout: 3e3
45896
45980
  });
45897
- return result.trim().length > 0;
45981
+ if (result.trim().length > 0) return true;
45898
45982
  } catch {
45983
+ }
45984
+ try {
45899
45985
  const result = (0, import_child_process7.execSync)(
45900
45986
  `osascript -e 'tell application "System Events" to count (every process whose name is "${escapeForAppleScript(appName)}")'`,
45901
45987
  {
@@ -45904,8 +45990,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
45904
45990
  stdio: ["pipe", "pipe", "pipe"]
45905
45991
  }
45906
45992
  );
45907
- return Number.parseInt(result.trim() || "0", 10) > 0;
45993
+ if (Number.parseInt(result.trim() || "0", 10) > 0) return true;
45994
+ } catch {
45908
45995
  }
45996
+ return getMacAppProcessPids(ideId).length > 0;
45909
45997
  } else if (plat === "win32") {
45910
45998
  const winProcesses = getWinProcessNames()[ideId];
45911
45999
  if (!winProcesses) return false;
@@ -47260,13 +47348,19 @@ Run 'adhdev doctor' for detailed diagnostics.`
47260
47348
  const wantsAll = args?.all === true;
47261
47349
  const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
47262
47350
  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 });
47351
+ const providerMeta = this.deps.providerLoader.getMeta(providerType);
47352
+ const { sessions: historySessions, hasMore, source } = listProviderHistorySessions(providerType, {
47353
+ canonicalHistory: providerMeta?.canonicalHistory,
47354
+ offset,
47355
+ limit,
47356
+ historyBehavior: providerMeta?.historyBehavior,
47357
+ scripts: providerMeta?.scripts
47358
+ });
47264
47359
  const state = loadState();
47265
47360
  const savedSessions = getSavedProviderSessions(state, { providerType, kind });
47266
47361
  const recentSessions = getRecentActivity(state, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
47267
47362
  const savedSessionById = new Map(savedSessions.map((entry) => [entry.providerSessionId, entry]));
47268
47363
  const recentSessionById = new Map(recentSessions.map((entry) => [entry.providerSessionId, entry]));
47269
- const providerMeta = this.deps.providerLoader.getMeta(providerType);
47270
47364
  const canResumeById = supportsExplicitSessionResume(providerMeta?.resume);
47271
47365
  return {
47272
47366
  success: true,
@@ -47286,10 +47380,14 @@ Run 'adhdev doctor' for detailed diagnostics.`
47286
47380
  messageCount: session.messageCount,
47287
47381
  firstMessageAt: session.firstMessageAt,
47288
47382
  lastMessageAt: session.lastMessageAt,
47289
- canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById
47383
+ canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById,
47384
+ historySource: session.source,
47385
+ sourcePath: session.sourcePath,
47386
+ sourceMtimeMs: session.sourceMtimeMs
47290
47387
  };
47291
47388
  }),
47292
- hasMore
47389
+ hasMore,
47390
+ source
47293
47391
  };
47294
47392
  }
47295
47393
  // ─── restart_session: IDE / CLI / ACP unified ───