@adhdev/daemon-core 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
@@ -985,6 +985,8 @@ function validateReadChatResultPayload(raw, source = "read_chat") {
985
985
  if (raw.summaryMetadata !== void 0) normalized.summaryMetadata = raw.summaryMetadata;
986
986
  if (Array.isArray(raw.effects)) normalized.effects = raw.effects;
987
987
  if (typeof raw.providerSessionId === "string") normalized.providerSessionId = raw.providerSessionId;
988
+ if (raw.transcriptAuthority === "provider" || raw.transcriptAuthority === "daemon") normalized.transcriptAuthority = raw.transcriptAuthority;
989
+ if (raw.coverage === "full" || raw.coverage === "tail" || raw.coverage === "current-turn") normalized.coverage = raw.coverage;
988
990
  return normalized;
989
991
  }
990
992
  var VALID_STATUSES, VALID_ROLES, VALID_BUBBLE_STATES, VALID_TURN_STATUSES;
@@ -2059,7 +2061,8 @@ __export(provider_cli_adapter_exports, {
2059
2061
  ProviderCliAdapter: () => ProviderCliAdapter,
2060
2062
  appendBoundedText: () => appendBoundedText,
2061
2063
  normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime,
2062
- sanitizeCliStandardMessageContent: () => sanitizeCliStandardMessageContent
2064
+ sanitizeCliStandardMessageContent: () => sanitizeCliStandardMessageContent,
2065
+ trimLastAssistantEchoForCliMessages: () => trimLastAssistantEchoForCliMessages
2063
2066
  });
2064
2067
  function normalizeComparableTranscriptText(value) {
2065
2068
  return sanitizeTerminalText(String(value || "")).replace(/\s+/g, " ").trim();
@@ -2155,6 +2158,19 @@ function sanitizeCommittedMessageForDisplay(message) {
2155
2158
  if (content === message.content) return message;
2156
2159
  return { ...message, content };
2157
2160
  }
2161
+ function trimLastAssistantEchoForCliMessages(messages, prompt) {
2162
+ if (!prompt) return;
2163
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
2164
+ const message = messages[index];
2165
+ if (!message || message.role !== "assistant" || typeof message.content !== "string") continue;
2166
+ if ((message.kind || "standard") !== "standard") continue;
2167
+ message.content = trimPromptEchoPrefix(message.content, prompt);
2168
+ if (!message.content.trim()) {
2169
+ messages.splice(index, 1);
2170
+ }
2171
+ return;
2172
+ }
2173
+ }
2158
2174
  var os10, COMMITTED_ACTIVITY_PREFIX_BLOCK_RE, ProviderCliAdapter;
