agentel 0.2.8 → 0.3.0
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/README.md +222 -68
- package/docs/code-reference.md +121 -37
- package/docs/history-source-handling.md +555 -124
- package/docs/release.md +35 -8
- package/npm-shrinkwrap.json +478 -0
- package/package.json +18 -5
- package/scripts/postinstall.js +156 -0
- package/src/archive.js +1174 -65
- package/src/canonical-events.js +346 -35
- package/src/cli.js +7121 -819
- package/src/collector.js +42 -4
- package/src/config.js +15 -4
- package/src/diffs.js +156 -0
- package/src/doctor.js +48 -5
- package/src/importers/claude.js +51 -4
- package/src/importers/copilot.js +385 -0
- package/src/importers/cursor-recovery.js +22 -0
- package/src/importers/factory.js +396 -0
- package/src/importers/gemini.js +39 -0
- package/src/importers/grok.js +367 -0
- package/src/importers/pi.js +422 -0
- package/src/importers/providers.js +64 -5
- package/src/importers.js +4524 -383
- package/src/mcp.js +1 -0
- package/src/memory-sources.js +671 -0
- package/src/memory-store.js +0 -0
- package/src/parser-versions.js +13 -0
- package/src/pricing.js +84 -0
- package/src/search.js +256 -70
- package/src/session-store.js +405 -0
- package/src/source-watch.js +293 -0
- package/src/sources.js +60 -11
- package/src/supervisor.js +197 -9
- package/src/sync.js +6 -0
- package/src/unavailable-sources.js +358 -0
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
|
|
5
|
+
const PROVIDER = "pi";
|
|
6
|
+
|
|
7
|
+
function parsePiSessionFile(file, options = {}) {
|
|
8
|
+
let text;
|
|
9
|
+
try {
|
|
10
|
+
text = fs.readFileSync(file, "utf8");
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
return parsePiSessionText(text, options);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// pi sessions are JSONL with a `session` header line followed by tree-linked
|
|
18
|
+
// entries (id/parentId, 8-char hex). v1 files have no entry ids and store
|
|
19
|
+
// provider/modelId on the header; v2 added the tree plus branch/label/custom
|
|
20
|
+
// entries; v3 renamed the hookMessage role to custom. Entries are imported in
|
|
21
|
+
// file order (branches included) with ids preserved in metadata.
|
|
22
|
+
function parsePiSessionText(text, options = {}) {
|
|
23
|
+
const lines = String(text || "").split(/\r?\n/);
|
|
24
|
+
let header = null;
|
|
25
|
+
let name = "";
|
|
26
|
+
const messages = [];
|
|
27
|
+
const fallbackTime = toIso(options.fallbackTime) || new Date().toISOString();
|
|
28
|
+
let index = 0;
|
|
29
|
+
for (const line of lines) {
|
|
30
|
+
if (!line.trim()) continue;
|
|
31
|
+
const entry = parseJson(line);
|
|
32
|
+
if (!entry || typeof entry !== "object") continue;
|
|
33
|
+
if (entry.type === "session") {
|
|
34
|
+
header ||= entry;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (!header) return null;
|
|
38
|
+
const timestamp = toIso(entry.timestamp) || offsetTimestamp(fallbackTime, index);
|
|
39
|
+
index++;
|
|
40
|
+
if (entry.type === "session_info") {
|
|
41
|
+
name = firstString(entry.name, name);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (entry.type === "message" && entry.message && typeof entry.message === "object") {
|
|
45
|
+
messages.push(...piEntryMessages(entry, timestamp, header));
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const systemMessage = piSystemMessage(entry, timestamp);
|
|
49
|
+
if (systemMessage) messages.push(systemMessage);
|
|
50
|
+
}
|
|
51
|
+
if (!header || !firstString(header.id)) return null;
|
|
52
|
+
return {
|
|
53
|
+
header,
|
|
54
|
+
sessionId: firstString(header.id),
|
|
55
|
+
title: name,
|
|
56
|
+
cwd: firstString(header.cwd),
|
|
57
|
+
version: Number(header.version) || 1,
|
|
58
|
+
parentSession: firstString(header.parentSession, header.branchedFrom),
|
|
59
|
+
messages,
|
|
60
|
+
startedAt: toIso(header.timestamp) || messages[0]?.timestamp || fallbackTime,
|
|
61
|
+
endedAt: messages[messages.length - 1]?.timestamp || toIso(header.timestamp) || fallbackTime
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function piEntryMessages(entry, timestamp, header) {
|
|
66
|
+
const payload = entry.message;
|
|
67
|
+
const role = String(payload.role || "");
|
|
68
|
+
const base = compactObject({
|
|
69
|
+
provider: PROVIDER,
|
|
70
|
+
providerMessageId: firstString(entry.id),
|
|
71
|
+
parentMessageId: firstString(entry.parentId)
|
|
72
|
+
}) || { provider: PROVIDER };
|
|
73
|
+
if (role === "user") {
|
|
74
|
+
const content = piContentText(payload.content);
|
|
75
|
+
if (!content) return [];
|
|
76
|
+
return [{ role: "user", content, timestamp, metadata: { ...base } }];
|
|
77
|
+
}
|
|
78
|
+
if (role === "assistant") {
|
|
79
|
+
return piAssistantMessages(payload, timestamp, base, header);
|
|
80
|
+
}
|
|
81
|
+
if (role === "toolResult") {
|
|
82
|
+
const toolResult = piToolResult(payload);
|
|
83
|
+
if (!toolResult) return [];
|
|
84
|
+
return [{ role: "tool", content: toolResult.output, timestamp, metadata: { ...base, toolResult } }];
|
|
85
|
+
}
|
|
86
|
+
if (role === "bashExecution") {
|
|
87
|
+
return piBashExecutionMessages(payload, timestamp, base);
|
|
88
|
+
}
|
|
89
|
+
if (role === "custom" || role === "hookMessage") {
|
|
90
|
+
const content = piContentText(payload.content);
|
|
91
|
+
if (!content) return [];
|
|
92
|
+
return [{
|
|
93
|
+
role: "system",
|
|
94
|
+
content,
|
|
95
|
+
timestamp,
|
|
96
|
+
metadata: { ...base, providerGenerated: true, contextKind: "extension", contextSource: firstString(payload.customType) || undefined }
|
|
97
|
+
}];
|
|
98
|
+
}
|
|
99
|
+
if (role === "branchSummary" || role === "compactionSummary") {
|
|
100
|
+
const content = firstString(payload.summary);
|
|
101
|
+
if (!content) return [];
|
|
102
|
+
return [{
|
|
103
|
+
role: "system",
|
|
104
|
+
content,
|
|
105
|
+
timestamp,
|
|
106
|
+
metadata: { ...base, providerGenerated: true, contextKind: role === "branchSummary" ? "branch_summary" : "compaction" }
|
|
107
|
+
}];
|
|
108
|
+
}
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function piAssistantMessages(payload, timestamp, base, header) {
|
|
113
|
+
const blocks = Array.isArray(payload.content) ? payload.content : [];
|
|
114
|
+
const texts = [];
|
|
115
|
+
const thinking = [];
|
|
116
|
+
const toolCalls = [];
|
|
117
|
+
for (const block of blocks) {
|
|
118
|
+
if (!block || typeof block !== "object") continue;
|
|
119
|
+
if (block.type === "text" && typeof block.text === "string") texts.push(block.text);
|
|
120
|
+
else if (block.type === "thinking") thinking.push(block.redacted ? "[redacted thinking]" : firstString(block.thinking));
|
|
121
|
+
else if (block.type === "toolCall") {
|
|
122
|
+
const call = piToolCall(block);
|
|
123
|
+
if (call) toolCalls.push(call);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (typeof payload.content === "string") texts.push(payload.content);
|
|
127
|
+
const content = texts.filter(Boolean).join("\n").trim();
|
|
128
|
+
const thinkingText = thinking.filter(Boolean).join("\n\n").trim();
|
|
129
|
+
if (!content && !toolCalls.length && !thinkingText && !payload.errorMessage) return [];
|
|
130
|
+
return [{
|
|
131
|
+
role: "assistant",
|
|
132
|
+
content: content || (payload.errorMessage ? `Error: ${payload.errorMessage}` : ""),
|
|
133
|
+
timestamp,
|
|
134
|
+
metadata: compactObject({
|
|
135
|
+
...base,
|
|
136
|
+
model: firstString(payload.model, payload.responseModel, header?.modelId) || undefined,
|
|
137
|
+
modelProvider: firstString(payload.provider, header?.provider) || undefined,
|
|
138
|
+
thinking: thinkingText || undefined,
|
|
139
|
+
stopReason: firstString(payload.stopReason) || undefined,
|
|
140
|
+
isError: payload.stopReason === "error" || undefined,
|
|
141
|
+
usage: piUsage(payload.usage),
|
|
142
|
+
toolCalls: toolCalls.length ? toolCalls : undefined
|
|
143
|
+
})
|
|
144
|
+
}];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function piToolCall(block) {
|
|
148
|
+
const name = firstString(block.name);
|
|
149
|
+
if (!name) return null;
|
|
150
|
+
const args = block.arguments && typeof block.arguments === "object" ? block.arguments : undefined;
|
|
151
|
+
const summary = summarizeToolArguments(args);
|
|
152
|
+
return compactObject({
|
|
153
|
+
id: firstString(block.id) || undefined,
|
|
154
|
+
name,
|
|
155
|
+
displayName: toolDisplayName(name),
|
|
156
|
+
rawCategory: "toolCall",
|
|
157
|
+
category: piToolCategory(name),
|
|
158
|
+
title: toolDisplayName(name),
|
|
159
|
+
status: "tool_call",
|
|
160
|
+
argument: summary,
|
|
161
|
+
rawInputSummary: summary,
|
|
162
|
+
inputPreview: summary,
|
|
163
|
+
target: toolTarget(args) || undefined,
|
|
164
|
+
arguments: args,
|
|
165
|
+
provider: PROVIDER
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function piToolResult(payload) {
|
|
170
|
+
const output = piContentText(payload.content);
|
|
171
|
+
const id = firstString(payload.toolCallId);
|
|
172
|
+
if (!output && !id) return null;
|
|
173
|
+
const isError = payload.isError === true;
|
|
174
|
+
const lineCount = output ? output.split(/\r?\n/).length : 0;
|
|
175
|
+
return compactObject({
|
|
176
|
+
provider: PROVIDER,
|
|
177
|
+
id: id || undefined,
|
|
178
|
+
kind: toolDisplayName(firstString(payload.toolName, "tool")),
|
|
179
|
+
title: isError ? "Tool error" : "Tool result",
|
|
180
|
+
rawCategory: "toolResult",
|
|
181
|
+
category: piToolCategory(firstString(payload.toolName)),
|
|
182
|
+
summary: firstLine(output),
|
|
183
|
+
output,
|
|
184
|
+
lineCount: lineCount || undefined,
|
|
185
|
+
collapsed: lineCount > 18 || undefined,
|
|
186
|
+
status: isError ? "error" : "completed"
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// `!` shell commands typed by the user are stored as bashExecution messages
|
|
191
|
+
// with the captured output and exit code.
|
|
192
|
+
function piBashExecutionMessages(payload, timestamp, base) {
|
|
193
|
+
const command = firstString(payload.command);
|
|
194
|
+
if (!command) return [];
|
|
195
|
+
const messages = [{
|
|
196
|
+
role: "user",
|
|
197
|
+
content: `! ${command}`,
|
|
198
|
+
timestamp,
|
|
199
|
+
metadata: { ...base, eventType: "pi-bash-execution" }
|
|
200
|
+
}];
|
|
201
|
+
const output = firstString(payload.output);
|
|
202
|
+
if (output) {
|
|
203
|
+
const lineCount = output.split(/\r?\n/).length;
|
|
204
|
+
messages.push({
|
|
205
|
+
role: "tool",
|
|
206
|
+
content: output,
|
|
207
|
+
timestamp,
|
|
208
|
+
metadata: {
|
|
209
|
+
...base,
|
|
210
|
+
toolResult: compactObject({
|
|
211
|
+
provider: PROVIDER,
|
|
212
|
+
kind: "Bash",
|
|
213
|
+
title: payload.exitCode ? "Tool error" : "Tool result",
|
|
214
|
+
rawCategory: "bashExecution",
|
|
215
|
+
category: "shell",
|
|
216
|
+
summary: firstLine(output),
|
|
217
|
+
output,
|
|
218
|
+
lineCount,
|
|
219
|
+
collapsed: lineCount > 18 || undefined,
|
|
220
|
+
status: payload.cancelled ? "cancelled" : payload.exitCode ? "error" : "completed",
|
|
221
|
+
exitCode: Number.isFinite(Number(payload.exitCode)) ? Number(payload.exitCode) : undefined
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return messages;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function piSystemMessage(entry, timestamp) {
|
|
230
|
+
const base = compactObject({
|
|
231
|
+
provider: PROVIDER,
|
|
232
|
+
providerMessageId: firstString(entry.id),
|
|
233
|
+
parentMessageId: firstString(entry.parentId),
|
|
234
|
+
providerGenerated: true
|
|
235
|
+
});
|
|
236
|
+
if (entry.type === "model_change") {
|
|
237
|
+
const model = firstString(entry.modelId, entry.model);
|
|
238
|
+
if (!model) return null;
|
|
239
|
+
return {
|
|
240
|
+
role: "system",
|
|
241
|
+
content: `Model changed to ${model}`,
|
|
242
|
+
timestamp,
|
|
243
|
+
metadata: { ...base, eventType: "pi-model-change", contextKind: "model_change", model }
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
if (entry.type === "thinking_level_change") {
|
|
247
|
+
const level = firstString(entry.thinkingLevel);
|
|
248
|
+
if (!level) return null;
|
|
249
|
+
return {
|
|
250
|
+
role: "system",
|
|
251
|
+
content: `Thinking level changed to ${level}`,
|
|
252
|
+
timestamp,
|
|
253
|
+
metadata: { ...base, eventType: "pi-thinking-level-change", contextKind: "thinking_level_change" }
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
if (entry.type === "compaction") {
|
|
257
|
+
return {
|
|
258
|
+
role: "system",
|
|
259
|
+
content: firstString(entry.summary, "Context compacted"),
|
|
260
|
+
timestamp,
|
|
261
|
+
metadata: compactObject({
|
|
262
|
+
...base,
|
|
263
|
+
eventType: "pi-compaction",
|
|
264
|
+
contextKind: "compaction",
|
|
265
|
+
tokensBefore: Number.isFinite(Number(entry.tokensBefore)) ? Number(entry.tokensBefore) : undefined,
|
|
266
|
+
firstKeptEntryId: firstString(entry.firstKeptEntryId) || undefined
|
|
267
|
+
})
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
if (entry.type === "branch_summary") {
|
|
271
|
+
return {
|
|
272
|
+
role: "system",
|
|
273
|
+
content: firstString(entry.summary, "Returned from branch"),
|
|
274
|
+
timestamp,
|
|
275
|
+
metadata: compactObject({ ...base, eventType: "pi-branch-summary", contextKind: "branch_summary", fromId: firstString(entry.fromId) || undefined })
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
if (entry.type === "custom_message") {
|
|
279
|
+
const content = piContentText(entry.content);
|
|
280
|
+
if (!content) return null;
|
|
281
|
+
return {
|
|
282
|
+
role: "system",
|
|
283
|
+
content,
|
|
284
|
+
timestamp,
|
|
285
|
+
metadata: compactObject({ ...base, eventType: "pi-custom-message", contextKind: "extension", contextSource: firstString(entry.customType) || undefined })
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// pi usage mirrors API token fields: input excludes cache reads/writes, and
|
|
292
|
+
// per-message dollar cost is stored under cost.total.
|
|
293
|
+
function piUsage(usage) {
|
|
294
|
+
if (!usage || typeof usage !== "object") return undefined;
|
|
295
|
+
const inputTokens = positiveNumber(usage.input);
|
|
296
|
+
const outputTokens = positiveNumber(usage.output);
|
|
297
|
+
const cacheReadTokens = positiveNumber(usage.cacheRead);
|
|
298
|
+
const cacheCreationInputTokens = positiveNumber(usage.cacheWrite);
|
|
299
|
+
const totalTokens = positiveNumber(usage.totalTokens);
|
|
300
|
+
const costUsd = positiveNumber(usage.cost?.total);
|
|
301
|
+
if (!inputTokens && !outputTokens && !cacheReadTokens && !cacheCreationInputTokens && !totalTokens) return undefined;
|
|
302
|
+
return compactObject({
|
|
303
|
+
inputTokens,
|
|
304
|
+
outputTokens,
|
|
305
|
+
cacheReadTokens,
|
|
306
|
+
cacheCreationInputTokens,
|
|
307
|
+
totalTokens,
|
|
308
|
+
costUsd
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function piContentText(content) {
|
|
313
|
+
if (typeof content === "string") return content.trim();
|
|
314
|
+
if (!Array.isArray(content)) return "";
|
|
315
|
+
return content
|
|
316
|
+
.map((block) => {
|
|
317
|
+
if (typeof block === "string") return block;
|
|
318
|
+
if (block && typeof block === "object" && typeof block.text === "string") return block.text;
|
|
319
|
+
if (block && typeof block === "object" && block.type === "image") return "[Attachment: image]";
|
|
320
|
+
return "";
|
|
321
|
+
})
|
|
322
|
+
.filter(Boolean)
|
|
323
|
+
.join("\n")
|
|
324
|
+
.trim();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function piToolCategory(name) {
|
|
328
|
+
const text = String(name || "");
|
|
329
|
+
if (/subagent|task|agent/i.test(text)) return "task";
|
|
330
|
+
if (/bash|shell|command|exec/i.test(text)) return "shell";
|
|
331
|
+
if (/web|fetch|url|http|browser/i.test(text)) return "web";
|
|
332
|
+
if (/edit|write|patch|replace/i.test(text)) return "edit";
|
|
333
|
+
if (/read|view|cat|ls|list/i.test(text)) return "read";
|
|
334
|
+
if (/grep|glob|find|search|rg/i.test(text)) return "search";
|
|
335
|
+
if (/^mcp/i.test(text)) return "mcp";
|
|
336
|
+
return "tool";
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
function summarizeToolArguments(value) {
|
|
340
|
+
if (value == null) return "";
|
|
341
|
+
if (typeof value === "string") return value.slice(0, 240);
|
|
342
|
+
if (typeof value !== "object") return String(value).slice(0, 240);
|
|
343
|
+
for (const key of ["command", "prompt", "query", "pattern", "path", "file_path", "url"]) {
|
|
344
|
+
if (value[key]) return String(value[key]).slice(0, 240);
|
|
345
|
+
}
|
|
346
|
+
return Object.entries(value)
|
|
347
|
+
.slice(0, 3)
|
|
348
|
+
.map(([key, item]) => `${key}: ${typeof item === "string" ? item : JSON.stringify(item)}`)
|
|
349
|
+
.join(", ")
|
|
350
|
+
.slice(0, 240);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function toolTarget(args) {
|
|
354
|
+
if (!args || typeof args !== "object") return "";
|
|
355
|
+
return firstString(args.path, args.file_path, args.filePath, args.file, args.directory, args.url);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function toolDisplayName(value) {
|
|
359
|
+
const text = String(value || "tool").trim();
|
|
360
|
+
return text
|
|
361
|
+
.split(/_+|(?=[A-Z])/g)
|
|
362
|
+
.filter(Boolean)
|
|
363
|
+
.map((part) => part.replace(/(^|[-\s])([a-z])/g, (_, prefix, char) => `${prefix}${char.toUpperCase()}`))
|
|
364
|
+
.join(" ");
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function firstLine(value) {
|
|
368
|
+
return String(value || "").split(/\r?\n/).find((line) => line.trim())?.trim() || "";
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function offsetTimestamp(base, index) {
|
|
372
|
+
const date = new Date(base);
|
|
373
|
+
if (Number.isNaN(date.valueOf())) return base;
|
|
374
|
+
return new Date(date.valueOf() + index * 1000).toISOString();
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function toIso(value) {
|
|
378
|
+
if (!value) return "";
|
|
379
|
+
if (typeof value === "number") {
|
|
380
|
+
const ms = value > 1e12 ? value : value * 1000;
|
|
381
|
+
const date = new Date(ms);
|
|
382
|
+
return Number.isNaN(date.valueOf()) ? "" : date.toISOString();
|
|
383
|
+
}
|
|
384
|
+
const date = new Date(value);
|
|
385
|
+
return Number.isNaN(date.valueOf()) ? "" : date.toISOString();
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
function parseJson(text) {
|
|
389
|
+
if (typeof text !== "string" || !text.trim()) return null;
|
|
390
|
+
try {
|
|
391
|
+
return JSON.parse(text);
|
|
392
|
+
} catch {
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
function firstString(...values) {
|
|
398
|
+
for (const value of values) {
|
|
399
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
400
|
+
}
|
|
401
|
+
return "";
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function positiveNumber(value) {
|
|
405
|
+
const number = Number(value);
|
|
406
|
+
return Number.isFinite(number) && number > 0 ? number : undefined;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
function compactObject(value) {
|
|
410
|
+
if (!value || typeof value !== "object") return value;
|
|
411
|
+
const result = {};
|
|
412
|
+
for (const [key, item] of Object.entries(value)) {
|
|
413
|
+
if (item === undefined || item === null || item === "") continue;
|
|
414
|
+
result[key] = item;
|
|
415
|
+
}
|
|
416
|
+
return Object.keys(result).length ? result : undefined;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
module.exports = {
|
|
420
|
+
parsePiSessionFile,
|
|
421
|
+
parsePiSessionText
|
|
422
|
+
};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
const { canonicalImportSource } = require("../sources");
|
|
4
|
+
|
|
3
5
|
const PROVIDER_ADAPTERS = [
|
|
4
6
|
{
|
|
5
7
|
source: "codex",
|
|
@@ -67,10 +69,10 @@ const PROVIDER_ADAPTERS = [
|
|
|
67
69
|
helpers.importClaudeDesktopProvider("claude_desktop", since, { ...options, claudeDesktopKind: "claude-code-desktop-metadata" }, env)
|
|
68
70
|
},
|
|
69
71
|
{
|
|
70
|
-
source: "claude-
|
|
72
|
+
source: "claude-cowork",
|
|
71
73
|
provider: "claude_desktop",
|
|
72
74
|
sourceType: "claude-workspace-desktop",
|
|
73
|
-
label: "Claude
|
|
75
|
+
label: "Claude Cowork",
|
|
74
76
|
run: ({ helpers, since, options, env }) =>
|
|
75
77
|
helpers.importClaudeDesktopProvider("claude_desktop", since, { ...options, claudeDesktopKind: "claude-workspace-desktop" }, env)
|
|
76
78
|
},
|
|
@@ -146,9 +148,10 @@ const PROVIDER_ADAPTERS = [
|
|
|
146
148
|
{
|
|
147
149
|
source: "windsurf",
|
|
148
150
|
provider: "windsurf",
|
|
151
|
+
sourceType: "windsurf-cascade-brain",
|
|
149
152
|
label: "Windsurf",
|
|
150
|
-
|
|
151
|
-
|
|
153
|
+
run: ({ helpers, since, options, env }) =>
|
|
154
|
+
helpers.importStructuredProvider("windsurf", helpers.readWindsurfSessions(options, env), since, options, env)
|
|
152
155
|
},
|
|
153
156
|
{
|
|
154
157
|
source: "antigravity",
|
|
@@ -158,6 +161,22 @@ const PROVIDER_ADAPTERS = [
|
|
|
158
161
|
run: ({ helpers, since, options, env }) =>
|
|
159
162
|
helpers.importStructuredProvider("antigravity", helpers.readAntigravitySessions(options, env), since, options, env)
|
|
160
163
|
},
|
|
164
|
+
{
|
|
165
|
+
source: "antigravity-cli",
|
|
166
|
+
provider: "antigravity_cli",
|
|
167
|
+
sourceType: "antigravity-cli-transcript-log",
|
|
168
|
+
label: "Antigravity CLI",
|
|
169
|
+
run: ({ helpers, since, options, env }) =>
|
|
170
|
+
helpers.importStructuredProvider("antigravity_cli", helpers.readAntigravityCliSessions(options, env), since, options, env)
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
source: "antigravity-ide",
|
|
174
|
+
provider: "antigravity_ide",
|
|
175
|
+
sourceType: "antigravity-ide-transcript-log",
|
|
176
|
+
label: "Antigravity IDE",
|
|
177
|
+
run: ({ helpers, since, options, env }) =>
|
|
178
|
+
helpers.importStructuredProvider("antigravity_ide", helpers.readAntigravityIdeSessions(options, env), since, options, env)
|
|
179
|
+
},
|
|
161
180
|
{
|
|
162
181
|
source: "devin-cli",
|
|
163
182
|
provider: "devin",
|
|
@@ -165,11 +184,51 @@ const PROVIDER_ADAPTERS = [
|
|
|
165
184
|
label: "Devin CLI",
|
|
166
185
|
run: ({ helpers, since, options, env }) =>
|
|
167
186
|
helpers.importStructuredProvider("devin", helpers.readDevinSessions(env, options), since, options, env)
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
source: "devin-desktop",
|
|
190
|
+
provider: "devin",
|
|
191
|
+
sourceType: "devin-desktop-acp-events",
|
|
192
|
+
label: "Devin Desktop",
|
|
193
|
+
run: ({ helpers, since, options, env }) =>
|
|
194
|
+
helpers.importStructuredProvider("devin", helpers.readDevinDesktopSessions(env, options), since, options, env)
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
source: "copilot-cli",
|
|
198
|
+
provider: "copilot",
|
|
199
|
+
sourceType: "copilot-cli-history",
|
|
200
|
+
label: "GitHub Copilot CLI",
|
|
201
|
+
run: ({ helpers, since, options, env }) =>
|
|
202
|
+
helpers.importStructuredProvider("copilot", helpers.readCopilotCliSessions(env, options), since, options, env)
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
source: "factory",
|
|
206
|
+
provider: "factory",
|
|
207
|
+
sourceType: "factory-droid-history",
|
|
208
|
+
label: "Factory Droid",
|
|
209
|
+
run: ({ helpers, since, options, env }) =>
|
|
210
|
+
helpers.importStructuredProvider("factory", helpers.readFactorySessions(env, options), since, options, env)
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
source: "grok-build",
|
|
214
|
+
provider: "grok",
|
|
215
|
+
sourceType: "grok-build-history",
|
|
216
|
+
label: "Grok Build",
|
|
217
|
+
run: ({ helpers, since, options, env }) =>
|
|
218
|
+
helpers.importStructuredProvider("grok", helpers.readGrokBuildSessions(env, options), since, options, env)
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
source: "pi",
|
|
222
|
+
provider: "pi",
|
|
223
|
+
sourceType: "pi-cli-history",
|
|
224
|
+
label: "pi",
|
|
225
|
+
run: ({ helpers, since, options, env }) =>
|
|
226
|
+
helpers.importStructuredProvider("pi", helpers.readPiSessions(env, options), since, options, env)
|
|
168
227
|
}
|
|
169
228
|
];
|
|
170
229
|
|
|
171
230
|
function providerAdapterForSource(source) {
|
|
172
|
-
const key =
|
|
231
|
+
const key = canonicalImportSource(source);
|
|
173
232
|
return PROVIDER_ADAPTERS.find((adapter) => adapter.source === key) || null;
|
|
174
233
|
}
|
|
175
234
|
|