@adhdev/daemon-standalone 0.9.43 → 0.9.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +722 -38
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/index-D0Z-_yFE.js +83 -0
- package/public/assets/index-DSVpeZ22.css +1 -0
- package/public/index.html +2 -2
- package/public/assets/index-Lp15xLIJ.css +0 -1
- package/public/assets/index-rD4lYEvn.js +0 -83
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;
|
|
@@ -29926,7 +29928,9 @@ var require_dist2 = __commonJS({
|
|
|
29926
29928
|
__export2(provider_cli_adapter_exports, {
|
|
29927
29929
|
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
29928
29930
|
appendBoundedText: () => appendBoundedText,
|
|
29929
|
-
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
29931
|
+
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime,
|
|
29932
|
+
sanitizeCliStandardMessageContent: () => sanitizeCliStandardMessageContent,
|
|
29933
|
+
trimLastAssistantEchoForCliMessages: () => trimLastAssistantEchoForCliMessages
|
|
29930
29934
|
});
|
|
29931
29935
|
function normalizeComparableTranscriptText(value) {
|
|
29932
29936
|
return sanitizeTerminalText(String(value || "")).replace(/\s+/g, " ").trim();
|
|
@@ -29966,7 +29970,77 @@ var require_dist2 = __commonJS({
|
|
|
29966
29970
|
if (current.length <= keepFromCurrent) return current + chunk;
|
|
29967
29971
|
return current.slice(-keepFromCurrent) + chunk;
|
|
29968
29972
|
}
|
|
29973
|
+
function isLikelyCommittedActivityPrefixContinuation(line) {
|
|
29974
|
+
const trimmed = String(line || "").trim();
|
|
29975
|
+
if (!trimmed) return false;
|
|
29976
|
+
if (COMMITTED_ACTIVITY_PREFIX_BLOCK_RE.test(trimmed)) return false;
|
|
29977
|
+
if (/\s/.test(trimmed)) return false;
|
|
29978
|
+
if (/[가-힣]/.test(trimmed)) return false;
|
|
29979
|
+
if (trimmed.length > 96) return false;
|
|
29980
|
+
return /^[A-Za-z0-9_./:@+%=-]+$/.test(trimmed);
|
|
29981
|
+
}
|
|
29982
|
+
function parseCommittedActivityPrefixBlock(lines, index) {
|
|
29983
|
+
const first = String(lines[index] || "").trim();
|
|
29984
|
+
if (!COMMITTED_ACTIVITY_PREFIX_BLOCK_RE.test(first)) return null;
|
|
29985
|
+
const parts = [first];
|
|
29986
|
+
let nextIndex = index + 1;
|
|
29987
|
+
while (nextIndex < lines.length && isLikelyCommittedActivityPrefixContinuation(lines[nextIndex])) {
|
|
29988
|
+
parts.push(String(lines[nextIndex] || "").trim());
|
|
29989
|
+
nextIndex += 1;
|
|
29990
|
+
}
|
|
29991
|
+
return { label: parts.join(""), nextIndex };
|
|
29992
|
+
}
|
|
29993
|
+
function sanitizeCliStandardMessageContent(content) {
|
|
29994
|
+
const source = String(content || "").trim();
|
|
29995
|
+
if (!source) return "";
|
|
29996
|
+
const lines = source.split(/\r?\n/);
|
|
29997
|
+
if (lines.length < 4) return source;
|
|
29998
|
+
const counts = /* @__PURE__ */ new Map();
|
|
29999
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
30000
|
+
const block = parseCommittedActivityPrefixBlock(lines, index);
|
|
30001
|
+
if (!block) continue;
|
|
30002
|
+
counts.set(block.label, (counts.get(block.label) || 0) + 1);
|
|
30003
|
+
index = block.nextIndex - 1;
|
|
30004
|
+
}
|
|
30005
|
+
const repeatedLabels = new Set(
|
|
30006
|
+
Array.from(counts.entries()).filter(([, count]) => count >= 3).map(([label]) => label)
|
|
30007
|
+
);
|
|
30008
|
+
if (repeatedLabels.size === 0) return source;
|
|
30009
|
+
const stripped = [];
|
|
30010
|
+
let removed = 0;
|
|
30011
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
30012
|
+
const block = parseCommittedActivityPrefixBlock(lines, index);
|
|
30013
|
+
if (block && repeatedLabels.has(block.label)) {
|
|
30014
|
+
removed += 1;
|
|
30015
|
+
index = block.nextIndex - 1;
|
|
30016
|
+
continue;
|
|
30017
|
+
}
|
|
30018
|
+
stripped.push(lines[index]);
|
|
30019
|
+
}
|
|
30020
|
+
const next = stripped.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
30021
|
+
return removed >= 3 && next.length >= 80 ? next : source;
|
|
30022
|
+
}
|
|
30023
|
+
function sanitizeCommittedMessageForDisplay(message) {
|
|
30024
|
+
if (!message || message.role !== "assistant" || (message.kind || "standard") !== "standard") return message;
|
|
30025
|
+
const content = sanitizeCliStandardMessageContent(message.content);
|
|
30026
|
+
if (content === message.content) return message;
|
|
30027
|
+
return { ...message, content };
|
|
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
|
+
}
|
|
29969
30042
|
var os10;
|
|
30043
|
+
var COMMITTED_ACTIVITY_PREFIX_BLOCK_RE;
|
|
29970
30044
|
var ProviderCliAdapter;
|
|
29971
30045
|
var init_provider_cli_adapter = __esm2({
|
|
29972
30046
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
@@ -29983,6 +30057,7 @@ var require_dist2 = __commonJS({
|
|
|
29983
30057
|
init_provider_cli_config();
|
|
29984
30058
|
init_provider_cli_runtime();
|
|
29985
30059
|
init_provider_cli_shared();
|
|
30060
|
+
COMMITTED_ACTIVITY_PREFIX_BLOCK_RE = /^(?:📖|💻|🔎|📚|📋|✏️|📝|🔧|🛠️|⚙️)\s+(.+)$/;
|
|
29986
30061
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
29987
30062
|
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
29988
30063
|
this.extraArgs = extraArgs;
|
|
@@ -30163,7 +30238,14 @@ var require_dist2 = __commonJS({
|
|
|
30163
30238
|
}
|
|
30164
30239
|
return null;
|
|
30165
30240
|
}
|
|
30241
|
+
providerOwnsTranscript() {
|
|
30242
|
+
return this.provider.transcriptAuthority === "provider";
|
|
30243
|
+
}
|
|
30244
|
+
shouldUseFullProviderTranscriptContext() {
|
|
30245
|
+
return this.providerOwnsTranscript() && this.provider.transcriptContext === "full";
|
|
30246
|
+
}
|
|
30166
30247
|
selectParseBaseMessages(baseMessages) {
|
|
30248
|
+
if (this.shouldUseFullProviderTranscriptContext()) return baseMessages;
|
|
30167
30249
|
if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
|
|
30168
30250
|
return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
|
|
30169
30251
|
}
|
|
@@ -30194,7 +30276,10 @@ var require_dist2 = __commonJS({
|
|
|
30194
30276
|
const tailFirst = parseBaseMessages[0];
|
|
30195
30277
|
if (tailFirst && this.messagesComparable(parsedFirst, tailFirst)) {
|
|
30196
30278
|
const prefixLength = fullBaseMessages.length - parseBaseMessages.length;
|
|
30197
|
-
|
|
30279
|
+
const prefix = fullBaseMessages.slice(0, prefixLength);
|
|
30280
|
+
const shouldSanitizePrefix = !!this.currentTurnScope || this.currentStatus !== "idle" || !!this.activeModal;
|
|
30281
|
+
const nextPrefix = shouldSanitizePrefix ? prefix.map((message) => sanitizeCommittedMessageForDisplay(message)) : prefix;
|
|
30282
|
+
return [...nextPrefix, ...parsedMessages];
|
|
30198
30283
|
}
|
|
30199
30284
|
return [...fullBaseMessages, ...parsedMessages];
|
|
30200
30285
|
}
|
|
@@ -30643,9 +30728,7 @@ var require_dist2 = __commonJS({
|
|
|
30643
30728
|
);
|
|
30644
30729
|
}
|
|
30645
30730
|
trimLastAssistantEcho(messages, prompt) {
|
|
30646
|
-
|
|
30647
|
-
const last = [...messages].reverse().find((m) => m.role === "assistant" && typeof m.content === "string");
|
|
30648
|
-
if (last) last.content = trimPromptEchoPrefix(last.content, prompt);
|
|
30731
|
+
trimLastAssistantEchoForCliMessages(messages, prompt);
|
|
30649
30732
|
}
|
|
30650
30733
|
clearAllTimers() {
|
|
30651
30734
|
if (this.responseTimeout) {
|
|
@@ -31393,10 +31476,12 @@ var require_dist2 = __commonJS({
|
|
|
31393
31476
|
}
|
|
31394
31477
|
buildCommittedChatMessages() {
|
|
31395
31478
|
return this.committedMessages.map((message, index) => {
|
|
31396
|
-
const
|
|
31479
|
+
const rawContentValue = message.content;
|
|
31480
|
+
const rawContent = typeof rawContentValue === "string" ? rawContentValue : String(rawContentValue || "");
|
|
31481
|
+
const content = message.role === "assistant" && (message.kind || "standard") === "standard" ? sanitizeCliStandardMessageContent(rawContent) : rawContent;
|
|
31397
31482
|
return buildChatMessage({
|
|
31398
31483
|
role: message.role,
|
|
31399
|
-
content
|
|
31484
|
+
content,
|
|
31400
31485
|
timestamp: message.timestamp,
|
|
31401
31486
|
kind: message.kind,
|
|
31402
31487
|
meta: message.meta,
|
|
@@ -31497,7 +31582,8 @@ var require_dist2 = __commonJS({
|
|
|
31497
31582
|
title: parsed.title || this.cliName,
|
|
31498
31583
|
messages: hydratedMessages,
|
|
31499
31584
|
activeModal: parsed.activeModal ?? this.activeModal,
|
|
31500
|
-
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" } : {}
|
|
31501
31587
|
};
|
|
31502
31588
|
} else {
|
|
31503
31589
|
const messages = [...this.committedMessages];
|
|
@@ -35793,6 +35879,27 @@ ${cleanBody}`;
|
|
|
35793
35879
|
return name.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
35794
35880
|
}
|
|
35795
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
|
+
}
|
|
35796
35903
|
function readChatHistory(agentType, offset = 0, limit = 30, historySessionId, excludeRecentCount = 0, historyBehavior) {
|
|
35797
35904
|
try {
|
|
35798
35905
|
const sanitized = agentType.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
@@ -35818,25 +35925,7 @@ ${cleanBody}`;
|
|
|
35818
35925
|
}
|
|
35819
35926
|
}
|
|
35820
35927
|
}
|
|
35821
|
-
|
|
35822
|
-
const chronological = [];
|
|
35823
|
-
let lastTurn = null;
|
|
35824
|
-
for (const message of allMessages) {
|
|
35825
|
-
const previous = chronological[chronological.length - 1];
|
|
35826
|
-
if (isAdjacentHistoryDuplicate(agentType, previous, message)) continue;
|
|
35827
|
-
if (message.role !== "system" && isAdjacentHistoryDuplicate(agentType, lastTurn, message)) continue;
|
|
35828
|
-
chronological.push(message);
|
|
35829
|
-
if (message.role !== "system") lastTurn = message;
|
|
35830
|
-
}
|
|
35831
|
-
const collapsed = collapseReplayAssistantTurns(chronological, historyBehavior);
|
|
35832
|
-
const boundedLimit = Math.max(1, limit);
|
|
35833
|
-
const boundedOffset = Math.max(0, offset);
|
|
35834
|
-
const boundedExclude = Math.max(0, Math.min(excludeRecentCount, collapsed.length));
|
|
35835
|
-
const endExclusive = Math.max(0, collapsed.length - boundedExclude - boundedOffset);
|
|
35836
|
-
const startInclusive = Math.max(0, endExclusive - boundedLimit);
|
|
35837
|
-
const sliced = collapsed.slice(startInclusive, endExclusive);
|
|
35838
|
-
const hasMore = startInclusive > 0;
|
|
35839
|
-
return { messages: sliced, hasMore };
|
|
35928
|
+
return pageHistoryRecords(agentType, allMessages, offset, limit, excludeRecentCount, historyBehavior);
|
|
35840
35929
|
} catch {
|
|
35841
35930
|
return { messages: [], hasMore: false };
|
|
35842
35931
|
}
|
|
@@ -35971,6 +36060,52 @@ ${cleanBody}`;
|
|
|
35971
36060
|
return false;
|
|
35972
36061
|
}
|
|
35973
36062
|
}
|
|
36063
|
+
function buildHermesNativeHistoryRecords(historySessionId) {
|
|
36064
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
36065
|
+
if (!normalizedSessionId) return null;
|
|
36066
|
+
try {
|
|
36067
|
+
const sessionFilePath = path7.join(os52.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
|
|
36068
|
+
if (!fs32.existsSync(sessionFilePath)) return null;
|
|
36069
|
+
const raw = JSON.parse(fs32.readFileSync(sessionFilePath, "utf-8"));
|
|
36070
|
+
const canonicalMessages = Array.isArray(raw.messages) ? raw.messages : [];
|
|
36071
|
+
const records = [];
|
|
36072
|
+
let fallbackTs = Date.parse(raw.session_start || raw.last_updated || "") || Date.now();
|
|
36073
|
+
for (const message of canonicalMessages) {
|
|
36074
|
+
const role = String(message.role || "").trim();
|
|
36075
|
+
const content = normalizeCanonicalHermesMessageContent(message.content);
|
|
36076
|
+
if (!content) continue;
|
|
36077
|
+
const receivedAt = extractCanonicalHermesMessageTimestamp(message, fallbackTs);
|
|
36078
|
+
fallbackTs = receivedAt + 1;
|
|
36079
|
+
if (role === "user" || role === "assistant") {
|
|
36080
|
+
records.push({
|
|
36081
|
+
ts: new Date(receivedAt).toISOString(),
|
|
36082
|
+
receivedAt,
|
|
36083
|
+
role,
|
|
36084
|
+
content,
|
|
36085
|
+
kind: "standard",
|
|
36086
|
+
agent: "hermes-cli",
|
|
36087
|
+
historySessionId: normalizedSessionId
|
|
36088
|
+
});
|
|
36089
|
+
continue;
|
|
36090
|
+
}
|
|
36091
|
+
if (role === "tool") {
|
|
36092
|
+
records.push({
|
|
36093
|
+
ts: new Date(receivedAt).toISOString(),
|
|
36094
|
+
receivedAt,
|
|
36095
|
+
role: "assistant",
|
|
36096
|
+
content,
|
|
36097
|
+
kind: "tool",
|
|
36098
|
+
senderName: "Tool",
|
|
36099
|
+
agent: "hermes-cli",
|
|
36100
|
+
historySessionId: normalizedSessionId
|
|
36101
|
+
});
|
|
36102
|
+
}
|
|
36103
|
+
}
|
|
36104
|
+
return records;
|
|
36105
|
+
} catch {
|
|
36106
|
+
return null;
|
|
36107
|
+
}
|
|
36108
|
+
}
|
|
35974
36109
|
function rebuildHermesSavedHistoryFromCanonicalSession(historySessionId) {
|
|
35975
36110
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
35976
36111
|
if (!normalizedSessionId) return false;
|
|
@@ -36120,6 +36255,77 @@ ${cleanBody}`;
|
|
|
36120
36255
|
}
|
|
36121
36256
|
return parts;
|
|
36122
36257
|
}
|
|
36258
|
+
function buildClaudeNativeHistoryRecords(historySessionId, workspace) {
|
|
36259
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
36260
|
+
if (!normalizedSessionId) return null;
|
|
36261
|
+
try {
|
|
36262
|
+
const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
|
|
36263
|
+
if (!transcriptPath) return null;
|
|
36264
|
+
const lines = fs32.readFileSync(transcriptPath, "utf-8").split("\n").filter(Boolean);
|
|
36265
|
+
const records = [];
|
|
36266
|
+
let fallbackTs = Date.now();
|
|
36267
|
+
for (const line of lines) {
|
|
36268
|
+
let parsed = null;
|
|
36269
|
+
try {
|
|
36270
|
+
parsed = JSON.parse(line);
|
|
36271
|
+
} catch {
|
|
36272
|
+
parsed = null;
|
|
36273
|
+
}
|
|
36274
|
+
if (!parsed) continue;
|
|
36275
|
+
const parsedSessionId = String(parsed.sessionId || "").trim();
|
|
36276
|
+
if (parsedSessionId && parsedSessionId !== normalizedSessionId) continue;
|
|
36277
|
+
const receivedAt = extractTimestampValue(parsed.timestamp) || fallbackTs;
|
|
36278
|
+
fallbackTs = receivedAt + 1;
|
|
36279
|
+
const parsedWorkspace = String(parsed.cwd || workspace || "").trim();
|
|
36280
|
+
if (records.length === 0 && parsedWorkspace) {
|
|
36281
|
+
records.push({
|
|
36282
|
+
ts: new Date(receivedAt).toISOString(),
|
|
36283
|
+
receivedAt,
|
|
36284
|
+
role: "system",
|
|
36285
|
+
kind: "session_start",
|
|
36286
|
+
content: parsedWorkspace,
|
|
36287
|
+
agent: "claude-cli",
|
|
36288
|
+
historySessionId: normalizedSessionId,
|
|
36289
|
+
workspace: parsedWorkspace
|
|
36290
|
+
});
|
|
36291
|
+
}
|
|
36292
|
+
const type = String(parsed.type || "").trim();
|
|
36293
|
+
const message = parsed.message && typeof parsed.message === "object" ? parsed.message : null;
|
|
36294
|
+
if (type === "user" && message) {
|
|
36295
|
+
for (const part of extractClaudeUserContentParts(message.content)) {
|
|
36296
|
+
records.push({
|
|
36297
|
+
ts: new Date(receivedAt).toISOString(),
|
|
36298
|
+
receivedAt,
|
|
36299
|
+
role: part.role,
|
|
36300
|
+
content: part.content,
|
|
36301
|
+
kind: part.kind,
|
|
36302
|
+
senderName: part.senderName,
|
|
36303
|
+
agent: "claude-cli",
|
|
36304
|
+
historySessionId: normalizedSessionId
|
|
36305
|
+
});
|
|
36306
|
+
}
|
|
36307
|
+
continue;
|
|
36308
|
+
}
|
|
36309
|
+
if (type === "assistant" && message) {
|
|
36310
|
+
for (const part of extractClaudeAssistantContentParts(message.content)) {
|
|
36311
|
+
records.push({
|
|
36312
|
+
ts: new Date(receivedAt).toISOString(),
|
|
36313
|
+
receivedAt,
|
|
36314
|
+
role: "assistant",
|
|
36315
|
+
content: part.content,
|
|
36316
|
+
kind: part.kind,
|
|
36317
|
+
senderName: part.senderName,
|
|
36318
|
+
agent: "claude-cli",
|
|
36319
|
+
historySessionId: normalizedSessionId
|
|
36320
|
+
});
|
|
36321
|
+
}
|
|
36322
|
+
}
|
|
36323
|
+
}
|
|
36324
|
+
return records;
|
|
36325
|
+
} catch {
|
|
36326
|
+
return null;
|
|
36327
|
+
}
|
|
36328
|
+
}
|
|
36123
36329
|
function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
|
|
36124
36330
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
36125
36331
|
if (!normalizedSessionId) return false;
|
|
@@ -36198,6 +36404,352 @@ ${cleanBody}`;
|
|
|
36198
36404
|
return false;
|
|
36199
36405
|
}
|
|
36200
36406
|
}
|
|
36407
|
+
function isUuidLikeSessionId(sessionId) {
|
|
36408
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(sessionId);
|
|
36409
|
+
}
|
|
36410
|
+
function readCodexSessionMeta(filePath) {
|
|
36411
|
+
try {
|
|
36412
|
+
const firstLine = fs32.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
|
|
36413
|
+
if (!firstLine) return null;
|
|
36414
|
+
const parsed = JSON.parse(firstLine);
|
|
36415
|
+
if (String(parsed.type || "") !== "session_meta") return null;
|
|
36416
|
+
const payload = parsed.payload && typeof parsed.payload === "object" ? parsed.payload : null;
|
|
36417
|
+
return payload;
|
|
36418
|
+
} catch {
|
|
36419
|
+
return null;
|
|
36420
|
+
}
|
|
36421
|
+
}
|
|
36422
|
+
function resolveCodexSessionTranscriptPath(historySessionId, workspace) {
|
|
36423
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
36424
|
+
if (!normalizedSessionId || !isUuidLikeSessionId(normalizedSessionId)) return null;
|
|
36425
|
+
const sessionsDir = path7.join(os52.homedir(), ".codex", "sessions");
|
|
36426
|
+
if (!fs32.existsSync(sessionsDir)) return null;
|
|
36427
|
+
const normalizedWorkspace = typeof workspace === "string" ? workspace.trim() : "";
|
|
36428
|
+
const candidates = [];
|
|
36429
|
+
const stack = [sessionsDir];
|
|
36430
|
+
while (stack.length > 0) {
|
|
36431
|
+
const current = stack.pop();
|
|
36432
|
+
if (!current) continue;
|
|
36433
|
+
let entries = [];
|
|
36434
|
+
try {
|
|
36435
|
+
entries = fs32.readdirSync(current, { withFileTypes: true });
|
|
36436
|
+
} catch {
|
|
36437
|
+
continue;
|
|
36438
|
+
}
|
|
36439
|
+
for (const entry of entries) {
|
|
36440
|
+
const entryPath = path7.join(current, entry.name);
|
|
36441
|
+
if (entry.isDirectory()) {
|
|
36442
|
+
stack.push(entryPath);
|
|
36443
|
+
continue;
|
|
36444
|
+
}
|
|
36445
|
+
if (!entry.isFile() || !entry.name.endsWith(".jsonl") || !entry.name.includes(normalizedSessionId)) continue;
|
|
36446
|
+
const meta3 = readCodexSessionMeta(entryPath);
|
|
36447
|
+
const metaSessionId = String(meta3?.id || "").trim();
|
|
36448
|
+
if (metaSessionId && metaSessionId !== normalizedSessionId) continue;
|
|
36449
|
+
const metaWorkspace = String(meta3?.cwd || "").trim();
|
|
36450
|
+
let mtimeMs = 0;
|
|
36451
|
+
try {
|
|
36452
|
+
mtimeMs = fs32.statSync(entryPath).mtimeMs;
|
|
36453
|
+
} catch {
|
|
36454
|
+
}
|
|
36455
|
+
candidates.push({
|
|
36456
|
+
path: entryPath,
|
|
36457
|
+
mtimeMs,
|
|
36458
|
+
workspaceMatches: !!normalizedWorkspace && metaWorkspace === normalizedWorkspace,
|
|
36459
|
+
metaMatches: metaSessionId === normalizedSessionId
|
|
36460
|
+
});
|
|
36461
|
+
}
|
|
36462
|
+
}
|
|
36463
|
+
candidates.sort((a, b2) => Number(b2.workspaceMatches) - Number(a.workspaceMatches) || Number(b2.metaMatches) - Number(a.metaMatches) || b2.mtimeMs - a.mtimeMs);
|
|
36464
|
+
return candidates[0]?.path || null;
|
|
36465
|
+
}
|
|
36466
|
+
function flattenCodexContent(content) {
|
|
36467
|
+
if (typeof content === "string") return content.trim();
|
|
36468
|
+
if (content == null) return "";
|
|
36469
|
+
if (Array.isArray(content)) {
|
|
36470
|
+
return content.map((entry) => flattenCodexContent(entry)).filter(Boolean).join("\n").trim();
|
|
36471
|
+
}
|
|
36472
|
+
if (typeof content === "object") {
|
|
36473
|
+
const record2 = content;
|
|
36474
|
+
if (typeof record2.text === "string") return record2.text.trim();
|
|
36475
|
+
if (typeof record2.content === "string" || Array.isArray(record2.content)) return flattenCodexContent(record2.content);
|
|
36476
|
+
if (typeof record2.output === "string") return record2.output.trim();
|
|
36477
|
+
if (typeof record2.message === "string") return record2.message.trim();
|
|
36478
|
+
}
|
|
36479
|
+
return "";
|
|
36480
|
+
}
|
|
36481
|
+
function summarizeCodexToolCall(payload) {
|
|
36482
|
+
const name = String(payload.name || payload.type || "tool").trim() || "tool";
|
|
36483
|
+
const rawArguments = payload.arguments ?? payload.input;
|
|
36484
|
+
let argumentValue = "";
|
|
36485
|
+
if (typeof rawArguments === "string") {
|
|
36486
|
+
const trimmed = rawArguments.trim();
|
|
36487
|
+
try {
|
|
36488
|
+
const parsed = JSON.parse(trimmed);
|
|
36489
|
+
argumentValue = summarizeCodexToolArguments(parsed);
|
|
36490
|
+
} catch {
|
|
36491
|
+
argumentValue = trimmed;
|
|
36492
|
+
}
|
|
36493
|
+
} else {
|
|
36494
|
+
argumentValue = summarizeCodexToolArguments(rawArguments);
|
|
36495
|
+
}
|
|
36496
|
+
return argumentValue ? `${name}: ${argumentValue}` : name;
|
|
36497
|
+
}
|
|
36498
|
+
function summarizeCodexToolArguments(value) {
|
|
36499
|
+
if (typeof value === "string") return value.trim();
|
|
36500
|
+
if (Array.isArray(value)) return value.map((entry) => String(entry)).join(" ").trim();
|
|
36501
|
+
if (!value || typeof value !== "object") return "";
|
|
36502
|
+
const record2 = value;
|
|
36503
|
+
const direct = record2.command || record2.cmd || record2.query || record2.path || record2.prompt;
|
|
36504
|
+
if (typeof direct === "string") return direct.trim();
|
|
36505
|
+
if (Array.isArray(direct)) return direct.map((entry) => String(entry)).join(" ").trim();
|
|
36506
|
+
try {
|
|
36507
|
+
return JSON.stringify(record2).trim();
|
|
36508
|
+
} catch {
|
|
36509
|
+
return "";
|
|
36510
|
+
}
|
|
36511
|
+
}
|
|
36512
|
+
function codexToolOutputContent(payload) {
|
|
36513
|
+
const output = payload.output ?? payload.result ?? payload.content;
|
|
36514
|
+
const text = flattenCodexContent(output);
|
|
36515
|
+
if (text) return text;
|
|
36516
|
+
if (output && typeof output === "object") {
|
|
36517
|
+
try {
|
|
36518
|
+
return JSON.stringify(output).trim();
|
|
36519
|
+
} catch {
|
|
36520
|
+
return "";
|
|
36521
|
+
}
|
|
36522
|
+
}
|
|
36523
|
+
return "";
|
|
36524
|
+
}
|
|
36525
|
+
function buildCodexNativeHistoryRecords(historySessionId, workspace) {
|
|
36526
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
36527
|
+
if (!normalizedSessionId || !isUuidLikeSessionId(normalizedSessionId)) return null;
|
|
36528
|
+
try {
|
|
36529
|
+
const transcriptPath = resolveCodexSessionTranscriptPath(normalizedSessionId, workspace);
|
|
36530
|
+
if (!transcriptPath) return null;
|
|
36531
|
+
const lines = fs32.readFileSync(transcriptPath, "utf-8").split("\n").filter(Boolean);
|
|
36532
|
+
const records = [];
|
|
36533
|
+
let fallbackTs = Date.now();
|
|
36534
|
+
for (const line of lines) {
|
|
36535
|
+
let parsed = null;
|
|
36536
|
+
try {
|
|
36537
|
+
parsed = JSON.parse(line);
|
|
36538
|
+
} catch {
|
|
36539
|
+
parsed = null;
|
|
36540
|
+
}
|
|
36541
|
+
if (!parsed) continue;
|
|
36542
|
+
const receivedAt = extractTimestampValue(parsed.timestamp) || fallbackTs;
|
|
36543
|
+
fallbackTs = receivedAt + 1;
|
|
36544
|
+
const type = String(parsed.type || "").trim();
|
|
36545
|
+
const payload = parsed.payload && typeof parsed.payload === "object" ? parsed.payload : null;
|
|
36546
|
+
if (!payload) continue;
|
|
36547
|
+
if (type === "session_meta") {
|
|
36548
|
+
const parsedSessionId = String(payload.id || "").trim();
|
|
36549
|
+
if (parsedSessionId && parsedSessionId !== normalizedSessionId) return null;
|
|
36550
|
+
const parsedWorkspace = String(payload.cwd || workspace || "").trim();
|
|
36551
|
+
if (records.length === 0 && parsedWorkspace) {
|
|
36552
|
+
records.push({
|
|
36553
|
+
ts: new Date(receivedAt).toISOString(),
|
|
36554
|
+
receivedAt,
|
|
36555
|
+
role: "system",
|
|
36556
|
+
kind: "session_start",
|
|
36557
|
+
content: parsedWorkspace,
|
|
36558
|
+
agent: "codex-cli",
|
|
36559
|
+
historySessionId: normalizedSessionId,
|
|
36560
|
+
workspace: parsedWorkspace
|
|
36561
|
+
});
|
|
36562
|
+
}
|
|
36563
|
+
continue;
|
|
36564
|
+
}
|
|
36565
|
+
if (type !== "response_item") continue;
|
|
36566
|
+
const payloadType = String(payload.type || "").trim();
|
|
36567
|
+
if (payloadType === "message") {
|
|
36568
|
+
const role = String(payload.role || "").trim();
|
|
36569
|
+
if (role !== "user" && role !== "assistant") continue;
|
|
36570
|
+
const content = flattenCodexContent(payload.content);
|
|
36571
|
+
if (!content) continue;
|
|
36572
|
+
records.push({
|
|
36573
|
+
ts: new Date(receivedAt).toISOString(),
|
|
36574
|
+
receivedAt,
|
|
36575
|
+
role,
|
|
36576
|
+
content,
|
|
36577
|
+
kind: "standard",
|
|
36578
|
+
agent: "codex-cli",
|
|
36579
|
+
historySessionId: normalizedSessionId
|
|
36580
|
+
});
|
|
36581
|
+
continue;
|
|
36582
|
+
}
|
|
36583
|
+
if (payloadType === "function_call" || payloadType === "custom_tool_call") {
|
|
36584
|
+
const content = summarizeCodexToolCall(payload);
|
|
36585
|
+
if (!content) continue;
|
|
36586
|
+
records.push({
|
|
36587
|
+
ts: new Date(receivedAt).toISOString(),
|
|
36588
|
+
receivedAt,
|
|
36589
|
+
role: "assistant",
|
|
36590
|
+
content,
|
|
36591
|
+
kind: "tool",
|
|
36592
|
+
senderName: "Tool",
|
|
36593
|
+
agent: "codex-cli",
|
|
36594
|
+
historySessionId: normalizedSessionId
|
|
36595
|
+
});
|
|
36596
|
+
continue;
|
|
36597
|
+
}
|
|
36598
|
+
if (payloadType === "function_call_output" || payloadType === "custom_tool_call_output") {
|
|
36599
|
+
const content = codexToolOutputContent(payload);
|
|
36600
|
+
if (!content) continue;
|
|
36601
|
+
records.push({
|
|
36602
|
+
ts: new Date(receivedAt).toISOString(),
|
|
36603
|
+
receivedAt,
|
|
36604
|
+
role: "assistant",
|
|
36605
|
+
content,
|
|
36606
|
+
kind: "tool",
|
|
36607
|
+
senderName: "Tool",
|
|
36608
|
+
agent: "codex-cli",
|
|
36609
|
+
historySessionId: normalizedSessionId
|
|
36610
|
+
});
|
|
36611
|
+
}
|
|
36612
|
+
}
|
|
36613
|
+
return records;
|
|
36614
|
+
} catch {
|
|
36615
|
+
return null;
|
|
36616
|
+
}
|
|
36617
|
+
}
|
|
36618
|
+
function rebuildCodexSavedHistoryFromNativeSession(historySessionId, workspace) {
|
|
36619
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
36620
|
+
if (!normalizedSessionId || !isUuidLikeSessionId(normalizedSessionId)) return false;
|
|
36621
|
+
const records = buildCodexNativeHistoryRecords(normalizedSessionId, workspace);
|
|
36622
|
+
if (!records || records.length === 0) return false;
|
|
36623
|
+
const existingSessionStart = readExistingSessionStartRecord("codex-cli", normalizedSessionId);
|
|
36624
|
+
const recordsToWrite = existingSessionStart && records[0]?.kind !== "session_start" ? [{ ...existingSessionStart, historySessionId: normalizedSessionId }, ...records] : records;
|
|
36625
|
+
return rewriteCanonicalSavedHistory("codex-cli", normalizedSessionId, recordsToWrite);
|
|
36626
|
+
}
|
|
36627
|
+
function isNativeSourceCanonicalHistory(canonicalHistory) {
|
|
36628
|
+
if (!canonicalHistory) return false;
|
|
36629
|
+
if (canonicalHistory.mode === "disabled") return false;
|
|
36630
|
+
if (canonicalHistory.mode === "materialized-mirror") return false;
|
|
36631
|
+
return true;
|
|
36632
|
+
}
|
|
36633
|
+
function buildNativeHistoryRecords(canonicalHistory, historySessionId, workspace) {
|
|
36634
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || "");
|
|
36635
|
+
if (!canonicalHistory || !normalizedSessionId || !isNativeSourceCanonicalHistory(canonicalHistory)) return null;
|
|
36636
|
+
if (canonicalHistory.format === "hermes-json") return buildHermesNativeHistoryRecords(normalizedSessionId);
|
|
36637
|
+
if (canonicalHistory.format === "claude-jsonl") return buildClaudeNativeHistoryRecords(normalizedSessionId, workspace);
|
|
36638
|
+
if (canonicalHistory.format === "codex-jsonl") return buildCodexNativeHistoryRecords(normalizedSessionId, workspace);
|
|
36639
|
+
return null;
|
|
36640
|
+
}
|
|
36641
|
+
function readProviderChatHistory(agentType, options = {}) {
|
|
36642
|
+
if (isNativeSourceCanonicalHistory(options.canonicalHistory) && options.historySessionId) {
|
|
36643
|
+
const records = buildNativeHistoryRecords(options.canonicalHistory, options.historySessionId, options.workspace);
|
|
36644
|
+
if (!records) return { messages: [], hasMore: false, source: "native-unavailable" };
|
|
36645
|
+
return {
|
|
36646
|
+
...pageHistoryRecords(agentType, records, options.offset || 0, options.limit || 30, options.excludeRecentCount || 0, options.historyBehavior),
|
|
36647
|
+
source: "provider-native"
|
|
36648
|
+
};
|
|
36649
|
+
}
|
|
36650
|
+
return {
|
|
36651
|
+
...readChatHistory(agentType, options.offset || 0, options.limit || 30, options.historySessionId, options.excludeRecentCount || 0, options.historyBehavior),
|
|
36652
|
+
source: "adhdev-mirror"
|
|
36653
|
+
};
|
|
36654
|
+
}
|
|
36655
|
+
function buildNativeSessionSummary(agentType, historySessionId, records, sourcePath) {
|
|
36656
|
+
const visible = pageHistoryRecords(agentType, records, 0, Number.MAX_SAFE_INTEGER).messages;
|
|
36657
|
+
if (visible.length === 0) return null;
|
|
36658
|
+
let sourceMtimeMs = 0;
|
|
36659
|
+
try {
|
|
36660
|
+
sourceMtimeMs = fs32.statSync(sourcePath).mtimeMs;
|
|
36661
|
+
} catch {
|
|
36662
|
+
}
|
|
36663
|
+
const firstMessageAt = visible[0]?.receivedAt || sourceMtimeMs || Date.now();
|
|
36664
|
+
const lastMessageAt = visible[visible.length - 1]?.receivedAt || firstMessageAt;
|
|
36665
|
+
const lastNonSystem = [...visible].reverse().find((message) => message.role !== "system") || visible[visible.length - 1];
|
|
36666
|
+
const firstSystem = visible.find((message) => message.kind === "session_start");
|
|
36667
|
+
return {
|
|
36668
|
+
historySessionId,
|
|
36669
|
+
sessionTitle: lastNonSystem?.content,
|
|
36670
|
+
messageCount: visible.length,
|
|
36671
|
+
firstMessageAt,
|
|
36672
|
+
lastMessageAt,
|
|
36673
|
+
preview: lastNonSystem?.content,
|
|
36674
|
+
workspace: firstSystem?.workspace || (firstSystem?.kind === "session_start" ? firstSystem.content : void 0),
|
|
36675
|
+
source: "provider-native",
|
|
36676
|
+
sourcePath,
|
|
36677
|
+
sourceMtimeMs
|
|
36678
|
+
};
|
|
36679
|
+
}
|
|
36680
|
+
function listFilesRecursive(root, predicate) {
|
|
36681
|
+
if (!fs32.existsSync(root)) return [];
|
|
36682
|
+
const results = [];
|
|
36683
|
+
const stack = [root];
|
|
36684
|
+
while (stack.length > 0) {
|
|
36685
|
+
const current = stack.pop();
|
|
36686
|
+
if (!current) continue;
|
|
36687
|
+
let entries = [];
|
|
36688
|
+
try {
|
|
36689
|
+
entries = fs32.readdirSync(current, { withFileTypes: true });
|
|
36690
|
+
} catch {
|
|
36691
|
+
continue;
|
|
36692
|
+
}
|
|
36693
|
+
for (const entry of entries) {
|
|
36694
|
+
const entryPath = path7.join(current, entry.name);
|
|
36695
|
+
if (entry.isDirectory()) {
|
|
36696
|
+
stack.push(entryPath);
|
|
36697
|
+
continue;
|
|
36698
|
+
}
|
|
36699
|
+
if (predicate(entryPath, entry)) results.push(entryPath);
|
|
36700
|
+
}
|
|
36701
|
+
}
|
|
36702
|
+
return results;
|
|
36703
|
+
}
|
|
36704
|
+
function collectNativeHistorySessionSummaries(agentType, canonicalHistory) {
|
|
36705
|
+
const summaries = [];
|
|
36706
|
+
if (canonicalHistory.format === "hermes-json") {
|
|
36707
|
+
const root = path7.join(os52.homedir(), ".hermes", "sessions");
|
|
36708
|
+
for (const filePath of listFilesRecursive(root, (_entryPath, entry) => entry.isFile() && /^session_.+\.json$/.test(entry.name))) {
|
|
36709
|
+
const fileName = path7.basename(filePath);
|
|
36710
|
+
const historySessionId = fileName.replace(/^session_/, "").replace(/\.json$/, "");
|
|
36711
|
+
const records = buildHermesNativeHistoryRecords(historySessionId);
|
|
36712
|
+
const summary = records ? buildNativeSessionSummary(agentType, historySessionId, records, filePath) : null;
|
|
36713
|
+
if (summary) summaries.push(summary);
|
|
36714
|
+
}
|
|
36715
|
+
} else if (canonicalHistory.format === "claude-jsonl") {
|
|
36716
|
+
const root = path7.join(os52.homedir(), ".claude", "projects");
|
|
36717
|
+
for (const filePath of listFilesRecursive(root, (_entryPath, entry) => entry.isFile() && entry.name.endsWith(".jsonl"))) {
|
|
36718
|
+
const historySessionId = path7.basename(filePath, ".jsonl");
|
|
36719
|
+
const records = buildClaudeNativeHistoryRecords(historySessionId);
|
|
36720
|
+
const summary = records ? buildNativeSessionSummary(agentType, historySessionId, records, filePath) : null;
|
|
36721
|
+
if (summary) summaries.push(summary);
|
|
36722
|
+
}
|
|
36723
|
+
} else if (canonicalHistory.format === "codex-jsonl") {
|
|
36724
|
+
const root = path7.join(os52.homedir(), ".codex", "sessions");
|
|
36725
|
+
const uuidPattern = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i;
|
|
36726
|
+
for (const filePath of listFilesRecursive(root, (_entryPath, entry) => entry.isFile() && entry.name.endsWith(".jsonl"))) {
|
|
36727
|
+
const meta3 = readCodexSessionMeta(filePath);
|
|
36728
|
+
const historySessionId = String(meta3?.id || path7.basename(filePath).match(uuidPattern)?.[1] || "").trim();
|
|
36729
|
+
if (!historySessionId) continue;
|
|
36730
|
+
const records = buildCodexNativeHistoryRecords(historySessionId, String(meta3?.cwd || "").trim() || void 0);
|
|
36731
|
+
const summary = records ? buildNativeSessionSummary(agentType, historySessionId, records, filePath) : null;
|
|
36732
|
+
if (summary) summaries.push(summary);
|
|
36733
|
+
}
|
|
36734
|
+
}
|
|
36735
|
+
return sortSavedHistorySessionSummaries(summaries);
|
|
36736
|
+
}
|
|
36737
|
+
function listProviderHistorySessions(agentType, options = {}) {
|
|
36738
|
+
if (isNativeSourceCanonicalHistory(options.canonicalHistory)) {
|
|
36739
|
+
const offset = Math.max(0, options.offset || 0);
|
|
36740
|
+
const limit = Math.max(1, options.limit || 30);
|
|
36741
|
+
const summaries = collectNativeHistorySessionSummaries(agentType, options.canonicalHistory);
|
|
36742
|
+
return {
|
|
36743
|
+
sessions: summaries.slice(offset, offset + limit),
|
|
36744
|
+
hasMore: offset + limit < summaries.length,
|
|
36745
|
+
source: "provider-native"
|
|
36746
|
+
};
|
|
36747
|
+
}
|
|
36748
|
+
return {
|
|
36749
|
+
...listSavedHistorySessions(agentType, { offset: options.offset, limit: options.limit }, options.historyBehavior),
|
|
36750
|
+
source: "adhdev-mirror"
|
|
36751
|
+
};
|
|
36752
|
+
}
|
|
36201
36753
|
function isControlValue(value) {
|
|
36202
36754
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
36203
36755
|
}
|
|
@@ -38765,7 +39317,16 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38765
39317
|
const visibleCount = Array.isArray(status?.messages) ? status.messages.length : 0;
|
|
38766
39318
|
if (visibleCount > excludeRecentCount) excludeRecentCount = visibleCount;
|
|
38767
39319
|
}
|
|
38768
|
-
const
|
|
39320
|
+
const workspace = typeof args?.workspace === "string" ? args.workspace : typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : void 0;
|
|
39321
|
+
const result = readProviderChatHistory(agentStr, {
|
|
39322
|
+
canonicalHistory: provider?.canonicalHistory,
|
|
39323
|
+
historySessionId,
|
|
39324
|
+
workspace,
|
|
39325
|
+
offset: offset || 0,
|
|
39326
|
+
limit: limit || 30,
|
|
39327
|
+
excludeRecentCount,
|
|
39328
|
+
historyBehavior: provider?.historyBehavior
|
|
39329
|
+
});
|
|
38769
39330
|
return { success: true, ...result, agent: agentStr };
|
|
38770
39331
|
} catch (e) {
|
|
38771
39332
|
return { success: false, error: e.message };
|
|
@@ -38790,7 +39351,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38790
39351
|
}
|
|
38791
39352
|
const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
|
|
38792
39353
|
const adapterStatus = adapter.getStatus();
|
|
38793
|
-
const
|
|
39354
|
+
const parsedIsProviderAuthoritative = parsedRecord?.transcriptAuthority === "provider" || parsedRecord?.coverage === "full";
|
|
39355
|
+
const shouldPreferAdapterMessages = !parsedIsProviderAuthoritative && Array.isArray(adapterStatus.messages) && adapterStatus.messages.length > 0 && Array.isArray(parsedRecord?.messages) && adapterStatus.messages.length > parsedRecord.messages.length;
|
|
38794
39356
|
const parsedShowsApproval = hasNonEmptyModalButtons(parsedRecord?.activeModal) && parsedRecord?.status === "waiting_approval";
|
|
38795
39357
|
const status = parsedRecord ? {
|
|
38796
39358
|
...parsedRecord,
|
|
@@ -38800,6 +39362,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38800
39362
|
} : adapterStatus;
|
|
38801
39363
|
const title = typeof parsedRecord?.title === "string" ? parsedRecord.title : void 0;
|
|
38802
39364
|
const providerSessionId = typeof parsedRecord?.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
|
|
39365
|
+
const transcriptAuthority = parsedRecord?.transcriptAuthority === "provider" || parsedRecord?.transcriptAuthority === "daemon" ? parsedRecord.transcriptAuthority : void 0;
|
|
39366
|
+
const coverage = parsedRecord?.coverage === "full" || parsedRecord?.coverage === "tail" || parsedRecord?.coverage === "current-turn" ? parsedRecord.coverage : void 0;
|
|
38803
39367
|
if (status) {
|
|
38804
39368
|
LOG2.debug("Command", `[read_chat] cli-like resolved provider=${adapter.cliType} target=${String(args?.targetSessionId || "")} adapterStatus=${String(adapterStatus.status || "")} parsedStatus=${String(parsedRecord?.status || "")} shouldPreferAdapterMessages=${String(shouldPreferAdapterMessages)} adapterMsgCount=${Array.isArray(adapterStatus.messages) ? adapterStatus.messages.length : 0} parsedMsgCount=${Array.isArray(parsedRecord?.messages) ? parsedRecord.messages.length : 0} returnedMsgCount=${Array.isArray(status.messages) ? status.messages.length : 0}`);
|
|
38805
39369
|
return buildReadChatCommandResult({
|
|
@@ -38818,7 +39382,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
38818
39382
|
returnedMsgCount: Array.isArray(status.messages) ? status.messages.length : 0
|
|
38819
39383
|
},
|
|
38820
39384
|
...title ? { title } : {},
|
|
38821
|
-
...providerSessionId ? { providerSessionId } : {}
|
|
39385
|
+
...providerSessionId ? { providerSessionId } : {},
|
|
39386
|
+
...transcriptAuthority ? { transcriptAuthority } : {},
|
|
39387
|
+
...coverage ? { coverage } : {}
|
|
38822
39388
|
}, args);
|
|
38823
39389
|
}
|
|
38824
39390
|
}
|
|
@@ -41216,6 +41782,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41216
41782
|
lastCanonicalHermesWatchPath = void 0;
|
|
41217
41783
|
lastCanonicalClaudeRebuildMtimeMs = 0;
|
|
41218
41784
|
lastCanonicalClaudeCheckAt = 0;
|
|
41785
|
+
lastCanonicalCodexRebuildMtimeMs = 0;
|
|
41786
|
+
lastCanonicalCodexCheckAt = 0;
|
|
41219
41787
|
cachedSqliteDb = null;
|
|
41220
41788
|
cachedSqliteDbPath = null;
|
|
41221
41789
|
cachedSqliteDbMissingUntil = 0;
|
|
@@ -41915,6 +42483,25 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41915
42483
|
if (!this.providerSessionId) return false;
|
|
41916
42484
|
const canonicalHistory = this.provider.canonicalHistory;
|
|
41917
42485
|
if (!canonicalHistory) return false;
|
|
42486
|
+
if (isNativeSourceCanonicalHistory(canonicalHistory)) {
|
|
42487
|
+
const restoredHistory = readProviderChatHistory(this.type, {
|
|
42488
|
+
canonicalHistory,
|
|
42489
|
+
historySessionId: this.providerSessionId,
|
|
42490
|
+
workspace: this.workingDir,
|
|
42491
|
+
offset: 0,
|
|
42492
|
+
limit: Number.MAX_SAFE_INTEGER,
|
|
42493
|
+
historyBehavior: this.provider.historyBehavior
|
|
42494
|
+
});
|
|
42495
|
+
if (restoredHistory.source !== "provider-native") return false;
|
|
42496
|
+
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
42497
|
+
role: message.role,
|
|
42498
|
+
content: message.content,
|
|
42499
|
+
kind: message.kind,
|
|
42500
|
+
senderName: message.senderName,
|
|
42501
|
+
receivedAt: message.receivedAt
|
|
42502
|
+
}));
|
|
42503
|
+
return true;
|
|
42504
|
+
}
|
|
41918
42505
|
try {
|
|
41919
42506
|
let rebuilt = false;
|
|
41920
42507
|
if (canonicalHistory.format === "hermes-json") {
|
|
@@ -41948,6 +42535,23 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41948
42535
|
if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalClaudeRebuildMtimeMs) return true;
|
|
41949
42536
|
rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
|
|
41950
42537
|
if (rebuilt) this.lastCanonicalClaudeRebuildMtimeMs = transcriptMtime || Date.now();
|
|
42538
|
+
} else if (canonicalHistory.format === "codex-jsonl") {
|
|
42539
|
+
const now = Date.now();
|
|
42540
|
+
if (now - this.lastCanonicalCodexCheckAt < 2e3 && this.lastCanonicalCodexRebuildMtimeMs !== 0) {
|
|
42541
|
+
return true;
|
|
42542
|
+
}
|
|
42543
|
+
this.lastCanonicalCodexCheckAt = now;
|
|
42544
|
+
const transcriptFile = resolveCodexSessionTranscriptPath(this.providerSessionId, this.workingDir);
|
|
42545
|
+
let transcriptMtime = 0;
|
|
42546
|
+
if (transcriptFile) {
|
|
42547
|
+
try {
|
|
42548
|
+
transcriptMtime = fs52.statSync(transcriptFile).mtimeMs;
|
|
42549
|
+
} catch {
|
|
42550
|
+
}
|
|
42551
|
+
}
|
|
42552
|
+
if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalCodexRebuildMtimeMs) return true;
|
|
42553
|
+
rebuilt = rebuildCodexSavedHistoryFromNativeSession(this.providerSessionId, this.workingDir);
|
|
42554
|
+
if (rebuilt) this.lastCanonicalCodexRebuildMtimeMs = transcriptMtime || Date.now();
|
|
41951
42555
|
}
|
|
41952
42556
|
if (!rebuilt) return false;
|
|
41953
42557
|
const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
|
|
@@ -41966,8 +42570,17 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41966
42570
|
restorePersistedHistoryFromCurrentSession() {
|
|
41967
42571
|
if (!this.providerSessionId) return;
|
|
41968
42572
|
this.syncCanonicalSavedHistoryIfNeeded();
|
|
41969
|
-
this.
|
|
41970
|
-
|
|
42573
|
+
const restoredHistory = isNativeSourceCanonicalHistory(this.provider.canonicalHistory) ? readProviderChatHistory(this.type, {
|
|
42574
|
+
canonicalHistory: this.provider.canonicalHistory,
|
|
42575
|
+
historySessionId: this.providerSessionId,
|
|
42576
|
+
workspace: this.workingDir,
|
|
42577
|
+
offset: 0,
|
|
42578
|
+
limit: Number.MAX_SAFE_INTEGER,
|
|
42579
|
+
historyBehavior: this.provider.historyBehavior
|
|
42580
|
+
}) : (() => {
|
|
42581
|
+
this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
|
|
42582
|
+
return readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
|
|
42583
|
+
})();
|
|
41971
42584
|
this.historyWriter.seedSessionHistory(
|
|
41972
42585
|
this.type,
|
|
41973
42586
|
restoredHistory.messages,
|
|
@@ -45680,6 +46293,36 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45680
46293
|
return 0;
|
|
45681
46294
|
}
|
|
45682
46295
|
};
|
|
46296
|
+
function normalizeMacAppPath(appPath) {
|
|
46297
|
+
const trimmed = String(appPath || "").trim();
|
|
46298
|
+
if (!trimmed) return null;
|
|
46299
|
+
return trimmed.replace(/\/+$/, "");
|
|
46300
|
+
}
|
|
46301
|
+
function parsePsLine(line) {
|
|
46302
|
+
const match = line.match(/^\s*(\d+)\s+(.+)$/);
|
|
46303
|
+
if (!match) return null;
|
|
46304
|
+
const pid = Number.parseInt(match[1], 10);
|
|
46305
|
+
if (!Number.isFinite(pid)) return null;
|
|
46306
|
+
return { pid, args: match[2] };
|
|
46307
|
+
}
|
|
46308
|
+
function isMacAppProcessArgs(args, appPath) {
|
|
46309
|
+
const normalized = normalizeMacAppPath(appPath);
|
|
46310
|
+
if (!normalized) return false;
|
|
46311
|
+
return String(args || "").startsWith(`${normalized}/`);
|
|
46312
|
+
}
|
|
46313
|
+
function findMacAppProcessPids(psOutput, appPaths) {
|
|
46314
|
+
const normalizedPaths = appPaths.map(normalizeMacAppPath).filter((value) => !!value);
|
|
46315
|
+
if (normalizedPaths.length === 0) return [];
|
|
46316
|
+
const pids = [];
|
|
46317
|
+
for (const line of String(psOutput || "").split(/\r?\n/)) {
|
|
46318
|
+
const parsed = parsePsLine(line);
|
|
46319
|
+
if (!parsed) continue;
|
|
46320
|
+
if (normalizedPaths.some((appPath) => isMacAppProcessArgs(parsed.args, appPath))) {
|
|
46321
|
+
pids.push(parsed.pid);
|
|
46322
|
+
}
|
|
46323
|
+
}
|
|
46324
|
+
return pids;
|
|
46325
|
+
}
|
|
45683
46326
|
var _providerLoader = null;
|
|
45684
46327
|
function getProviderLoader() {
|
|
45685
46328
|
if (!_providerLoader) {
|
|
@@ -45715,6 +46358,35 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45715
46358
|
function escapeForAppleScript(value) {
|
|
45716
46359
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
45717
46360
|
}
|
|
46361
|
+
function getIdePathCandidates(ideId) {
|
|
46362
|
+
return getProviderLoader().getIdePathCandidates(ideId);
|
|
46363
|
+
}
|
|
46364
|
+
function getMacAppProcessPids(ideId) {
|
|
46365
|
+
const appPaths = getIdePathCandidates(ideId);
|
|
46366
|
+
if (appPaths.length === 0) return [];
|
|
46367
|
+
try {
|
|
46368
|
+
const output = (0, import_child_process7.execSync)("ps axww -o pid=,args=", {
|
|
46369
|
+
encoding: "utf-8",
|
|
46370
|
+
timeout: 3e3,
|
|
46371
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
46372
|
+
});
|
|
46373
|
+
return findMacAppProcessPids(output, appPaths);
|
|
46374
|
+
} catch {
|
|
46375
|
+
return [];
|
|
46376
|
+
}
|
|
46377
|
+
}
|
|
46378
|
+
function killMacAppPathProcesses(ideId, signal) {
|
|
46379
|
+
const pids = getMacAppProcessPids(ideId);
|
|
46380
|
+
let signalled = false;
|
|
46381
|
+
for (const pid of pids) {
|
|
46382
|
+
try {
|
|
46383
|
+
process.kill(pid, signal);
|
|
46384
|
+
signalled = true;
|
|
46385
|
+
} catch {
|
|
46386
|
+
}
|
|
46387
|
+
}
|
|
46388
|
+
return signalled;
|
|
46389
|
+
}
|
|
45718
46390
|
async function findFreePort(ports) {
|
|
45719
46391
|
for (const port2 of ports) {
|
|
45720
46392
|
const free = await checkPortFree(port2);
|
|
@@ -45776,6 +46448,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45776
46448
|
} catch {
|
|
45777
46449
|
}
|
|
45778
46450
|
}
|
|
46451
|
+
killMacAppPathProcesses(ideId, "SIGTERM");
|
|
45779
46452
|
} else if (plat === "win32" && winProcesses) {
|
|
45780
46453
|
for (const proc of winProcesses) {
|
|
45781
46454
|
try {
|
|
@@ -45805,6 +46478,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45805
46478
|
(0, import_child_process7.execSync)(`pkill -9 -x "${appName}" 2>/dev/null`, { timeout: 5e3 });
|
|
45806
46479
|
} catch {
|
|
45807
46480
|
}
|
|
46481
|
+
killMacAppPathProcesses(ideId, "SIGKILL");
|
|
45808
46482
|
} else if (plat === "win32" && winProcesses) {
|
|
45809
46483
|
for (const proc of winProcesses) {
|
|
45810
46484
|
try {
|
|
@@ -45824,14 +46498,16 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45824
46498
|
try {
|
|
45825
46499
|
if (plat === "darwin") {
|
|
45826
46500
|
const appName = getMacAppIdentifiers()[ideId];
|
|
45827
|
-
if (!appName) return
|
|
46501
|
+
if (!appName) return getMacAppProcessPids(ideId).length > 0;
|
|
45828
46502
|
try {
|
|
45829
46503
|
const result = (0, import_child_process7.execSync)(`pgrep -x "${appName}" 2>/dev/null`, {
|
|
45830
46504
|
encoding: "utf-8",
|
|
45831
46505
|
timeout: 3e3
|
|
45832
46506
|
});
|
|
45833
|
-
|
|
46507
|
+
if (result.trim().length > 0) return true;
|
|
45834
46508
|
} catch {
|
|
46509
|
+
}
|
|
46510
|
+
try {
|
|
45835
46511
|
const result = (0, import_child_process7.execSync)(
|
|
45836
46512
|
`osascript -e 'tell application "System Events" to count (every process whose name is "${escapeForAppleScript(appName)}")'`,
|
|
45837
46513
|
{
|
|
@@ -45840,8 +46516,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
45840
46516
|
stdio: ["pipe", "pipe", "pipe"]
|
|
45841
46517
|
}
|
|
45842
46518
|
);
|
|
45843
|
-
|
|
46519
|
+
if (Number.parseInt(result.trim() || "0", 10) > 0) return true;
|
|
46520
|
+
} catch {
|
|
45844
46521
|
}
|
|
46522
|
+
return getMacAppProcessPids(ideId).length > 0;
|
|
45845
46523
|
} else if (plat === "win32") {
|
|
45846
46524
|
const winProcesses = getWinProcessNames()[ideId];
|
|
45847
46525
|
if (!winProcesses) return false;
|
|
@@ -47196,13 +47874,18 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47196
47874
|
const wantsAll = args?.all === true;
|
|
47197
47875
|
const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
|
|
47198
47876
|
const limit = wantsAll ? Number.MAX_SAFE_INTEGER : Math.max(1, Math.min(100, Number(args?.limit) || 30));
|
|
47199
|
-
const
|
|
47877
|
+
const providerMeta = this.deps.providerLoader.getMeta(providerType);
|
|
47878
|
+
const { sessions: historySessions, hasMore, source } = listProviderHistorySessions(providerType, {
|
|
47879
|
+
canonicalHistory: providerMeta?.canonicalHistory,
|
|
47880
|
+
offset,
|
|
47881
|
+
limit,
|
|
47882
|
+
historyBehavior: providerMeta?.historyBehavior
|
|
47883
|
+
});
|
|
47200
47884
|
const state = loadState();
|
|
47201
47885
|
const savedSessions = getSavedProviderSessions(state, { providerType, kind });
|
|
47202
47886
|
const recentSessions = getRecentActivity(state, 200).filter((entry) => entry.providerType === providerType && entry.kind === kind && entry.providerSessionId);
|
|
47203
47887
|
const savedSessionById = new Map(savedSessions.map((entry) => [entry.providerSessionId, entry]));
|
|
47204
47888
|
const recentSessionById = new Map(recentSessions.map((entry) => [entry.providerSessionId, entry]));
|
|
47205
|
-
const providerMeta = this.deps.providerLoader.getMeta(providerType);
|
|
47206
47889
|
const canResumeById = supportsExplicitSessionResume(providerMeta?.resume);
|
|
47207
47890
|
return {
|
|
47208
47891
|
success: true,
|
|
@@ -47225,7 +47908,8 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47225
47908
|
canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById
|
|
47226
47909
|
};
|
|
47227
47910
|
}),
|
|
47228
|
-
hasMore
|
|
47911
|
+
hasMore,
|
|
47912
|
+
source
|
|
47229
47913
|
};
|
|
47230
47914
|
}
|
|
47231
47915
|
// ─── restart_session: IDE / CLI / ACP unified ───
|