2159
2175
  var init_provider_cli_adapter = __esm({
2160
2176
  "src/cli-adapters/provider-cli-adapter.ts"() {
@@ -2352,7 +2368,14 @@ var init_provider_cli_adapter = __esm({
2352
2368
  }
2353
2369
  return null;
2354
2370
  }
2371
+ providerOwnsTranscript() {
2372
+ return this.provider.transcriptAuthority === "provider";
2373
+ }
2374
+ shouldUseFullProviderTranscriptContext() {
2375
+ return this.providerOwnsTranscript() && this.provider.transcriptContext === "full";
2376
+ }
2355
2377
  selectParseBaseMessages(baseMessages) {
2378
+ if (this.shouldUseFullProviderTranscriptContext()) return baseMessages;
2356
2379
  if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
2357
2380
  return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
2358
2381
  }
@@ -2835,9 +2858,7 @@ var init_provider_cli_adapter = __esm({
2835
2858
  );
2836
2859
  }
2837
2860
  trimLastAssistantEcho(messages, prompt) {
2838
- if (!prompt) return;
2839
- const last = [...messages].reverse().find((m) => m.role === "assistant" && typeof m.content === "string");
2840
- if (last) last.content = trimPromptEchoPrefix(last.content, prompt);
2861
+ trimLastAssistantEchoForCliMessages(messages, prompt);
2841
2862
  }
2842
2863
  clearAllTimers() {
2843
2864
  if (this.responseTimeout) {
@@ -3691,7 +3712,8 @@ var init_provider_cli_adapter = __esm({
3691
3712
  title: parsed.title || this.cliName,
3692
3713
  messages: hydratedMessages,
3693
3714
  activeModal: parsed.activeModal ?? this.activeModal,
3694
- providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0
3715
+ providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0,
3716
+ ...this.providerOwnsTranscript() ? { transcriptAuthority: "provider", coverage: this.shouldUseFullProviderTranscriptContext() ? "full" : "tail" } : {}
3695
3717
  };
3696
3718
  } else {
3697
3719
  const messages = [...this.committedMessages];
@@ -8025,6 +8047,27 @@ var ChatHistoryWriter = class {
8025
8047
  return name.replace(/[^a-zA-Z0-9_-]/g, "_");
8026
8048
  }
8027
8049
  };
8050
+ function pageHistoryRecords(agentType, records, offset = 0, limit = 30, excludeRecentCount = 0, historyBehavior) {
8051
+ const allMessages = records.map((message) => sanitizeHistoryMessage(agentType, message)).filter(Boolean);
8052
+ allMessages.sort((a, b) => a.receivedAt - b.receivedAt);
8053
+ const chronological = [];
8054
+ let lastTurn = null;
8055
+ for (const message of allMessages) {
8056
+ const previous = chronological[chronological.length - 1];
8057
+ if (isAdjacentHistoryDuplicate(agentType, previous, message)) continue;
8058
+ if (message.role !== "system" && isAdjacentHistoryDuplicate(agentType, lastTurn, message)) continue;
8059
+ chronological.push(message);
8060
+ if (message.role !== "system") lastTurn = message;
8061
+ }
8062
+ const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
8063
+ const boundedLimit = Math.max(1, limit);
8064
+ const boundedOffset = Math.max(0, offset);
8065
+ const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
8066
+ const endExclusive = Math.max(0, collapsed.length - boundedExclude - boundedOffset);
8067
+ const startInclusive = Math.max(0, endExclusive - boundedLimit);
8068
+ const sliced = collapsed.slice(startInclusive, endExclusive);
8069
+ return { messages: sliced, hasMore: startInclusive > 0 };
8070
+ }
8028
8071
  function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
8029
8072
  try {
8030
8073
  const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
@@ -8050,25 +8093,7 @@ function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, ex
8050
8093
  }
8051
8094
  }
8052
8095
  }
8053
- allMessages.sort((a, b) => a.receivedAt - b.receivedAt);
8054
- const chronological = [];
8055
- let lastTurn = null;
8056
- for (const message of allMessages) {
8057
- const previous = chronological[chronological.length - 1];
8058
- if (isAdjacentHistoryDuplicate(agentType, previous, message)) continue;
8059
- if (message.role !== "system" && isAdjacentHistoryDuplicate(agentType, lastTurn, message)) continue;
8060
- chronological.push(message);
8061
- if (message.role !== "system") lastTurn = message;
8062
- }
8063
- const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
8064
- const boundedLimit = Math.max(1, limit);
8065
- const boundedOffset = Math.max(0, offset);
8066
- const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
8067
- const endExclusive = Math.max(0, collapsed.length - boundedExclude - boundedOffset);
8068
- const startInclusive = Math.max(0, endExclusive - boundedLimit);
8069
- const sliced = collapsed.slice(startInclusive, endExclusive);
8070
- const hasMore = startInclusive > 0;
8071
- return { messages: sliced, hasMore };
8096
+ return pageHistoryRecords(agentType, allMessages, offset, limit, excludeRecentCount, historyBehavior);
8072
8097
  } catch {
8073
8098
  return { messages: [], hasMore: false };
8074
8099
  }
@@ -8135,29 +8160,6 @@ function listSavedHistorySessions(agentType, options = {}, historyBehavior) {
8135
8160
  return { sessions: [], hasMore: false };
8136
8161
  }
8137
8162
  }
8138
- function normalizeCanonicalHermesMessageContent(content) {
8139
- if (typeof content === "string") return content.trim();
8140
- if (content == null) return "";
8141
- try {
8142
- return JSON.stringify(content).trim();
8143
- } catch {
8144
- return String(content).trim();
8145
- }
8146
- }
8147
- function extractCanonicalHermesMessageTimestamp(message, fallbackTs) {
8148
- const numericTimestamp = Number(message.receivedAt || message.timestamp || message.ts || 0);
8149
- if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
8150
- const stringTimestamp = typeof message.ts === "string" ? Date.parse(message.ts) : typeof message.timestamp === "string" ? Date.parse(message.timestamp) : NaN;
8151
- if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
8152
- return fallbackTs;
8153
- }
8154
- function extractTimestampValue(value) {
8155
- const numericTimestamp = Number(value || 0);
8156
- if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
8157
- const stringTimestamp = typeof value === "string" ? Date.parse(value) : NaN;
8158
- if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
8159
- return 0;
8160
- }
8161
8163
  function readExistingSessionStartRecord(agentType, historySessionId) {
8162
8164
  try {
8163
8165
  const dir = path7.join(HISTORY_DIR, agentType);
@@ -8203,232 +8205,193 @@ function rewriteCanonicalSavedHistory(agentType, historySessionId, records) {
8203
8205
  return false;
8204
8206
  }
8205
8207
  }
8206
- function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
8208
+ function getNativeHistoryScriptName(canonicalHistory, key) {
8209
+ const configured = canonicalHistory?.scripts?.[key];
8210
+ if (typeof configured === "string" && configured.trim()) return configured.trim();
8211
+ return key === "readSession" ? "readNativeHistory" : "listNativeHistory";
8212
+ }
8213
+ function getProviderNativeHistoryScript(scripts, canonicalHistory, key) {
8214
+ if (!canonicalHistory?.scripts) return null;
8215
+ const fn = scripts?.[getNativeHistoryScriptName(canonicalHistory, key)];
8216
+ return typeof fn === "function" ? fn : null;
8217
+ }
8218
+ function normalizeProviderNativeHistoryRecords(agentType, historySessionId, records) {
8219
+ if (!Array.isArray(records)) return [];
8220
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
8221
+ return records.map((record) => sanitizeHistoryMessage(agentType, {
8222
+ ts: typeof record?.ts === "string" ? record.ts : new Date(Number(record?.receivedAt) || Date.now()).toISOString(),
8223
+ receivedAt: Number(record?.receivedAt) || Date.parse(record?.ts || "") || Date.now(),
8224
+ role: record?.role,
8225
+ content: String(record?.content || ""),
8226
+ kind: record?.kind || (record?.role === "system" ? "session_start" : "standard"),
8227
+ senderName: record?.senderName,
8228
+ agent: agentType,
8229
+ instanceId: record?.instanceId,
8230
+ historySessionId: normalizeSavedHistorySessionId(record?.historySessionId || normalizedSessionId),
8231
+ sessionTitle: record?.sessionTitle,
8232
+ workspace: record?.workspace
8233
+ })).filter(Boolean);
8234
+ }
8235
+ function callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, historySessionId, workspace) {
8236
+ const fn = getProviderNativeHistoryScript(scripts, canonicalHistory, "readSession");
8237
+ if (!fn) return null;
8238
+ const result = fn({
8239
+ agentType,
8240
+ sessionId: historySessionId,
8241
+ historySessionId,
8242
+ workspace,
8243
+ format: canonicalHistory?.format,
8244
+ watchPath: canonicalHistory?.watchPath,
8245
+ args: { sessionId: historySessionId, historySessionId, workspace }
8246
+ });
8247
+ if (!result || typeof result !== "object") return null;
8248
+ const records = normalizeProviderNativeHistoryRecords(agentType, historySessionId, result.messages || result.records);
8249
+ if (records.length === 0) return null;
8250
+ return {
8251
+ records,
8252
+ sourcePath: typeof result.sourcePath === "string" ? result.sourcePath : "",
8253
+ sourceMtimeMs: Number(result.sourceMtimeMs) || 0
8254
+ };
8255
+ }
8256
+ function buildNativeHistoryReadResult(agentType, canonicalHistory, scripts, historySessionId, workspace) {
8257
+ const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || "");
8258
+ if (!canonicalHistory || !normalizedSessionId || !isNativeSourceCanonicalHistory(canonicalHistory)) return null;
8259
+ return callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace);
8260
+ }
8261
+ function materializeNativeHistoryToMirror(agentType, canonicalHistory, historySessionId, workspace, scripts) {
8207
8262
  const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
8208
8263
  if (!normalizedSessionId) return false;
8264
+ const nativeResult = callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace);
8265
+ const nativeRecords = nativeResult?.records || [];
8266
+ if (nativeRecords.length === 0) return false;
8267
+ const normalizedRecords = nativeRecords.map((record) => ({
8268
+ ...record,
8269
+ agent: agentType,
8270
+ historySessionId: normalizedSessionId
8271
+ }));
8272
+ const existingSessionStart = readExistingSessionStartRecord(agentType, normalizedSessionId);
8273
+ const records = existingSessionStart && normalizedRecords[0]?.kind !== "session_start" ? [{ ...existingSessionStart, historySessionId: normalizedSessionId, agent: agentType }, ...normalizedRecords] : normalizedRecords;
8274
+ return rewriteCanonicalSavedHistory(agentType, normalizedSessionId, records);
8275
+ }
8276
+ function materializeProviderNativeHistory(agentType, canonicalHistory, historySessionId, workspace, scripts) {
8277
+ if (!canonicalHistory || canonicalHistory.mode !== "materialized-mirror") return false;
8278
+ return materializeNativeHistoryToMirror(agentType, canonicalHistory, historySessionId, workspace, scripts);
8279
+ }
8280
+ function isNativeSourceCanonicalHistory(canonicalHistory) {
8281
+ if (!canonicalHistory) return false;
8282
+ if (canonicalHistory.mode === "disabled") return false;
8283
+ if (canonicalHistory.mode === "materialized-mirror") return false;
8284
+ return true;
8285
+ }
8286
+ function readProviderChatHistory(agentType, options = {}) {
8287
+ if (isNativeSourceCanonicalHistory(options.canonicalHistory) && options.historySessionId) {
8288
+ const nativeResult = buildNativeHistoryReadResult(agentType, options.canonicalHistory, options.scripts, options.historySessionId, options.workspace);
8289
+ if (!nativeResult) return { messages: [], hasMore: false, source: "native-unavailable" };
8290
+ return {
8291
+ ...pageHistoryRecords(agentType, nativeResult.records, options.offset || 0, options.limit || 30, options.excludeRecentCount || 0, options.historyBehavior),
8292
+ source: "provider-native",
8293
+ sourcePath: nativeResult.sourcePath,
8294
+ sourceMtimeMs: nativeResult.sourceMtimeMs
8295
+ };
8296
+ }
8297
+ return {
8298
+ ...readChatHistory(agentType, options.offset || 0, options.limit || 30, options.historySessionId, options.excludeRecentCount || 0, options.historyBehavior),
8299
+ source: "adhdev-mirror"
8300
+ };
8301
+ }
8302
+ function buildNativeSessionSummary(agentType, historySessionId, records, sourcePath) {
8303
+ const visible = pageHistoryRecords(agentType, records, 0, Number.MAX_SAFE_INTEGER).messages;
8304
+ if (visible.length === 0) return null;
8305
+ let sourceMtimeMs = 0;
8209
8306
  try {
8210
- const sessionFilePath = path7.join(os5.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
8211
- if (!fs3.existsSync(sessionFilePath)) return false;
8212
- const raw = JSON.parse(fs3.readFileSync(sessionFilePath, "utf-8"));
8213
- const canonicalMessages = Array.isArray(raw.messages) ? raw.messages : [];
8214
- const dir = path7.join(HISTORY_DIR, "hermes-cli");
8215
- fs3.mkdirSync(dir, { recursive: true });
8216
- const existingSessionStart = readExistingSessionStartRecord("hermes-cli", normalizedSessionId);
8217
- const records = [];
8218
- if (existingSessionStart) {
8219
- records.push({
8220
- ...existingSessionStart,
8221
- historySessionId: normalizedSessionId
8222
- });
8223
- }
8224
- let fallbackTs = Date.parse(raw.session_start || raw.last_updated || "") || Date.now();
8225
- for (const message of canonicalMessages) {
8226
- const role = String(message.role || "").trim();
8227
- const content = normalizeCanonicalHermesMessageContent(message.content);
8228
- if (!content) continue;
8229
- const receivedAt = extractCanonicalHermesMessageTimestamp(message, fallbackTs);
8230
- fallbackTs = receivedAt + 1;
8231
- if (role === "user") {
8232
- records.push({
8233
- ts: new Date(receivedAt).toISOString(),
8234
- receivedAt,
8235
- role: "user",
8236
- content,
8237
- kind: "standard",
8238
- agent: "hermes-cli",
8239
- historySessionId: normalizedSessionId
8240
- });
8241
- continue;
8242
- }
8243
- if (role === "assistant") {
8244
- records.push({
8245
- ts: new Date(receivedAt).toISOString(),
8246
- receivedAt,
8247
- role: "assistant",
8248
- content,
8249
- kind: "standard",
8250
- agent: "hermes-cli",
8251
- historySessionId: normalizedSessionId
8252
- });
8253
- continue;
8254
- }
8255
- if (role === "tool") {
8256
- records.push({
8257
- ts: new Date(receivedAt).toISOString(),
8258
- receivedAt,
8259
- role: "assistant",
8260
- content,
8261
- kind: "tool",
8262
- senderName: "Tool",
8263
- agent: "hermes-cli",
8264
- historySessionId: normalizedSessionId
8265
- });
8266
- }
8267
- }
8268
- return rewriteCanonicalSavedHistory("hermes-cli", normalizedSessionId, records);
8307
+ sourceMtimeMs = fs3.statSync(sourcePath).mtimeMs;
8269
8308
  } catch {
8270
- return false;
8271
8309
  }
8310
+ const firstMessageAt = visible[0]?.receivedAt || sourceMtimeMs || Date.now();
8311
+ const lastMessageAt = visible[visible.length - 1]?.receivedAt || firstMessageAt;
8312
+ const lastNonSystem = [...visible].reverse().find((message) => message.role !== "system") || visible[visible.length - 1];
8313
+ const firstSystem = visible.find((message) => message.kind === "session_start");
8314
+ return {
8315
+ historySessionId,
8316
+ sessionTitle: lastNonSystem?.content,
8317
+ messageCount: visible.length,
8318
+ firstMessageAt,
8319
+ lastMessageAt,
8320
+ preview: lastNonSystem?.content,
8321
+ workspace: firstSystem?.workspace || (firstSystem?.kind === "session_start" ? firstSystem.content : void 0),
8322
+ source: "provider-native",
8323
+ sourcePath,
8324
+ sourceMtimeMs
8325
+ };
8272
8326
  }
8273
- function resolveClaudeProjectTranscriptPath(historySessionId, workspace) {
8274
- const claudeProjectsDir = path7.join(os5.homedir(), ".claude", "projects");
8275
- if (!fs3.existsSync(claudeProjectsDir)) return null;
8276
- const normalizedWorkspace = typeof workspace === "string" ? workspace.trim() : "";
8277
- if (normalizedWorkspace) {
8278
- const directPath = path7.join(claudeProjectsDir, normalizedWorkspace.replace(/[\\/]/g, "-"), `${historySessionId}.jsonl`);
8279
- if (fs3.existsSync(directPath)) return directPath;
8280
- }
8281
- const stack = [claudeProjectsDir];
8282
- while (stack.length > 0) {
8283
- const current = stack.pop();
8284
- if (!current) continue;
8285
- for (const entry of fs3.readdirSync(current, { withFileTypes: true })) {
8286
- const entryPath = path7.join(current, entry.name);
8287
- if (entry.isDirectory()) {
8288
- stack.push(entryPath);
8289
- continue;
8290
- }
8291
- if (entry.isFile() && entry.name === `${historySessionId}.jsonl`) {
8292
- return entryPath;
8293
- }
8294
- }
8295
- }
8296
- return null;
8327
+ function normalizeProviderNativeHistorySessionSummary(agentType, item) {
8328
+ const historySessionId = normalizeSavedHistorySessionId(item?.historySessionId || item?.sessionId || "");
8329
+ if (!historySessionId) return null;
8330
+ const sourcePath = typeof item?.sourcePath === "string" ? item.sourcePath : "";
8331
+ const sourceMtimeMs = Number(item?.sourceMtimeMs) || 0;
8332
+ const firstMessageAt = Number(item?.firstMessageAt) || sourceMtimeMs || Date.now();
8333
+ const lastMessageAt = Number(item?.lastMessageAt) || firstMessageAt;
8334
+ const messageCount = Math.max(0, Number(item?.messageCount) || 0);
8335
+ return {
8336
+ historySessionId,
8337
+ sessionTitle: typeof item?.sessionTitle === "string" ? item.sessionTitle : void 0,
8338
+ messageCount,
8339
+ firstMessageAt,
8340
+ lastMessageAt,
8341
+ preview: typeof item?.preview === "string" ? item.preview : void 0,
8342
+ workspace: typeof item?.workspace === "string" ? item.workspace : void 0,
8343
+ source: "provider-native",
8344
+ sourcePath,
8345
+ sourceMtimeMs
8346
+ };
8297
8347
  }
8298
- function extractClaudeAssistantContentParts(content) {
8299
- if (typeof content === "string") {
8300
- const trimmed = content.trim();
8301
- return trimmed ? [{ content: trimmed, kind: "standard", role: "assistant" }] : [];
8302
- }
8303
- if (!Array.isArray(content)) return [];
8304
- const parts = [];
8305
- for (const block of content) {
8306
- if (!block || typeof block !== "object") continue;
8307
- const record = block;
8308
- const type = String(record.type || "").trim();
8309
- if (type === "text") {
8310
- const text = String(record.text || "").trim();
8311
- if (text) parts.push({ content: text, kind: "standard", role: "assistant" });
8348
+ function collectProviderScriptNativeHistorySessionSummaries(agentType, canonicalHistory, scripts) {
8349
+ const fn = getProviderNativeHistoryScript(scripts, canonicalHistory, "listSessions");
8350
+ if (!fn) return null;
8351
+ const result = fn({
8352
+ agentType,
8353
+ format: canonicalHistory.format,
8354
+ watchPath: canonicalHistory.watchPath,
8355
+ args: {}
8356
+ });
8357
+ if (!result || typeof result !== "object") return [];
8358
+ const sessions = Array.isArray(result.sessions) ? result.sessions : [];
8359
+ const summaries = [];
8360
+ for (const item of sessions) {
8361
+ if (Array.isArray(item?.messages || item?.records)) {
8362
+ const historySessionId = normalizeSavedHistorySessionId(item?.historySessionId || item?.sessionId || "");
8363
+ if (!historySessionId) continue;
8364
+ const records = normalizeProviderNativeHistoryRecords(agentType, historySessionId, item.messages || item.records);
8365
+ const summary2 = buildNativeSessionSummary(agentType, historySessionId, records, typeof item?.sourcePath === "string" ? item.sourcePath : "");
8366
+ if (summary2) {
8367
+ if (Number(item?.sourceMtimeMs)) summary2.sourceMtimeMs = Number(item.sourceMtimeMs);
8368
+ summaries.push(summary2);
8369
+ }
8312
8370
  continue;
8313
8371
  }
8314
- if (type === "tool_use") {
8315
- const name = String(record.name || "").trim() || "Tool";
8316
- const input = record.input && typeof record.input === "object" ? record.input : null;
8317
- const command = input ? String(input.command || "").trim() : "";
8318
- const summary = command ? `${name}: ${command}` : name;
8319
- if (summary) parts.push({ content: summary, kind: "tool", senderName: "Tool", role: "assistant" });
8320
- }
8372
+ const summary = normalizeProviderNativeHistorySessionSummary(agentType, item);
8373
+ if (summary) summaries.push(summary);
8321
8374
  }
8322
- return parts;
8375
+ return sortSavedHistorySessionSummaries(summaries);
8323
8376
  }
8324
- function extractClaudeUserContentParts(content) {
8325
- if (typeof content === "string") {
8326
- const trimmed = content.trim();
8327
- return trimmed ? [{ role: "user", content: trimmed, kind: "standard" }] : [];
8328
- }
8329
- if (!Array.isArray(content)) return [];
8330
- const parts = [];
8331
- for (const block of content) {
8332
- if (!block || typeof block !== "object") continue;
8333
- const record = block;
8334
- const type = String(record.type || "").trim();
8335
- if (type === "text") {
8336
- const text = String(record.text || "").trim();
8337
- if (text) parts.push({ role: "user", content: text, kind: "standard" });
8338
- continue;
8339
- }
8340
- if (type === "tool_result") {
8341
- const rawContent = record.content;
8342
- const text = typeof rawContent === "string" ? rawContent.trim() : Array.isArray(rawContent) ? rawContent.map((entry) => {
8343
- if (typeof entry === "string") return entry.trim();
8344
- if (!entry || typeof entry !== "object") return "";
8345
- const nested = entry;
8346
- if (typeof nested.text === "string") return nested.text.trim();
8347
- if (typeof nested.content === "string") return nested.content.trim();
8348
- return "";
8349
- }).filter(Boolean).join("\n") : "";
8350
- if (text) parts.push({ role: "assistant", content: text, kind: "tool", senderName: "Tool" });
8351
- }
8352
- }
8353
- return parts;
8377
+ function collectNativeHistorySessionSummaries(agentType, canonicalHistory, scripts) {
8378
+ return collectProviderScriptNativeHistorySessionSummaries(agentType, canonicalHistory, scripts) || [];
8354
8379
  }
8355
- function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
8356
- const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
8357
- if (!normalizedSessionId) return false;
8358
- try {
8359
- const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
8360
- if (!transcriptPath) return false;
8361
- const lines = fs3.readFileSync(transcriptPath, "utf-8").split("\n").filter(Boolean);
8362
- const records = [];
8363
- const existingSessionStart = readExistingSessionStartRecord("claude-cli", normalizedSessionId);
8364
- if (existingSessionStart) {
8365
- records.push({
8366
- ...existingSessionStart,
8367
- historySessionId: normalizedSessionId
8368
- });
8369
- }
8370
- let fallbackTs = Date.now();
8371
- for (const line of lines) {
8372
- let parsed = null;
8373
- try {
8374
- parsed = JSON.parse(line);
8375
- } catch {
8376
- parsed = null;
8377
- }
8378
- if (!parsed) continue;
8379
- const parsedSessionId = String(parsed.sessionId || "").trim();
8380
- if (parsedSessionId && parsedSessionId !== normalizedSessionId) continue;
8381
- const receivedAt = extractTimestampValue(parsed.timestamp) || fallbackTs;
8382
- fallbackTs = receivedAt + 1;
8383
- const parsedWorkspace = String(parsed.cwd || workspace || "").trim();
8384
- if (records.length === 0 && parsedWorkspace) {
8385
- records.push({
8386
- ts: new Date(receivedAt).toISOString(),
8387
- receivedAt,
8388
- role: "system",
8389
- kind: "session_start",
8390
- content: parsedWorkspace,
8391
- agent: "claude-cli",
8392
- historySessionId: normalizedSessionId,
8393
- workspace: parsedWorkspace
8394
- });
8395
- }
8396
- const type = String(parsed.type || "").trim();
8397
- const message = parsed.message && typeof parsed.message === "object" ? parsed.message : null;
8398
- if (type === "user" && message) {
8399
- for (const part of extractClaudeUserContentParts(message.content)) {
8400
- records.push({
8401
- ts: new Date(receivedAt).toISOString(),
8402
- receivedAt,
8403
- role: part.role,
8404
- content: part.content,
8405
- kind: part.kind,
8406
- senderName: part.senderName,
8407
- agent: "claude-cli",
8408
- historySessionId: normalizedSessionId
8409
- });
8410
- }
8411
- continue;
8412
- }
8413
- if (type === "assistant" && message) {
8414
- for (const part of extractClaudeAssistantContentParts(message.content)) {
8415
- records.push({
8416
- ts: new Date(receivedAt).toISOString(),
8417
- receivedAt,
8418
- role: "assistant",
8419
- content: part.content,
8420
- kind: part.kind,
8421
- senderName: part.senderName,
8422
- agent: "claude-cli",
8423
- historySessionId: normalizedSessionId
8424
- });
8425
- }
8426
- }
8427
- }
8428
- return rewriteCanonicalSavedHistory("claude-cli", normalizedSessionId, records);
8429
- } catch {
8430
- return false;
8380
+ function listProviderHistorySessions(agentType, options = {}) {
8381
+ if (isNativeSourceCanonicalHistory(options.canonicalHistory)) {
8382
+ const offset = Math.max(0, options.offset || 0);
8383
+ const limit = Math.max(1, options.limit || 30);
8384
+ const summaries = collectNativeHistorySessionSummaries(agentType, options.canonicalHistory, options.scripts);
8385
+ return {
8386
+ sessions: summaries.slice(offset, offset + limit),
8387
+ hasMore: offset + limit < summaries.length,
8388
+ source: "provider-native"
8389
+ };
8431
8390
  }
8391
+ return {
8392
+ ...listSavedHistorySessions(agentType, { offset: options.offset, limit: options.limit }, options.historyBehavior),
8393
+ source: "adhdev-mirror"
8394
+ };
8432
8395
  }
8433
8396
 
8434
8397
  // src/providers/provider-patch-state.ts
@@ -11043,7 +11006,17 @@ async function handleChatHistory(h, args) {
11043
11006
  const visibleCount = Array.isArray(status?.messages) ? status.messages.length : 0;
11044
11007
  if (visibleCount > excludeRecentCount) excludeRecentCount = visibleCount;
11045
11008
  }
11046
- const result = readChatHistory(agentStr, offset || 0, limit || 30, historySessionId, excludeRecentCount);
11009
+ const workspace = typeof args?.workspace === "string" ? args.workspace : typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : void 0;
11010
+ const result = readProviderChatHistory(agentStr, {
11011
+ canonicalHistory: provider?.canonicalHistory,
11012
+ historySessionId,
11013
+ workspace,
11014
+ offset: offset || 0,
11015
+ limit: limit || 30,
11016
+ excludeRecentCount,
11017
+ historyBehavior: provider?.historyBehavior,
11018
+ scripts: provider?.scripts
11019
+ });
11047
11020
  return { success: true, ...result, agent: agentStr };
11048
11021
  } catch (e) {
11049
11022
  return { success: false, error: e.message };
@@ -11068,7 +11041,8 @@ async function handleReadChat(h, args) {
11068
11041
  }
11069
11042
  const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
11070
11043
  const adapterStatus = adapter.getStatus();
11071
- const shouldPreferAdapterMessages = Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
11044
+ const parsedIsProviderAuthoritative = parsedRecord?.transcriptAuthority === "provider" || parsedRecord?.coverage === "full";
11045
+ const shouldPreferAdapterMessages = !parsedIsProviderAuthoritative && Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
11072
11046
  const parsedShowsApproval = hasNonEmptyModalButtons(parsedRecord?.activeModal) && parsedRecord?.status === "waiting_approval";
11073
11047
  const status = parsedRecord ? {
11074
11048
  ...parsedRecord,
@@ -11078,6 +11052,8 @@ async function handleReadChat(h, args) {
11078
11052
  } : adapterStatus;
11079
11053
  const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
11080
11054
  const providerSessionId = typeof parsedRecord?.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
11055
+ const transcriptAuthority = parsedRecord?.transcriptAuthority === "provider" || parsedRecord?.transcriptAuthority === "daemon" ? parsedRecord.transcriptAuthority : void 0;
11056
+ const coverage = parsedRecord?.coverage === "full" || parsedRecord?.coverage === "tail" || parsedRecord?.coverage === "current-turn" ? parsedRecord.coverage : void 0;
11081
11057
  if (status) {
11082
11058
  LOG.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}`);
11083
11059
  return buildReadChatCommandResult({
@@ -11096,7 +11072,9 @@ async function handleReadChat(h, args) {
11096
11072
  returnedMsgCount: Array.isArray(status.messages) ? status.messages.length : 0
11097
11073
  },
11098
11074
  ...title ? { title } : {},
11099
- ...providerSessionId ? { providerSessionId } : {}
11075
+ ...providerSessionId ? { providerSessionId } : {},
11076
+ ...transcriptAuthority ? { transcriptAuthority } : {},
11077
+ ...coverage ? { coverage } : {}
11100
11078
  }, args);
11101
11079
  }
11102
11080
  }
@@ -13511,11 +13489,8 @@ var CliProviderInstance = class {
13511
13489
  historyWriter;
13512
13490
  runtimeMessages = [];
13513
13491
  lastPersistedHistoryMessages = [];
13514
- lastCanonicalHermesSyncMtimeMs = 0;
13515
- lastCanonicalHermesExistCheckAt = 0;
13516
- lastCanonicalHermesWatchPath = void 0;
13517
- lastCanonicalClaudeRebuildMtimeMs = 0;
13518
- lastCanonicalClaudeCheckAt = 0;
13492
+ lastNativeSourceCanonicalCheckAt = 0;
13493
+ lastNativeSourceCanonicalCacheKey = void 0;
13519
13494
  cachedSqliteDb = null;
13520
13495
  cachedSqliteDbPath = null;
13521
13496
  cachedSqliteDbMissingUntil = 0;
@@ -14215,41 +14190,45 @@ ${effect.notification.body || ""}`.trim();
14215
14190
  if (!this.providerSessionId) return false;
14216
14191
  const canonicalHistory = this.provider.canonicalHistory;
14217
14192
  if (!canonicalHistory) return false;
14193
+ if (isNativeSourceCanonicalHistory(canonicalHistory)) {
14194
+ const cacheKey = [this.type, this.providerSessionId, this.workingDir].join("\0");
14195
+ const now = Date.now();
14196
+ if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
14197
+ return true;
14198
+ }
14199
+ this.lastNativeSourceCanonicalCacheKey = cacheKey;
14200
+ this.lastNativeSourceCanonicalCheckAt = now;
14201
+ const restoredHistory = readProviderChatHistory(this.type, {
14202
+ canonicalHistory,
14203
+ historySessionId: this.providerSessionId,
14204
+ workspace: this.workingDir,
14205
+ offset: 0,
14206
+ limit: Number.MAX_SAFE_INTEGER,
14207
+ historyBehavior: this.provider.historyBehavior,
14208
+ scripts: this.provider.scripts
14209
+ });
14210
+ if (restoredHistory.source === "provider-native") {
14211
+ this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
14212
+ role: message.role,
14213
+ content: message.content,
14214
+ kind: message.kind,
14215
+ senderName: message.senderName,
14216
+ receivedAt: message.receivedAt
14217
+ }));
14218
+ }
14219
+ return true;
14220
+ }
14218
14221
  try {
14219
- let rebuilt = false;
14220
- if (canonicalHistory.format === "hermes-json") {
14221
- const watchPath = canonicalHistory.watchPath.replace(/^~/, os11.homedir()).replace("{{sessionId}}", this.providerSessionId);
14222
- const now = Date.now();
14223
- if (watchPath !== this.lastCanonicalHermesWatchPath || now - this.lastCanonicalHermesExistCheckAt >= 2e3) {
14224
- this.lastCanonicalHermesWatchPath = watchPath;
14225
- this.lastCanonicalHermesExistCheckAt = now;
14226
- if (!fs5.existsSync(watchPath)) return false;
14227
- } else if (this.lastCanonicalHermesSyncMtimeMs === 0) {
14228
- if (!fs5.existsSync(watchPath)) return false;
14229
- }
14230
- const stat = fs5.statSync(watchPath);
14231
- if (stat.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
14232
- rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
14233
- if (rebuilt) this.lastCanonicalHermesSyncMtimeMs = stat.mtimeMs;
14234
- } else if (canonicalHistory.format === "claude-jsonl") {
14235
- const now = Date.now();
14236
- if (now - this.lastCanonicalClaudeCheckAt < 2e3 && this.lastCanonicalClaudeRebuildMtimeMs !== 0) {
14237
- return true;
14238
- }
14239
- this.lastCanonicalClaudeCheckAt = now;
14240
- const claudeProjectsDir = path11.join(os11.homedir(), ".claude", "projects");
14241
- const workspaceSegment = typeof this.workingDir === "string" ? this.workingDir.replace(/[\\/]/g, "-").replace(/^-+/, "") : "";
14242
- const transcriptFile = path11.join(claudeProjectsDir, workspaceSegment, `${this.providerSessionId}.jsonl`);
14243
- let transcriptMtime = 0;
14244
- try {
14245
- transcriptMtime = fs5.statSync(transcriptFile).mtimeMs;
14246
- } catch {
14247
- }
14248
- if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalClaudeRebuildMtimeMs) return true;
14249
- rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
14250
- if (rebuilt) this.lastCanonicalClaudeRebuildMtimeMs = transcriptMtime || Date.now();
14222
+ const cacheKey = [this.type, this.providerSessionId, this.workingDir, canonicalHistory.mode || "materialized-mirror"].join("\0");
14223
+ const now = Date.now();
14224
+ if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
14225
+ return true;
14226
+ }
14227
+ this.lastNativeSourceCanonicalCacheKey = cacheKey;
14228
+ this.lastNativeSourceCanonicalCheckAt = now;
14229
+ if (!materializeProviderNativeHistory(this.type, canonicalHistory, this.providerSessionId, this.workingDir, this.provider.scripts)) {
14230
+ return false;
14251
14231
  }
14252
- if (!rebuilt) return false;
14253
14232
  const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
14254
14233
  this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
14255
14234
  role: message.role,
@@ -14266,8 +14245,18 @@ ${effect.notification.body || ""}`.trim();
14266
14245
  restorePersistedHistoryFromCurrentSession() {
14267
14246
  if (!this.providerSessionId) return;
14268
14247
  this.syncCanonicalSavedHistoryIfNeeded();
14269
- this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
14270
- const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
14248
+ const restoredHistory = isNativeSourceCanonicalHistory(this.provider.canonicalHistory) ? readProviderChatHistory(this.type, {
14249
+ canonicalHistory: this.provider.canonicalHistory,
14250
+ historySessionId: this.providerSessionId,
14251
+ workspace: this.workingDir,
14252
+ offset: 0,
14253
+ limit: Number.MAX_SAFE_INTEGER,
14254
+ historyBehavior: this.provider.historyBehavior,
14255
+ scripts: this.provider.scripts
14256
+ }) : (() => {
14257
+ this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
14258
+ return readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
14259
+ })();
14271
14260
  this.historyWriter.seedSessionHistory(
14272
14261
  this.type,
14273
14262
  restoredHistory.messages,
@@ -16398,6 +16387,7 @@ function validateProviderDefinition(raw) {
16398
16387
  warnings.push("Extension providers should have extensionId");
16399
16388
  }
16400
16389
  validateCapabilities(provider, controls, errors);
16390
+ validateCanonicalHistory(provider.canonicalHistory, errors);
16401
16391
  for (const control of controls) {
16402
16392
  validateControl(control, errors);
16403
16393
  }
@@ -16455,6 +16445,39 @@ function validateCapabilities(provider, controls, errors) {
16455
16445
  errors.push("providers declaring controls must set capabilities.controls.typedResults=true");
16456
16446
  }
16457
16447
  }
16448
+ function validateCanonicalHistory(raw, errors) {
16449
+ if (raw === void 0) return;
16450
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
16451
+ errors.push("canonicalHistory must be an object");
16452
+ return;
16453
+ }
16454
+ const canonicalHistory = raw;
16455
+ const format = canonicalHistory.format;
16456
+ if (format !== void 0 && (typeof format !== "string" || !format.trim())) {
16457
+ errors.push("canonicalHistory.format must be a non-empty string when provided");
16458
+ }
16459
+ const watchPath = canonicalHistory.watchPath;
16460
+ if (watchPath !== void 0 && (typeof watchPath !== "string" || !watchPath.trim())) {
16461
+ errors.push("canonicalHistory.watchPath must be a non-empty string when provided");
16462
+ }
16463
+ const mode = canonicalHistory.mode;
16464
+ if (mode !== void 0 && !["native-source", "materialized-mirror", "disabled"].includes(String(mode))) {
16465
+ errors.push("canonicalHistory.mode must be one of: native-source, materialized-mirror, disabled");
16466
+ }
16467
+ const scripts = canonicalHistory.scripts;
16468
+ if (scripts === void 0) return;
16469
+ if (!scripts || typeof scripts !== "object" || Array.isArray(scripts)) {
16470
+ errors.push("canonicalHistory.scripts must be an object");
16471
+ return;
16472
+ }
16473
+ const scriptConfig = scripts;
16474
+ for (const key of ["readSession", "listSessions"]) {
16475
+ const value = scriptConfig[key];
16476
+ if (typeof value !== "string" || !value.trim()) {
16477
+ errors.push(`canonicalHistory.scripts.${key} must be a non-empty string`);
16478
+ }
16479
+ }
16480
+ }
16458
16481
  function validateControl(control, errors) {
16459
16482
  if (!control || typeof control !== "object") {
16460
16483
  errors.push("controls: each control must be an object");
@@ -17997,6 +18020,38 @@ var ProviderLoader = class _ProviderLoader {
17997
18020
  }
17998
18021
  };
17999
18022
 
18023
+ // src/launch/macos-app-process.ts
18024
+ function normalizeMacAppPath(appPath) {
18025
+ const trimmed = String(appPath || "").trim();
18026
+ if (!trimmed) return null;
18027
+ return trimmed.replace(/\/+$/, "");
18028
+ }
18029
+ function parsePsLine(line) {
18030
+ const match = line.match(/^\s*(\d+)\s+(.+)$/);
18031
+ if (!match) return null;
18032
+ const pid = Number.parseInt(match[1], 10);
18033
+ if (!Number.isFinite(pid)) return null;
18034
+ return { pid, args: match[2] };
18035
+ }
18036
+ function isMacAppProcessArgs(args, appPath) {
18037
+ const normalized = normalizeMacAppPath(appPath);
18038
+ if (!normalized) return false;
18039
+ return String(args || "").startsWith(`${normalized}/`);
18040
+ }
18041
+ function findMacAppProcessPids(psOutput, appPaths) {
18042
+ const normalizedPaths = appPaths.map(normalizeMacAppPath).filter((value) => !!value);
18043
+ if (normalizedPaths.length === 0) return [];
18044
+ const pids = [];
18045
+ for (const line of String(psOutput || "").split(/\r?\n/)) {
18046
+ const parsed = parsePsLine(line);
18047
+ if (!parsed) continue;
18048
+ if (normalizedPaths.some((appPath) => isMacAppProcessArgs(parsed.args, appPath))) {
18049
+ pids.push(parsed.pid);
18050
+ }
18051
+ }
18052
+ return pids;
18053
+ }
18054
+
18000
18055
  // src/launch.ts
18001
18056
  var _providerLoader = null;
18002
18057
  function getProviderLoader() {
@@ -18033,6 +18088,35 @@ function getCdpStartupTimeoutMs(ideId) {
18033
18088
  function escapeForAppleScript(value) {
18034
18089
  return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
18035
18090
  }
18091
+ function getIdePathCandidates(ideId) {
18092
+ return getProviderLoader().getIdePathCandidates(ideId);
18093
+ }
18094
+ function getMacAppProcessPids(ideId) {
18095
+ const appPaths = getIdePathCandidates(ideId);
18096
+ if (appPaths.length === 0) return [];
18097
+ try {
18098
+ const output = (0, import_child_process7.execSync)("ps axww -o pid=,args=", {
18099
+ encoding: "utf-8",
18100
+ timeout: 3e3,
18101
+ stdio: ["pipe", "pipe", "pipe"]
18102
+ });
18103
+ return findMacAppProcessPids(output, appPaths);
18104
+ } catch {
18105
+ return [];
18106
+ }
18107
+ }
18108
+ function killMacAppPathProcesses(ideId, signal) {
18109
+ const pids = getMacAppProcessPids(ideId);
18110
+ let signalled = false;
18111
+ for (const pid of pids) {
18112
+ try {
18113
+ process.kill(pid, signal);
18114
+ signalled = true;
18115
+ } catch {
18116
+ }
18117
+ }
18118
+ return signalled;
18119
+ }
18036
18120
  async function findFreePort(ports) {
18037
18121
  for (const port2 of ports) {
18038
18122
  const free = await checkPortFree(port2);
@@ -18094,6 +18178,7 @@ async function killIdeProcess(ideId) {
18094
18178
  } catch {
18095
18179
  }
18096
18180
  }
18181
+ killMacAppPathProcesses(ideId, "SIGTERM");
18097
18182
  } else if (plat === "win32" && winProcesses) {
18098
18183
  for (const proc of winProcesses) {
18099
18184
  try {
@@ -18123,6 +18208,7 @@ async function killIdeProcess(ideId) {
18123
18208
  (0, import_child_process7.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
18124
18209
  } catch {
18125
18210
  }
18211
+ killMacAppPathProcesses(ideId, "SIGKILL");
18126
18212
  } else if (plat === "win32" && winProcesses) {
18127
18213
  for (const proc of winProcesses) {
18128
18214
  try {
@@ -18142,14 +18228,16 @@ function isIdeRunning(ideId) {
18142
18228
  try {
18143
18229
  if (plat === "darwin") {
18144
18230
  const appName = getMacAppIdentifiers()[ideId];
18145
- if (!appName) return false;
18231
+ if (!appName) return getMacAppProcessPids(ideId).length > 0;
18146
18232
  try {
18147
18233
  const result = (0, import_child_process7.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
18148
18234
  encoding: "utf-8",
18149
18235
  timeout: 3e3
18150
18236
  });
18151
- return result.trim().length > 0;
18237
+ if (result.trim().length > 0) return true;
18152
18238
  } catch {
18239
+ }
18240
+ try {
18153
18241
  const result = (0, import_child_process7.execSync)(
18154
18242
  `osascript -e 'tell application "System Events" to count (every process whose name is "${escapeForAppleScript(appName)}")'`,
18155
18243
  {
@@ -18158,8 +18246,10 @@ function isIdeRunning(ideId) {
18158
18246
  stdio: ["pipe", "pipe", "pipe"]
18159
18247
  }
18160
18248
  );
18161
- return Number.parseInt(result.trim() || "0", 10) > 0;
18249
+ if (Number.parseInt(result.trim() || "0", 10) > 0) return true;
18250
+ } catch {
18162
18251
  }
18252
+ return getMacAppProcessPids(ideId).length > 0;
18163
18253
  } else if (plat === "win32") {
18164
18254
  const winProcesses = getWinProcessNames()[ideId];
18165
18255
  if (!winProcesses) return false;
@@ -19526,13 +19616,19 @@ var DaemonCommandRouter = class {
19526
19616
  const wantsAll = args?.all === true;
19527
19617
  const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
19528
19618
  const limit = wantsAll ? Number.MAX_SAFE_INTEGER : Math.max(1, Math.min(100, Number(args?.limit) || 30));
19529
- const { sessions: historySessions, hasMore } = listSavedHistorySessions(providerType, { offset, limit });
19619
+ const providerMeta = this.deps.providerLoader.getMeta(providerType);
19620
+ const { sessions: historySessions, hasMore, source } = listProviderHistorySessions(providerType, {
19621
+ canonicalHistory: providerMeta?.canonicalHistory,
19622
+ offset,
19623
+ limit,
19624
+ historyBehavior: providerMeta?.historyBehavior,
19625
+ scripts: providerMeta?.scripts
19626
+ });
19530
19627
  const state = loadState();
19531
19628
  const savedSessions = getSavedProviderSessions(state, { providerType, kind });
19532
19629
  const recentSessions = getRecentActivity(state, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
19533
19630
  const savedSessionById = new Map(savedSessions.map((entry) => [entry.providerSessionId, entry]));
19534
19631
  const recentSessionById = new Map(recentSessions.map((entry) => [entry.providerSessionId, entry]));
19535
- const providerMeta = this.deps.providerLoader.getMeta(providerType);
19536
19632
  const canResumeById = supportsExplicitSessionResume(providerMeta?.resume);
19537
19633
  return {
19538
19634
  success: true,
@@ -19552,10 +19648,14 @@ var DaemonCommandRouter = class {
19552
19648
  messageCount: session.messageCount,
19553
19649
  firstMessageAt: session.firstMessageAt,
19554
19650
  lastMessageAt: session.lastMessageAt,
19555
- canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById
19651
+ canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById,
19652
+ historySource: session.source,
19653
+ sourcePath: session.sourcePath,
19654
+ sourceMtimeMs: session.sourceMtimeMs
19556
19655
  };
19557
19656
  }),
19558
- hasMore
19657
+ hasMore,
19658
+ source
19559
19659
  };
19560
19660
  }
19561
19661
  // ─── restart_session: IDE / CLI / ACP unified ───