@adhdev/daemon-standalone 0.9.45 → 0.9.47
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 +191 -713
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/public/assets/{index-D0Z-_yFE.js → index-DE1t1pa6.js} +16 -16
- package/public/index.html +1 -1
package/dist/index.js
CHANGED
|
@@ -35992,29 +35992,6 @@ ${cleanBody}`;
|
|
|
35992
35992
|
return { sessions: [], hasMore: false };
|
|
35993
35993
|
}
|
|
35994
35994
|
}
|
|
35995
|
-
function normalizeCanonicalHermesMessageContent(content) {
|
|
35996
|
-
if (typeof content === "string") return content.trim();
|
|
35997
|
-
if (content == null) return "";
|
|
35998
|
-
try {
|
|
35999
|
-
return JSON.stringify(content).trim();
|
|
36000
|
-
} catch {
|
|
36001
|
-
return String(content).trim();
|
|
36002
|
-
}
|
|
36003
|
-
}
|
|
36004
|
-
function extractCanonicalHermesMessageTimestamp(message, fallbackTs) {
|
|
36005
|
-
const numericTimestamp = Number(message.receivedAt || message.timestamp || message.ts || 0);
|
|
36006
|
-
if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
|
|
36007
|
-
const stringTimestamp = typeof message.ts === "string" ? Date.parse(message.ts) : typeof message.timestamp === "string" ? Date.parse(message.timestamp) : NaN;
|
|
36008
|
-
if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
|
|
36009
|
-
return fallbackTs;
|
|
36010
|
-
}
|
|
36011
|
-
function extractTimestampValue(value) {
|
|
36012
|
-
const numericTimestamp = Number(value || 0);
|
|
36013
|
-
if (Number.isFinite(numericTimestamp) && numericTimestamp > 0) return numericTimestamp;
|
|
36014
|
-
const stringTimestamp = typeof value === "string" ? Date.parse(value) : NaN;
|
|
36015
|
-
if (Number.isFinite(stringTimestamp) && stringTimestamp > 0) return stringTimestamp;
|
|
36016
|
-
return 0;
|
|
36017
|
-
}
|
|
36018
35995
|
function readExistingSessionStartRecord(agentType, historySessionId) {
|
|
36019
35996
|
try {
|
|
36020
35997
|
const dir = path7.join(HISTORY_DIR, agentType);
|
|
@@ -36060,569 +36037,77 @@ ${cleanBody}`;
|
|
|
36060
36037
|
return false;
|
|
36061
36038
|
}
|
|
36062
36039
|
}
|
|
36063
|
-
function
|
|
36064
|
-
const
|
|
36065
|
-
if (
|
|
36066
|
-
|
|
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
|
-
}
|
|
36040
|
+
function getNativeHistoryScriptName(canonicalHistory, key) {
|
|
36041
|
+
const configured = canonicalHistory?.scripts?.[key];
|
|
36042
|
+
if (typeof configured === "string" && configured.trim()) return configured.trim();
|
|
36043
|
+
return key === "readSession" ? "readNativeHistory" : "listNativeHistory";
|
|
36108
36044
|
}
|
|
36109
|
-
function
|
|
36110
|
-
|
|
36111
|
-
|
|
36112
|
-
|
|
36113
|
-
const sessionFilePath = path7.join(os52.homedir(), ".hermes", "sessions", `session_${normalizedSessionId}.json`);
|
|
36114
|
-
if (!fs32.existsSync(sessionFilePath)) return false;
|
|
36115
|
-
const raw = JSON.parse(fs32.readFileSync(sessionFilePath, "utf-8"));
|
|
36116
|
-
const canonicalMessages = Array.isArray(raw.messages) ? raw.messages : [];
|
|
36117
|
-
const dir = path7.join(HISTORY_DIR, "hermes-cli");
|
|
36118
|
-
fs32.mkdirSync(dir, { recursive: true });
|
|
36119
|
-
const existingSessionStart = readExistingSessionStartRecord("hermes-cli", normalizedSessionId);
|
|
36120
|
-
const records = [];
|
|
36121
|
-
if (existingSessionStart) {
|
|
36122
|
-
records.push({
|
|
36123
|
-
...existingSessionStart,
|
|
36124
|
-
historySessionId: normalizedSessionId
|
|
36125
|
-
});
|
|
36126
|
-
}
|
|
36127
|
-
let fallbackTs = Date.parse(raw.session_start || raw.last_updated || "") || Date.now();
|
|
36128
|
-
for (const message of canonicalMessages) {
|
|
36129
|
-
const role = String(message.role || "").trim();
|
|
36130
|
-
const content = normalizeCanonicalHermesMessageContent(message.content);
|
|
36131
|
-
if (!content) continue;
|
|
36132
|
-
const receivedAt = extractCanonicalHermesMessageTimestamp(message, fallbackTs);
|
|
36133
|
-
fallbackTs = receivedAt + 1;
|
|
36134
|
-
if (role === "user") {
|
|
36135
|
-
records.push({
|
|
36136
|
-
ts: new Date(receivedAt).toISOString(),
|
|
36137
|
-
receivedAt,
|
|
36138
|
-
role: "user",
|
|
36139
|
-
content,
|
|
36140
|
-
kind: "standard",
|
|
36141
|
-
agent: "hermes-cli",
|
|
36142
|
-
historySessionId: normalizedSessionId
|
|
36143
|
-
});
|
|
36144
|
-
continue;
|
|
36145
|
-
}
|
|
36146
|
-
if (role === "assistant") {
|
|
36147
|
-
records.push({
|
|
36148
|
-
ts: new Date(receivedAt).toISOString(),
|
|
36149
|
-
receivedAt,
|
|
36150
|
-
role: "assistant",
|
|
36151
|
-
content,
|
|
36152
|
-
kind: "standard",
|
|
36153
|
-
agent: "hermes-cli",
|
|
36154
|
-
historySessionId: normalizedSessionId
|
|
36155
|
-
});
|
|
36156
|
-
continue;
|
|
36157
|
-
}
|
|
36158
|
-
if (role === "tool") {
|
|
36159
|
-
records.push({
|
|
36160
|
-
ts: new Date(receivedAt).toISOString(),
|
|
36161
|
-
receivedAt,
|
|
36162
|
-
role: "assistant",
|
|
36163
|
-
content,
|
|
36164
|
-
kind: "tool",
|
|
36165
|
-
senderName: "Tool",
|
|
36166
|
-
agent: "hermes-cli",
|
|
36167
|
-
historySessionId: normalizedSessionId
|
|
36168
|
-
});
|
|
36169
|
-
}
|
|
36170
|
-
}
|
|
36171
|
-
return rewriteCanonicalSavedHistory("hermes-cli", normalizedSessionId, records);
|
|
36172
|
-
} catch {
|
|
36173
|
-
return false;
|
|
36174
|
-
}
|
|
36045
|
+
function getProviderNativeHistoryScript(scripts, canonicalHistory, key) {
|
|
36046
|
+
if (!canonicalHistory?.scripts) return null;
|
|
36047
|
+
const fn2 = scripts?.[getNativeHistoryScriptName(canonicalHistory, key)];
|
|
36048
|
+
return typeof fn2 === "function" ? fn2 : null;
|
|
36175
36049
|
}
|
|
36176
|
-
function
|
|
36177
|
-
|
|
36178
|
-
if (!fs32.existsSync(claudeProjectsDir)) return null;
|
|
36179
|
-
const normalizedWorkspace = typeof workspace === "string" ? workspace.trim() : "";
|
|
36180
|
-
if (normalizedWorkspace) {
|
|
36181
|
-
const directPath = path7.join(claudeProjectsDir, normalizedWorkspace.replace(/[\\/]/g, "-"), `${historySessionId}.jsonl`);
|
|
36182
|
-
if (fs32.existsSync(directPath)) return directPath;
|
|
36183
|
-
}
|
|
36184
|
-
const stack = [claudeProjectsDir];
|
|
36185
|
-
while (stack.length > 0) {
|
|
36186
|
-
const current = stack.pop();
|
|
36187
|
-
if (!current) continue;
|
|
36188
|
-
for (const entry of fs32.readdirSync(current, { withFileTypes: true })) {
|
|
36189
|
-
const entryPath = path7.join(current, entry.name);
|
|
36190
|
-
if (entry.isDirectory()) {
|
|
36191
|
-
stack.push(entryPath);
|
|
36192
|
-
continue;
|
|
36193
|
-
}
|
|
36194
|
-
if (entry.isFile() && entry.name === `${historySessionId}.jsonl`) {
|
|
36195
|
-
return entryPath;
|
|
36196
|
-
}
|
|
36197
|
-
}
|
|
36198
|
-
}
|
|
36199
|
-
return null;
|
|
36200
|
-
}
|
|
36201
|
-
function extractClaudeAssistantContentParts(content) {
|
|
36202
|
-
if (typeof content === "string") {
|
|
36203
|
-
const trimmed = content.trim();
|
|
36204
|
-
return trimmed ? [{ content: trimmed, kind: "standard", role: "assistant" }] : [];
|
|
36205
|
-
}
|
|
36206
|
-
if (!Array.isArray(content)) return [];
|
|
36207
|
-
const parts = [];
|
|
36208
|
-
for (const block of content) {
|
|
36209
|
-
if (!block || typeof block !== "object") continue;
|
|
36210
|
-
const record2 = block;
|
|
36211
|
-
const type = String(record2.type || "").trim();
|
|
36212
|
-
if (type === "text") {
|
|
36213
|
-
const text = String(record2.text || "").trim();
|
|
36214
|
-
if (text) parts.push({ content: text, kind: "standard", role: "assistant" });
|
|
36215
|
-
continue;
|
|
36216
|
-
}
|
|
36217
|
-
if (type === "tool_use") {
|
|
36218
|
-
const name = String(record2.name || "").trim() || "Tool";
|
|
36219
|
-
const input = record2.input && typeof record2.input === "object" ? record2.input : null;
|
|
36220
|
-
const command = input ? String(input.command || "").trim() : "";
|
|
36221
|
-
const summary = command ? `${name}: ${command}` : name;
|
|
36222
|
-
if (summary) parts.push({ content: summary, kind: "tool", senderName: "Tool", role: "assistant" });
|
|
36223
|
-
}
|
|
36224
|
-
}
|
|
36225
|
-
return parts;
|
|
36226
|
-
}
|
|
36227
|
-
function extractClaudeUserContentParts(content) {
|
|
36228
|
-
if (typeof content === "string") {
|
|
36229
|
-
const trimmed = content.trim();
|
|
36230
|
-
return trimmed ? [{ role: "user", content: trimmed, kind: "standard" }] : [];
|
|
36231
|
-
}
|
|
36232
|
-
if (!Array.isArray(content)) return [];
|
|
36233
|
-
const parts = [];
|
|
36234
|
-
for (const block of content) {
|
|
36235
|
-
if (!block || typeof block !== "object") continue;
|
|
36236
|
-
const record2 = block;
|
|
36237
|
-
const type = String(record2.type || "").trim();
|
|
36238
|
-
if (type === "text") {
|
|
36239
|
-
const text = String(record2.text || "").trim();
|
|
36240
|
-
if (text) parts.push({ role: "user", content: text, kind: "standard" });
|
|
36241
|
-
continue;
|
|
36242
|
-
}
|
|
36243
|
-
if (type === "tool_result") {
|
|
36244
|
-
const rawContent = record2.content;
|
|
36245
|
-
const text = typeof rawContent === "string" ? rawContent.trim() : Array.isArray(rawContent) ? rawContent.map((entry) => {
|
|
36246
|
-
if (typeof entry === "string") return entry.trim();
|
|
36247
|
-
if (!entry || typeof entry !== "object") return "";
|
|
36248
|
-
const nested = entry;
|
|
36249
|
-
if (typeof nested.text === "string") return nested.text.trim();
|
|
36250
|
-
if (typeof nested.content === "string") return nested.content.trim();
|
|
36251
|
-
return "";
|
|
36252
|
-
}).filter(Boolean).join("\n") : "";
|
|
36253
|
-
if (text) parts.push({ role: "assistant", content: text, kind: "tool", senderName: "Tool" });
|
|
36254
|
-
}
|
|
36255
|
-
}
|
|
36256
|
-
return parts;
|
|
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
|
-
}
|
|
36329
|
-
function rebuildClaudeSavedHistoryFromNativeProject(historySessionId, workspace) {
|
|
36330
|
-
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
36331
|
-
if (!normalizedSessionId) return false;
|
|
36332
|
-
try {
|
|
36333
|
-
const transcriptPath = resolveClaudeProjectTranscriptPath(normalizedSessionId, workspace);
|
|
36334
|
-
if (!transcriptPath) return false;
|
|
36335
|
-
const lines = fs32.readFileSync(transcriptPath, "utf-8").split("\n").filter(Boolean);
|
|
36336
|
-
const records = [];
|
|
36337
|
-
const existingSessionStart = readExistingSessionStartRecord("claude-cli", normalizedSessionId);
|
|
36338
|
-
if (existingSessionStart) {
|
|
36339
|
-
records.push({
|
|
36340
|
-
...existingSessionStart,
|
|
36341
|
-
historySessionId: normalizedSessionId
|
|
36342
|
-
});
|
|
36343
|
-
}
|
|
36344
|
-
let fallbackTs = Date.now();
|
|
36345
|
-
for (const line of lines) {
|
|
36346
|
-
let parsed = null;
|
|
36347
|
-
try {
|
|
36348
|
-
parsed = JSON.parse(line);
|
|
36349
|
-
} catch {
|
|
36350
|
-
parsed = null;
|
|
36351
|
-
}
|
|
36352
|
-
if (!parsed) continue;
|
|
36353
|
-
const parsedSessionId = String(parsed.sessionId || "").trim();
|
|
36354
|
-
if (parsedSessionId && parsedSessionId !== normalizedSessionId) continue;
|
|
36355
|
-
const receivedAt = extractTimestampValue(parsed.timestamp) || fallbackTs;
|
|
36356
|
-
fallbackTs = receivedAt + 1;
|
|
36357
|
-
const parsedWorkspace = String(parsed.cwd || workspace || "").trim();
|
|
36358
|
-
if (records.length === 0 && parsedWorkspace) {
|
|
36359
|
-
records.push({
|
|
36360
|
-
ts: new Date(receivedAt).toISOString(),
|
|
36361
|
-
receivedAt,
|
|
36362
|
-
role: "system",
|
|
36363
|
-
kind: "session_start",
|
|
36364
|
-
content: parsedWorkspace,
|
|
36365
|
-
agent: "claude-cli",
|
|
36366
|
-
historySessionId: normalizedSessionId,
|
|
36367
|
-
workspace: parsedWorkspace
|
|
36368
|
-
});
|
|
36369
|
-
}
|
|
36370
|
-
const type = String(parsed.type || "").trim();
|
|
36371
|
-
const message = parsed.message && typeof parsed.message === "object" ? parsed.message : null;
|
|
36372
|
-
if (type === "user" && message) {
|
|
36373
|
-
for (const part of extractClaudeUserContentParts(message.content)) {
|
|
36374
|
-
records.push({
|
|
36375
|
-
ts: new Date(receivedAt).toISOString(),
|
|
36376
|
-
receivedAt,
|
|
36377
|
-
role: part.role,
|
|
36378
|
-
content: part.content,
|
|
36379
|
-
kind: part.kind,
|
|
36380
|
-
senderName: part.senderName,
|
|
36381
|
-
agent: "claude-cli",
|
|
36382
|
-
historySessionId: normalizedSessionId
|
|
36383
|
-
});
|
|
36384
|
-
}
|
|
36385
|
-
continue;
|
|
36386
|
-
}
|
|
36387
|
-
if (type === "assistant" && message) {
|
|
36388
|
-
for (const part of extractClaudeAssistantContentParts(message.content)) {
|
|
36389
|
-
records.push({
|
|
36390
|
-
ts: new Date(receivedAt).toISOString(),
|
|
36391
|
-
receivedAt,
|
|
36392
|
-
role: "assistant",
|
|
36393
|
-
content: part.content,
|
|
36394
|
-
kind: part.kind,
|
|
36395
|
-
senderName: part.senderName,
|
|
36396
|
-
agent: "claude-cli",
|
|
36397
|
-
historySessionId: normalizedSessionId
|
|
36398
|
-
});
|
|
36399
|
-
}
|
|
36400
|
-
}
|
|
36401
|
-
}
|
|
36402
|
-
return rewriteCanonicalSavedHistory("claude-cli", normalizedSessionId, records);
|
|
36403
|
-
} catch {
|
|
36404
|
-
return false;
|
|
36405
|
-
}
|
|
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) {
|
|
36050
|
+
function normalizeProviderNativeHistoryRecords(agentType, historySessionId, records) {
|
|
36051
|
+
if (!Array.isArray(records)) return [];
|
|
36423
36052
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
36424
|
-
|
|
36425
|
-
|
|
36426
|
-
|
|
36427
|
-
|
|
36428
|
-
|
|
36429
|
-
|
|
36430
|
-
|
|
36431
|
-
|
|
36432
|
-
|
|
36433
|
-
|
|
36434
|
-
|
|
36435
|
-
|
|
36436
|
-
|
|
36437
|
-
|
|
36438
|
-
|
|
36439
|
-
|
|
36440
|
-
|
|
36441
|
-
|
|
36442
|
-
|
|
36443
|
-
|
|
36444
|
-
|
|
36445
|
-
|
|
36446
|
-
|
|
36447
|
-
|
|
36448
|
-
|
|
36449
|
-
|
|
36450
|
-
|
|
36451
|
-
|
|
36452
|
-
|
|
36453
|
-
|
|
36454
|
-
|
|
36455
|
-
|
|
36456
|
-
|
|
36457
|
-
|
|
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
|
-
}
|
|
36053
|
+
return records.map((record2) => sanitizeHistoryMessage(agentType, {
|
|
36054
|
+
ts: typeof record2?.ts === "string" ? record2.ts : new Date(Number(record2?.receivedAt) || Date.now()).toISOString(),
|
|
36055
|
+
receivedAt: Number(record2?.receivedAt) || Date.parse(record2?.ts || "") || Date.now(),
|
|
36056
|
+
role: record2?.role,
|
|
36057
|
+
content: String(record2?.content || ""),
|
|
36058
|
+
kind: record2?.kind || (record2?.role === "system" ? "session_start" : "standard"),
|
|
36059
|
+
senderName: record2?.senderName,
|
|
36060
|
+
agent: agentType,
|
|
36061
|
+
instanceId: record2?.instanceId,
|
|
36062
|
+
historySessionId: normalizeSavedHistorySessionId(record2?.historySessionId || normalizedSessionId),
|
|
36063
|
+
sessionTitle: record2?.sessionTitle,
|
|
36064
|
+
workspace: record2?.workspace
|
|
36065
|
+
})).filter(Boolean);
|
|
36066
|
+
}
|
|
36067
|
+
function callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, historySessionId, workspace) {
|
|
36068
|
+
const fn2 = getProviderNativeHistoryScript(scripts, canonicalHistory, "readSession");
|
|
36069
|
+
if (!fn2) return null;
|
|
36070
|
+
const result = fn2({
|
|
36071
|
+
agentType,
|
|
36072
|
+
sessionId: historySessionId,
|
|
36073
|
+
historySessionId,
|
|
36074
|
+
workspace,
|
|
36075
|
+
format: canonicalHistory?.format,
|
|
36076
|
+
watchPath: canonicalHistory?.watchPath,
|
|
36077
|
+
args: { sessionId: historySessionId, historySessionId, workspace }
|
|
36078
|
+
});
|
|
36079
|
+
if (!result || typeof result !== "object") return null;
|
|
36080
|
+
const records = normalizeProviderNativeHistoryRecords(agentType, historySessionId, result.messages || result.records);
|
|
36081
|
+
if (records.length === 0) return null;
|
|
36082
|
+
return {
|
|
36083
|
+
records,
|
|
36084
|
+
sourcePath: typeof result.sourcePath === "string" ? result.sourcePath : "",
|
|
36085
|
+
sourceMtimeMs: Number(result.sourceMtimeMs) || 0
|
|
36086
|
+
};
|
|
36511
36087
|
}
|
|
36512
|
-
function
|
|
36513
|
-
const
|
|
36514
|
-
|
|
36515
|
-
|
|
36516
|
-
if (output && typeof output === "object") {
|
|
36517
|
-
try {
|
|
36518
|
-
return JSON.stringify(output).trim();
|
|
36519
|
-
} catch {
|
|
36520
|
-
return "";
|
|
36521
|
-
}
|
|
36522
|
-
}
|
|
36523
|
-
return "";
|
|
36088
|
+
function buildNativeHistoryReadResult(agentType, canonicalHistory, scripts, historySessionId, workspace) {
|
|
36089
|
+
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId || "");
|
|
36090
|
+
if (!canonicalHistory || !normalizedSessionId || !isNativeSourceCanonicalHistory(canonicalHistory)) return null;
|
|
36091
|
+
return callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace);
|
|
36524
36092
|
}
|
|
36525
|
-
function
|
|
36093
|
+
function materializeNativeHistoryToMirror(agentType, canonicalHistory, historySessionId, workspace, scripts) {
|
|
36526
36094
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
36527
|
-
if (!normalizedSessionId
|
|
36528
|
-
|
|
36529
|
-
|
|
36530
|
-
|
|
36531
|
-
|
|
36532
|
-
|
|
36533
|
-
|
|
36534
|
-
|
|
36535
|
-
|
|
36536
|
-
|
|
36537
|
-
|
|
36538
|
-
|
|
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
|
-
}
|
|
36095
|
+
if (!normalizedSessionId) return false;
|
|
36096
|
+
const nativeResult = callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, normalizedSessionId, workspace);
|
|
36097
|
+
const nativeRecords = nativeResult?.records || [];
|
|
36098
|
+
if (nativeRecords.length === 0) return false;
|
|
36099
|
+
const normalizedRecords = nativeRecords.map((record2) => ({
|
|
36100
|
+
...record2,
|
|
36101
|
+
agent: agentType,
|
|
36102
|
+
historySessionId: normalizedSessionId
|
|
36103
|
+
}));
|
|
36104
|
+
const existingSessionStart = readExistingSessionStartRecord(agentType, normalizedSessionId);
|
|
36105
|
+
const records = existingSessionStart && normalizedRecords[0]?.kind !== "session_start" ? [{ ...existingSessionStart, historySessionId: normalizedSessionId, agent: agentType }, ...normalizedRecords] : normalizedRecords;
|
|
36106
|
+
return rewriteCanonicalSavedHistory(agentType, normalizedSessionId, records);
|
|
36617
36107
|
}
|
|
36618
|
-
function
|
|
36619
|
-
|
|
36620
|
-
|
|
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);
|
|
36108
|
+
function materializeProviderNativeHistory(agentType, canonicalHistory, historySessionId, workspace, scripts) {
|
|
36109
|
+
if (!canonicalHistory || canonicalHistory.mode !== "materialized-mirror") return false;
|
|
36110
|
+
return materializeNativeHistoryToMirror(agentType, canonicalHistory, historySessionId, workspace, scripts);
|
|
36626
36111
|
}
|
|
36627
36112
|
function isNativeSourceCanonicalHistory(canonicalHistory) {
|
|
36628
36113
|
if (!canonicalHistory) return false;
|
|
@@ -36630,21 +36115,15 @@ ${cleanBody}`;
|
|
|
36630
36115
|
if (canonicalHistory.mode === "materialized-mirror") return false;
|
|
36631
36116
|
return true;
|
|
36632
36117
|
}
|
|
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
36118
|
function readProviderChatHistory(agentType, options = {}) {
|
|
36642
36119
|
if (isNativeSourceCanonicalHistory(options.canonicalHistory) && options.historySessionId) {
|
|
36643
|
-
const
|
|
36644
|
-
if (!
|
|
36120
|
+
const nativeResult = buildNativeHistoryReadResult(agentType, options.canonicalHistory, options.scripts, options.historySessionId, options.workspace);
|
|
36121
|
+
if (!nativeResult) return { messages: [], hasMore: false, source: "native-unavailable" };
|
|
36645
36122
|
return {
|
|
36646
|
-
...pageHistoryRecords(agentType, records, options.offset || 0, options.limit || 30, options.excludeRecentCount || 0, options.historyBehavior),
|
|
36647
|
-
source: "provider-native"
|
|
36123
|
+
...pageHistoryRecords(agentType, nativeResult.records, options.offset || 0, options.limit || 30, options.excludeRecentCount || 0, options.historyBehavior),
|
|
36124
|
+
source: "provider-native",
|
|
36125
|
+
sourcePath: nativeResult.sourcePath,
|
|
36126
|
+
sourceMtimeMs: nativeResult.sourceMtimeMs
|
|
36648
36127
|
};
|
|
36649
36128
|
}
|
|
36650
36129
|
return {
|
|
@@ -36677,68 +36156,64 @@ ${cleanBody}`;
|
|
|
36677
36156
|
sourceMtimeMs
|
|
36678
36157
|
};
|
|
36679
36158
|
}
|
|
36680
|
-
function
|
|
36681
|
-
|
|
36682
|
-
|
|
36683
|
-
const
|
|
36684
|
-
|
|
36685
|
-
|
|
36686
|
-
|
|
36687
|
-
|
|
36688
|
-
|
|
36689
|
-
|
|
36690
|
-
|
|
36691
|
-
|
|
36692
|
-
|
|
36693
|
-
|
|
36694
|
-
|
|
36695
|
-
|
|
36696
|
-
|
|
36697
|
-
|
|
36698
|
-
|
|
36699
|
-
|
|
36700
|
-
}
|
|
36701
|
-
}
|
|
36702
|
-
return results;
|
|
36159
|
+
function normalizeProviderNativeHistorySessionSummary(agentType, item) {
|
|
36160
|
+
const historySessionId = normalizeSavedHistorySessionId(item?.historySessionId || item?.sessionId || "");
|
|
36161
|
+
if (!historySessionId) return null;
|
|
36162
|
+
const sourcePath = typeof item?.sourcePath === "string" ? item.sourcePath : "";
|
|
36163
|
+
const sourceMtimeMs = Number(item?.sourceMtimeMs) || 0;
|
|
36164
|
+
const firstMessageAt = Number(item?.firstMessageAt) || sourceMtimeMs || Date.now();
|
|
36165
|
+
const lastMessageAt = Number(item?.lastMessageAt) || firstMessageAt;
|
|
36166
|
+
const messageCount = Math.max(0, Number(item?.messageCount) || 0);
|
|
36167
|
+
return {
|
|
36168
|
+
historySessionId,
|
|
36169
|
+
sessionTitle: typeof item?.sessionTitle === "string" ? item.sessionTitle : void 0,
|
|
36170
|
+
messageCount,
|
|
36171
|
+
firstMessageAt,
|
|
36172
|
+
lastMessageAt,
|
|
36173
|
+
preview: typeof item?.preview === "string" ? item.preview : void 0,
|
|
36174
|
+
workspace: typeof item?.workspace === "string" ? item.workspace : void 0,
|
|
36175
|
+
source: "provider-native",
|
|
36176
|
+
sourcePath,
|
|
36177
|
+
sourceMtimeMs
|
|
36178
|
+
};
|
|
36703
36179
|
}
|
|
36704
|
-
function
|
|
36180
|
+
function collectProviderScriptNativeHistorySessionSummaries(agentType, canonicalHistory, scripts) {
|
|
36181
|
+
const fn2 = getProviderNativeHistoryScript(scripts, canonicalHistory, "listSessions");
|
|
36182
|
+
if (!fn2) return null;
|
|
36183
|
+
const result = fn2({
|
|
36184
|
+
agentType,
|
|
36185
|
+
format: canonicalHistory.format,
|
|
36186
|
+
watchPath: canonicalHistory.watchPath,
|
|
36187
|
+
args: {}
|
|
36188
|
+
});
|
|
36189
|
+
if (!result || typeof result !== "object") return [];
|
|
36190
|
+
const sessions = Array.isArray(result.sessions) ? result.sessions : [];
|
|
36705
36191
|
const summaries = [];
|
|
36706
|
-
|
|
36707
|
-
|
|
36708
|
-
|
|
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();
|
|
36192
|
+
for (const item of sessions) {
|
|
36193
|
+
if (Array.isArray(item?.messages || item?.records)) {
|
|
36194
|
+
const historySessionId = normalizeSavedHistorySessionId(item?.historySessionId || item?.sessionId || "");
|
|
36729
36195
|
if (!historySessionId) continue;
|
|
36730
|
-
const records =
|
|
36731
|
-
const
|
|
36732
|
-
if (
|
|
36196
|
+
const records = normalizeProviderNativeHistoryRecords(agentType, historySessionId, item.messages || item.records);
|
|
36197
|
+
const summary2 = buildNativeSessionSummary(agentType, historySessionId, records, typeof item?.sourcePath === "string" ? item.sourcePath : "");
|
|
36198
|
+
if (summary2) {
|
|
36199
|
+
if (Number(item?.sourceMtimeMs)) summary2.sourceMtimeMs = Number(item.sourceMtimeMs);
|
|
36200
|
+
summaries.push(summary2);
|
|
36201
|
+
}
|
|
36202
|
+
continue;
|
|
36733
36203
|
}
|
|
36204
|
+
const summary = normalizeProviderNativeHistorySessionSummary(agentType, item);
|
|
36205
|
+
if (summary) summaries.push(summary);
|
|
36734
36206
|
}
|
|
36735
36207
|
return sortSavedHistorySessionSummaries(summaries);
|
|
36736
36208
|
}
|
|
36209
|
+
function collectNativeHistorySessionSummaries(agentType, canonicalHistory, scripts) {
|
|
36210
|
+
return collectProviderScriptNativeHistorySessionSummaries(agentType, canonicalHistory, scripts) || [];
|
|
36211
|
+
}
|
|
36737
36212
|
function listProviderHistorySessions(agentType, options = {}) {
|
|
36738
36213
|
if (isNativeSourceCanonicalHistory(options.canonicalHistory)) {
|
|
36739
36214
|
const offset = Math.max(0, options.offset || 0);
|
|
36740
36215
|
const limit = Math.max(1, options.limit || 30);
|
|
36741
|
-
const summaries = collectNativeHistorySessionSummaries(agentType, options.canonicalHistory);
|
|
36216
|
+
const summaries = collectNativeHistorySessionSummaries(agentType, options.canonicalHistory, options.scripts);
|
|
36742
36217
|
return {
|
|
36743
36218
|
sessions: summaries.slice(offset, offset + limit),
|
|
36744
36219
|
hasMore: offset + limit < summaries.length,
|
|
@@ -39325,7 +38800,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
39325
38800
|
offset: offset || 0,
|
|
39326
38801
|
limit: limit || 30,
|
|
39327
38802
|
excludeRecentCount,
|
|
39328
|
-
historyBehavior: provider?.historyBehavior
|
|
38803
|
+
historyBehavior: provider?.historyBehavior,
|
|
38804
|
+
scripts: provider?.scripts
|
|
39329
38805
|
});
|
|
39330
38806
|
return { success: true, ...result, agent: agentStr };
|
|
39331
38807
|
} catch (e) {
|
|
@@ -41777,13 +41253,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
41777
41253
|
historyWriter;
|
|
41778
41254
|
runtimeMessages = [];
|
|
41779
41255
|
lastPersistedHistoryMessages = [];
|
|
41780
|
-
|
|
41781
|
-
|
|
41782
|
-
lastCanonicalHermesWatchPath = void 0;
|
|
41783
|
-
lastCanonicalClaudeRebuildMtimeMs = 0;
|
|
41784
|
-
lastCanonicalClaudeCheckAt = 0;
|
|
41785
|
-
lastCanonicalCodexRebuildMtimeMs = 0;
|
|
41786
|
-
lastCanonicalCodexCheckAt = 0;
|
|
41256
|
+
lastNativeSourceCanonicalCheckAt = 0;
|
|
41257
|
+
lastNativeSourceCanonicalCacheKey = void 0;
|
|
41787
41258
|
cachedSqliteDb = null;
|
|
41788
41259
|
cachedSqliteDbPath = null;
|
|
41789
41260
|
cachedSqliteDbMissingUntil = 0;
|
|
@@ -42484,76 +41955,44 @@ ${effect.notification.body || ""}`.trim();
|
|
|
42484
41955
|
const canonicalHistory = this.provider.canonicalHistory;
|
|
42485
41956
|
if (!canonicalHistory) return false;
|
|
42486
41957
|
if (isNativeSourceCanonicalHistory(canonicalHistory)) {
|
|
41958
|
+
const cacheKey = [this.type, this.providerSessionId, this.workingDir].join("\0");
|
|
41959
|
+
const now = Date.now();
|
|
41960
|
+
if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
|
|
41961
|
+
return true;
|
|
41962
|
+
}
|
|
41963
|
+
this.lastNativeSourceCanonicalCacheKey = cacheKey;
|
|
41964
|
+
this.lastNativeSourceCanonicalCheckAt = now;
|
|
42487
41965
|
const restoredHistory = readProviderChatHistory(this.type, {
|
|
42488
41966
|
canonicalHistory,
|
|
42489
41967
|
historySessionId: this.providerSessionId,
|
|
42490
41968
|
workspace: this.workingDir,
|
|
42491
41969
|
offset: 0,
|
|
42492
41970
|
limit: Number.MAX_SAFE_INTEGER,
|
|
42493
|
-
historyBehavior: this.provider.historyBehavior
|
|
41971
|
+
historyBehavior: this.provider.historyBehavior,
|
|
41972
|
+
scripts: this.provider.scripts
|
|
42494
41973
|
});
|
|
42495
|
-
if (restoredHistory.source
|
|
42496
|
-
|
|
42497
|
-
|
|
42498
|
-
|
|
42499
|
-
|
|
42500
|
-
|
|
42501
|
-
|
|
42502
|
-
|
|
41974
|
+
if (restoredHistory.source === "provider-native") {
|
|
41975
|
+
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
41976
|
+
role: message.role,
|
|
41977
|
+
content: message.content,
|
|
41978
|
+
kind: message.kind,
|
|
41979
|
+
senderName: message.senderName,
|
|
41980
|
+
receivedAt: message.receivedAt
|
|
41981
|
+
}));
|
|
41982
|
+
}
|
|
42503
41983
|
return true;
|
|
42504
41984
|
}
|
|
42505
41985
|
try {
|
|
42506
|
-
|
|
42507
|
-
|
|
42508
|
-
|
|
42509
|
-
|
|
42510
|
-
|
|
42511
|
-
|
|
42512
|
-
|
|
42513
|
-
|
|
42514
|
-
|
|
42515
|
-
if (!fs52.existsSync(watchPath)) return false;
|
|
42516
|
-
}
|
|
42517
|
-
const stat4 = fs52.statSync(watchPath);
|
|
42518
|
-
if (stat4.mtimeMs <= this.lastCanonicalHermesSyncMtimeMs) return true;
|
|
42519
|
-
rebuilt = rebuildHermesSavedHistoryFromCanonicalSession(this.providerSessionId);
|
|
42520
|
-
if (rebuilt) this.lastCanonicalHermesSyncMtimeMs = stat4.mtimeMs;
|
|
42521
|
-
} else if (canonicalHistory.format === "claude-jsonl") {
|
|
42522
|
-
const now = Date.now();
|
|
42523
|
-
if (now - this.lastCanonicalClaudeCheckAt < 2e3 && this.lastCanonicalClaudeRebuildMtimeMs !== 0) {
|
|
42524
|
-
return true;
|
|
42525
|
-
}
|
|
42526
|
-
this.lastCanonicalClaudeCheckAt = now;
|
|
42527
|
-
const claudeProjectsDir = path11.join(os11.homedir(), ".claude", "projects");
|
|
42528
|
-
const workspaceSegment = typeof this.workingDir === "string" ? this.workingDir.replace(/[\\/]/g, "-").replace(/^-+/, "") : "";
|
|
42529
|
-
const transcriptFile = path11.join(claudeProjectsDir, workspaceSegment, `${this.providerSessionId}.jsonl`);
|
|
42530
|
-
let transcriptMtime = 0;
|
|
42531
|
-
try {
|
|
42532
|
-
transcriptMtime = fs52.statSync(transcriptFile).mtimeMs;
|
|
42533
|
-
} catch {
|
|
42534
|
-
}
|
|
42535
|
-
if (transcriptMtime > 0 && transcriptMtime <= this.lastCanonicalClaudeRebuildMtimeMs) return true;
|
|
42536
|
-
rebuilt = rebuildClaudeSavedHistoryFromNativeProject(this.providerSessionId, this.workingDir);
|
|
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();
|
|
41986
|
+
const cacheKey = [this.type, this.providerSessionId, this.workingDir, canonicalHistory.mode || "materialized-mirror"].join("\0");
|
|
41987
|
+
const now = Date.now();
|
|
41988
|
+
if (cacheKey === this.lastNativeSourceCanonicalCacheKey && now - this.lastNativeSourceCanonicalCheckAt < 2e3) {
|
|
41989
|
+
return true;
|
|
41990
|
+
}
|
|
41991
|
+
this.lastNativeSourceCanonicalCacheKey = cacheKey;
|
|
41992
|
+
this.lastNativeSourceCanonicalCheckAt = now;
|
|
41993
|
+
if (!materializeProviderNativeHistory(this.type, canonicalHistory, this.providerSessionId, this.workingDir, this.provider.scripts)) {
|
|
41994
|
+
return false;
|
|
42555
41995
|
}
|
|
42556
|
-
if (!rebuilt) return false;
|
|
42557
41996
|
const restoredHistory = readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
|
|
42558
41997
|
this.lastPersistedHistoryMessages = restoredHistory.messages.map((message) => ({
|
|
42559
41998
|
role: message.role,
|
|
@@ -42576,7 +42015,8 @@ ${effect.notification.body || ""}`.trim();
|
|
|
42576
42015
|
workspace: this.workingDir,
|
|
42577
42016
|
offset: 0,
|
|
42578
42017
|
limit: Number.MAX_SAFE_INTEGER,
|
|
42579
|
-
historyBehavior: this.provider.historyBehavior
|
|
42018
|
+
historyBehavior: this.provider.historyBehavior,
|
|
42019
|
+
scripts: this.provider.scripts
|
|
42580
42020
|
}) : (() => {
|
|
42581
42021
|
this.historyWriter.compactHistorySession(this.type, this.providerSessionId, this.provider.historyBehavior);
|
|
42582
42022
|
return readChatHistory(this.type, 0, Number.MAX_SAFE_INTEGER, this.providerSessionId, 0, this.provider.historyBehavior);
|
|
@@ -44697,6 +44137,7 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44697
44137
|
warnings.push("Extension providers should have extensionId");
|
|
44698
44138
|
}
|
|
44699
44139
|
validateCapabilities(provider, controls, errors);
|
|
44140
|
+
validateCanonicalHistory(provider.canonicalHistory, errors);
|
|
44700
44141
|
for (const control of controls) {
|
|
44701
44142
|
validateControl(control, errors);
|
|
44702
44143
|
}
|
|
@@ -44754,6 +44195,39 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
44754
44195
|
errors.push("providers declaring controls must set capabilities.controls.typedResults=true");
|
|
44755
44196
|
}
|
|
44756
44197
|
}
|
|
44198
|
+
function validateCanonicalHistory(raw, errors) {
|
|
44199
|
+
if (raw === void 0) return;
|
|
44200
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
44201
|
+
errors.push("canonicalHistory must be an object");
|
|
44202
|
+
return;
|
|
44203
|
+
}
|
|
44204
|
+
const canonicalHistory = raw;
|
|
44205
|
+
const format = canonicalHistory.format;
|
|
44206
|
+
if (format !== void 0 && (typeof format !== "string" || !format.trim())) {
|
|
44207
|
+
errors.push("canonicalHistory.format must be a non-empty string when provided");
|
|
44208
|
+
}
|
|
44209
|
+
const watchPath = canonicalHistory.watchPath;
|
|
44210
|
+
if (watchPath !== void 0 && (typeof watchPath !== "string" || !watchPath.trim())) {
|
|
44211
|
+
errors.push("canonicalHistory.watchPath must be a non-empty string when provided");
|
|
44212
|
+
}
|
|
44213
|
+
const mode = canonicalHistory.mode;
|
|
44214
|
+
if (mode !== void 0 && !["native-source", "materialized-mirror", "disabled"].includes(String(mode))) {
|
|
44215
|
+
errors.push("canonicalHistory.mode must be one of: native-source, materialized-mirror, disabled");
|
|
44216
|
+
}
|
|
44217
|
+
const scripts = canonicalHistory.scripts;
|
|
44218
|
+
if (scripts === void 0) return;
|
|
44219
|
+
if (!scripts || typeof scripts !== "object" || Array.isArray(scripts)) {
|
|
44220
|
+
errors.push("canonicalHistory.scripts must be an object");
|
|
44221
|
+
return;
|
|
44222
|
+
}
|
|
44223
|
+
const scriptConfig = scripts;
|
|
44224
|
+
for (const key of ["readSession", "listSessions"]) {
|
|
44225
|
+
const value = scriptConfig[key];
|
|
44226
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
44227
|
+
errors.push(`canonicalHistory.scripts.${key} must be a non-empty string`);
|
|
44228
|
+
}
|
|
44229
|
+
}
|
|
44230
|
+
}
|
|
44757
44231
|
function validateControl(control, errors) {
|
|
44758
44232
|
if (!control || typeof control !== "object") {
|
|
44759
44233
|
errors.push("controls: each control must be an object");
|
|
@@ -47874,12 +47348,13 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47874
47348
|
const wantsAll = args?.all === true;
|
|
47875
47349
|
const offset = wantsAll ? 0 : Math.max(0, Number(args?.offset) || 0);
|
|
47876
47350
|
const limit = wantsAll ? Number.MAX_SAFE_INTEGER : Math.max(1, Math.min(100, Number(args?.limit) || 30));
|
|
47877
|
-
const providerMeta = this.deps.providerLoader.getMeta(providerType);
|
|
47351
|
+
const providerMeta = this.deps.providerLoader.resolve?.(providerType) || this.deps.providerLoader.getMeta(providerType);
|
|
47878
47352
|
const { sessions: historySessions, hasMore, source } = listProviderHistorySessions(providerType, {
|
|
47879
47353
|
canonicalHistory: providerMeta?.canonicalHistory,
|
|
47880
47354
|
offset,
|
|
47881
47355
|
limit,
|
|
47882
|
-
historyBehavior: providerMeta?.historyBehavior
|
|
47356
|
+
historyBehavior: providerMeta?.historyBehavior,
|
|
47357
|
+
scripts: providerMeta?.scripts
|
|
47883
47358
|
});
|
|
47884
47359
|
const state = loadState();
|
|
47885
47360
|
const savedSessions = getSavedProviderSessions(state, { providerType, kind });
|
|
@@ -47905,7 +47380,10 @@ Run 'adhdev doctor' for detailed diagnostics.`
|
|
|
47905
47380
|
messageCount: session.messageCount,
|
|
47906
47381
|
firstMessageAt: session.firstMessageAt,
|
|
47907
47382
|
lastMessageAt: session.lastMessageAt,
|
|
47908
|
-
canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById
|
|
47383
|
+
canResume: !!(saved?.workspace || recent?.workspace || session.workspace) && canResumeById,
|
|
47384
|
+
historySource: session.source,
|
|
47385
|
+
sourcePath: session.sourcePath,
|
|
47386
|
+
sourceMtimeMs: session.sourceMtimeMs
|
|
47909
47387
|
};
|
|
47910
47388
|
}),
|
|
47911
47389
|
hasMore,
|