agentcache 0.4.2 → 0.5.0-beta.2

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.
Files changed (38) hide show
  1. package/README.md +282 -151
  2. package/dist/{chunk-T4COG3XD.js → chunk-R5I6WWSD.js} +31 -14
  3. package/dist/chunk-RXGW4Q3G.js +109 -0
  4. package/dist/chunk-XRJ6QW6N.js +92 -0
  5. package/dist/chunk-YKG6CDGT.js +1818 -0
  6. package/dist/chunk-YY7QXBG5.js +6610 -0
  7. package/dist/cli.js +2535 -292
  8. package/dist/device-id-RV7RO5RB.js +7 -0
  9. package/dist/ide-detector-ETGAVVXO.js +8 -0
  10. package/dist/mcp.d.ts +734 -2
  11. package/dist/mcp.js +1126 -446
  12. package/dist/{paths-5LZRKNYY.js → paths-NTZ2357O.js} +3 -2
  13. package/dist/postinstall.js +1 -65
  14. package/dist/setup-7JJPW3VG.js +48 -0
  15. package/docs/compatibility.md +152 -0
  16. package/docs/demo-script.md +121 -0
  17. package/docs/launch-copy.md +125 -0
  18. package/docs/privacy.md +173 -0
  19. package/docs/troubleshooting.md +209 -0
  20. package/package.json +32 -14
  21. package/dist/3-canonicalizer-HIN2F7SZ.js +0 -11
  22. package/dist/chunk-5UO7NJPQ.js +0 -71
  23. package/dist/chunk-CUBZRYS5.js +0 -580
  24. package/dist/chunk-GGAATZKM.js +0 -120
  25. package/dist/chunk-JUDLOBOC.js +0 -77
  26. package/dist/chunk-KFQGP6VL.js +0 -33
  27. package/dist/chunk-PSASDZQE.js +0 -490
  28. package/dist/chunk-SLRKWMSE.js +0 -202
  29. package/dist/chunk-T7BJPANN.js +0 -45
  30. package/dist/chunk-WTXSZBQE.js +0 -388
  31. package/dist/compile-all-PTWTZVP5.js +0 -495
  32. package/dist/ide-detector-5TRCR4F5.js +0 -7
  33. package/dist/pre-tool-use-A4AJHZOJ.js +0 -30
  34. package/dist/session-start-DGMGEAJU.js +0 -78
  35. package/dist/setup-CVG35TUZ.js +0 -51
  36. package/dist/sqlite-NM2BVHUY.js +0 -7
  37. package/dist/stop-WGGRX6TQ.js +0 -38
  38. package/dist/transcript-JWSGSDSF.js +0 -24
@@ -1,202 +0,0 @@
1
- // src/utils/ide-registrar.ts
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync, appendFileSync } from "fs";
3
- import { join, dirname } from "path";
4
- import { homedir } from "os";
5
- import { execSync } from "child_process";
6
- function findNodeBinary() {
7
- try {
8
- return execSync("which node", { encoding: "utf-8" }).trim();
9
- } catch {
10
- return "node";
11
- }
12
- }
13
- function findAgentcacheScript() {
14
- try {
15
- const binPath = execSync("which agentcache", { encoding: "utf-8" }).trim();
16
- return binPath;
17
- } catch {
18
- return join(dirname(dirname(__dirname)), "dist", "cli.js");
19
- }
20
- }
21
- function isVscodeExtensionIde(ide) {
22
- return ide.name === "Roo Code" || ide.name === "Continue";
23
- }
24
- var ALL_TOOLS = [
25
- "inject_context",
26
- "compile_submit",
27
- "compile_cluster",
28
- "compile_extract",
29
- "enforce",
30
- "save_observation",
31
- "get_knowledge",
32
- "deprecate_knowledge"
33
- ];
34
- function registerMcpServer(ide) {
35
- if (!ide.detected) return false;
36
- if (ide.mcpConfigFormat === "claude-settings") {
37
- return registerClaudeCode();
38
- }
39
- if (ide.mcpConfigFormat === "mcp-json") {
40
- return registerMcpJson(ide);
41
- }
42
- if (ide.mcpConfigFormat === "continue-dir") {
43
- return registerContinue(ide);
44
- }
45
- if (ide.mcpConfigFormat === "codex-toml") {
46
- return registerCodex(ide);
47
- }
48
- return false;
49
- }
50
- function registerClaudeCode() {
51
- const claudeJsonPath = join(homedir(), ".claude.json");
52
- let config = {};
53
- if (existsSync(claudeJsonPath)) {
54
- try {
55
- config = JSON.parse(readFileSync(claudeJsonPath, "utf-8"));
56
- } catch {
57
- return false;
58
- }
59
- }
60
- if (!config.mcpServers) config.mcpServers = {};
61
- let serverRegistered = false;
62
- if (!config.mcpServers.agentcache) {
63
- config.mcpServers.agentcache = {
64
- type: "stdio",
65
- command: "agentcache",
66
- args: ["serve"],
67
- env: {}
68
- };
69
- writeFileSync(claudeJsonPath, JSON.stringify(config, null, 2));
70
- serverRegistered = true;
71
- }
72
- const settingsPath = join(homedir(), ".claude", "settings.json");
73
- if (existsSync(join(homedir(), ".claude"))) {
74
- let settings = {};
75
- if (existsSync(settingsPath)) {
76
- try {
77
- settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
78
- } catch {
79
- return false;
80
- }
81
- }
82
- if (!settings.permissions) settings.permissions = {};
83
- if (!settings.permissions.allow) settings.permissions.allow = [];
84
- let allowList = settings.permissions.allow;
85
- allowList = allowList.filter((p) => !p.startsWith("mcp__agentcache__loop_") && !p.startsWith("mcp__agentcache__agentcache_"));
86
- settings.permissions.allow = allowList;
87
- const mcpPerms = ALL_TOOLS.map((t) => `mcp__agentcache__${t}`);
88
- for (const perm of mcpPerms) {
89
- if (!allowList.includes(perm)) {
90
- allowList.push(perm);
91
- }
92
- }
93
- writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
94
- }
95
- return serverRegistered;
96
- }
97
- function registerMcpJson(ide) {
98
- let config = {};
99
- if (existsSync(ide.mcpConfigPath)) {
100
- try {
101
- config = JSON.parse(readFileSync(ide.mcpConfigPath, "utf-8"));
102
- } catch {
103
- return false;
104
- }
105
- }
106
- if (!config.mcpServers) config.mcpServers = {};
107
- const existing = config.mcpServers.agentcache;
108
- if (isVscodeExtensionIde(ide)) {
109
- const nodeBin = findNodeBinary();
110
- const script = findAgentcacheScript();
111
- config.mcpServers.agentcache = {
112
- command: nodeBin,
113
- args: [script, "serve"],
114
- alwaysAllow: ALL_TOOLS,
115
- disabled: false
116
- };
117
- } else {
118
- config.mcpServers.agentcache = {
119
- command: "agentcache",
120
- args: ["serve"],
121
- alwaysAllow: ALL_TOOLS
122
- };
123
- }
124
- mkdirSync(dirname(ide.mcpConfigPath), { recursive: true });
125
- writeFileSync(ide.mcpConfigPath, JSON.stringify(config, null, 2));
126
- return true;
127
- }
128
- function registerContinue(ide) {
129
- const configPath = ide.mcpConfigPath;
130
- const nodeBin = findNodeBinary();
131
- const script = findAgentcacheScript();
132
- const config = {
133
- mcpServers: {
134
- agentcache: {
135
- command: nodeBin,
136
- args: [script, "serve"],
137
- alwaysAllow: ALL_TOOLS
138
- }
139
- }
140
- };
141
- mkdirSync(dirname(configPath), { recursive: true });
142
- writeFileSync(configPath, JSON.stringify(config, null, 2));
143
- return true;
144
- }
145
- function registerCodex(ide) {
146
- const configPath = ide.mcpConfigPath;
147
- if (existsSync(configPath)) {
148
- const content = readFileSync(configPath, "utf-8");
149
- if (content.includes("[mcp_servers.agentcache]")) return false;
150
- }
151
- const tomlBlock = `
152
- [mcp_servers.agentcache]
153
- command = "agentcache"
154
- args = ["serve"]
155
- default_tools_approval_mode = "auto"
156
- `;
157
- mkdirSync(dirname(configPath), { recursive: true });
158
- if (existsSync(configPath)) {
159
- appendFileSync(configPath, tomlBlock);
160
- } else {
161
- writeFileSync(configPath, tomlBlock.trimStart());
162
- }
163
- return true;
164
- }
165
- function registerClaudeHooks() {
166
- const settingsPath = join(homedir(), ".claude", "settings.json");
167
- if (!existsSync(join(homedir(), ".claude"))) return false;
168
- let settings = {};
169
- if (existsSync(settingsPath)) {
170
- try {
171
- settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
172
- } catch {
173
- return false;
174
- }
175
- }
176
- if (!settings.hooks) settings.hooks = {};
177
- const hooks = settings.hooks;
178
- const agentcacheHooks = {
179
- Stop: [{ matcher: "", hooks: [{ type: "command", command: "agentcache compile-session" }] }],
180
- SessionStart: [{ matcher: "", hooks: [{ type: "command", command: "agentcache discover" }] }],
181
- PreToolUse: [{ matcher: "", hooks: [{ type: "command", command: "agentcache enforce" }] }]
182
- };
183
- let registered = false;
184
- for (const [event, hookConfig] of Object.entries(agentcacheHooks)) {
185
- if (!hooks[event]) hooks[event] = [];
186
- const existing = hooks[event];
187
- const hasAgentcache = existing.some((h) => h.hooks?.some((hh) => hh.command?.includes("agentcache")));
188
- if (!hasAgentcache) {
189
- hooks[event].push(...hookConfig);
190
- registered = true;
191
- }
192
- }
193
- if (registered) {
194
- writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
195
- }
196
- return registered;
197
- }
198
-
199
- export {
200
- registerMcpServer,
201
- registerClaudeHooks
202
- };
@@ -1,45 +0,0 @@
1
- // src/policy/engine.ts
2
- var HARDCODED_BLOCKS = [
3
- { pattern: /git\s+push\s+--force\s+(origin\s+)?(main|master)/i, reason: "Force-push to main/master is blocked by AgentCache policy" },
4
- { pattern: /rm\s+-rf\s+[\/~]/i, reason: "Destructive rm -rf on root or home is blocked by AgentCache policy" },
5
- { pattern: />\s*(.*\.(env|pem|key))/i, reason: "Writing to sensitive files (.env, .pem, .key) is blocked by AgentCache policy" }
6
- ];
7
- function evaluatePolicy(input, enforcedRules) {
8
- const command = extractCommand(input.tool_name, input.tool_input);
9
- if (!command) return {};
10
- for (const block of HARDCODED_BLOCKS) {
11
- if (block.pattern.test(command)) {
12
- return { decision: "block", reason: block.reason };
13
- }
14
- }
15
- for (const item of enforcedRules) {
16
- if (matchesRule(item, input.tool_name, command)) {
17
- return { decision: "block", reason: `Blocked by enforced rule: ${item.content}` };
18
- }
19
- }
20
- return {};
21
- }
22
- function extractCommand(toolName, toolInput) {
23
- if (toolName === "Bash" && typeof toolInput.command === "string") {
24
- return toolInput.command;
25
- }
26
- if (toolName === "Write" && typeof toolInput.file_path === "string") {
27
- return `> ${toolInput.file_path}`;
28
- }
29
- if (toolName === "Edit" && typeof toolInput.file_path === "string") {
30
- return `edit ${toolInput.file_path}`;
31
- }
32
- return null;
33
- }
34
- function matchesRule(item, _toolName, command) {
35
- const content = item.content.toLowerCase();
36
- const cmd = command.toLowerCase();
37
- const keywords = content.replace(/never|always|don't|do not|avoid|must not/gi, "").split(/\s+/).filter((w) => w.length > 3);
38
- if (keywords.length === 0) return false;
39
- const matchCount = keywords.filter((k) => cmd.includes(k)).length;
40
- return matchCount >= Math.ceil(keywords.length * 0.5);
41
- }
42
-
43
- export {
44
- evaluatePolicy
45
- };
@@ -1,388 +0,0 @@
1
- import {
2
- getClaudeTranscriptsDir,
3
- getContinueSessionsDir
4
- } from "./chunk-T4COG3XD.js";
5
- import {
6
- __export
7
- } from "./chunk-KFQGP6VL.js";
8
-
9
- // src/utils/transcript.ts
10
- import { readdirSync, statSync, existsSync } from "fs";
11
- import { join } from "path";
12
- import { homedir } from "os";
13
-
14
- // src/utils/transcript-parsers/claude-jsonl.ts
15
- var claude_jsonl_exports = {};
16
- __export(claude_jsonl_exports, {
17
- canParse: () => canParse,
18
- parse: () => parse
19
- });
20
- import { readFileSync } from "fs";
21
- function canParse(path) {
22
- return path.endsWith(".jsonl");
23
- }
24
- function parse(path) {
25
- const content = readFileSync(path, "utf-8");
26
- const events = [];
27
- for (const line of content.split("\n")) {
28
- if (!line.trim()) continue;
29
- try {
30
- const obj = JSON.parse(line);
31
- if (obj.type === "user" && obj.message?.content) {
32
- events.push({
33
- type: "message",
34
- role: "user",
35
- content: typeof obj.message.content === "string" ? obj.message.content : JSON.stringify(obj.message.content)
36
- });
37
- } else if (obj.type === "assistant" && obj.message?.content) {
38
- const blocks = Array.isArray(obj.message.content) ? obj.message.content : [{ type: "text", text: obj.message.content }];
39
- for (const block of blocks) {
40
- if (block.type === "text" && block.text) {
41
- events.push({ type: "message", role: "assistant", content: block.text });
42
- } else if (block.type === "tool_use") {
43
- events.push({
44
- type: "tool_use",
45
- tool_name: block.name,
46
- tool_input: block.input
47
- });
48
- }
49
- }
50
- }
51
- } catch {
52
- continue;
53
- }
54
- }
55
- return events;
56
- }
57
-
58
- // src/utils/transcript-parsers/continue-json.ts
59
- var continue_json_exports = {};
60
- __export(continue_json_exports, {
61
- canParse: () => canParse2,
62
- parse: () => parse2
63
- });
64
- import { readFileSync as readFileSync2 } from "fs";
65
- function canParse2(path) {
66
- if (!path.endsWith(".json")) return false;
67
- try {
68
- const content = readFileSync2(path, "utf-8");
69
- const parsed = JSON.parse(content);
70
- return parsed.history && Array.isArray(parsed.history);
71
- } catch {
72
- return false;
73
- }
74
- }
75
- function parse2(path) {
76
- const content = readFileSync2(path, "utf-8");
77
- const session = JSON.parse(content);
78
- const events = [];
79
- if (!session.history || !Array.isArray(session.history)) return events;
80
- for (const entry of session.history) {
81
- const msg = entry.message;
82
- if (!msg) continue;
83
- const role = msg.role === "user" ? "user" : msg.role === "assistant" ? "assistant" : null;
84
- if (!role) continue;
85
- let text = "";
86
- if (typeof msg.content === "string") {
87
- text = msg.content;
88
- } else if (Array.isArray(msg.content)) {
89
- text = msg.content.filter((b) => b.type === "text" && b.text).map((b) => b.text).join("\n");
90
- }
91
- if (text) {
92
- events.push({ type: "message", role, content: text });
93
- }
94
- }
95
- return events;
96
- }
97
-
98
- // src/utils/transcript-parsers/codex-jsonl.ts
99
- var codex_jsonl_exports = {};
100
- __export(codex_jsonl_exports, {
101
- canParse: () => canParse3,
102
- parse: () => parse3
103
- });
104
- import { readFileSync as readFileSync3 } from "fs";
105
- function canParse3(path) {
106
- if (!path.endsWith(".jsonl")) return false;
107
- return path.includes(".codex/sessions/");
108
- }
109
- function parse3(path) {
110
- const content = readFileSync3(path, "utf-8");
111
- const events = [];
112
- for (const line of content.split("\n")) {
113
- if (!line.trim()) continue;
114
- try {
115
- const obj = JSON.parse(line);
116
- if (obj.type === "response_item" && obj.payload) {
117
- const p = obj.payload;
118
- if (p.role === "developer" && Array.isArray(p.content)) {
119
- const text = p.content.filter((c) => c.type === "input_text").map((c) => c.text).join("\n");
120
- if (text) events.push({ type: "message", role: "user", content: text });
121
- } else if (p.role === "assistant" && Array.isArray(p.content)) {
122
- for (const block of p.content) {
123
- if (block.type === "output_text" && block.text) {
124
- events.push({ type: "message", role: "assistant", content: block.text });
125
- } else if (block.type === "function_call") {
126
- events.push({
127
- type: "tool_use",
128
- tool_name: block.name,
129
- tool_input: { arguments: block.arguments }
130
- });
131
- }
132
- }
133
- }
134
- }
135
- } catch {
136
- continue;
137
- }
138
- }
139
- return events;
140
- }
141
-
142
- // src/utils/transcript-parsers/cursor-jsonl.ts
143
- var cursor_jsonl_exports = {};
144
- __export(cursor_jsonl_exports, {
145
- canParse: () => canParse4,
146
- parse: () => parse4
147
- });
148
- import { readFileSync as readFileSync4 } from "fs";
149
- function canParse4(path) {
150
- if (!path.endsWith(".jsonl")) return false;
151
- return path.includes(".cursor/projects/") && path.includes("/agent-transcripts/");
152
- }
153
- function parse4(path) {
154
- const content = readFileSync4(path, "utf-8");
155
- const events = [];
156
- for (const line of content.split("\n")) {
157
- if (!line.trim()) continue;
158
- try {
159
- const obj = JSON.parse(line);
160
- if (obj.role === "user" && obj.message?.content) {
161
- const blocks = Array.isArray(obj.message.content) ? obj.message.content : [{ type: "text", text: obj.message.content }];
162
- const text = blocks.filter((c) => c.type === "text").map((c) => c.text).join("\n");
163
- if (text) events.push({ type: "message", role: "user", content: text });
164
- } else if (obj.role === "assistant" && obj.message?.content) {
165
- const blocks = Array.isArray(obj.message.content) ? obj.message.content : [{ type: "text", text: obj.message.content }];
166
- for (const block of blocks) {
167
- if (block.type === "text" && block.text) {
168
- events.push({ type: "message", role: "assistant", content: block.text });
169
- } else if (block.type === "tool_use") {
170
- events.push({
171
- type: "tool_use",
172
- tool_name: block.name,
173
- tool_input: block.input
174
- });
175
- }
176
- }
177
- }
178
- } catch {
179
- continue;
180
- }
181
- }
182
- return events;
183
- }
184
-
185
- // src/utils/transcript-parsers/roo-code-json.ts
186
- var roo_code_json_exports = {};
187
- __export(roo_code_json_exports, {
188
- canParse: () => canParse5,
189
- parse: () => parse5
190
- });
191
- import { readFileSync as readFileSync5 } from "fs";
192
- function canParse5(path) {
193
- return path.includes("roo-cline/tasks/") && path.endsWith("api_conversation_history.json");
194
- }
195
- function parse5(path) {
196
- const content = readFileSync5(path, "utf-8");
197
- const events = [];
198
- try {
199
- const messages = JSON.parse(content);
200
- if (!Array.isArray(messages)) return [];
201
- for (const msg of messages) {
202
- if (msg.role === "user" && Array.isArray(msg.content)) {
203
- const text = msg.content.filter((c) => c.type === "text").map((c) => c.text).join("\n");
204
- if (text) events.push({ type: "message", role: "user", content: text });
205
- } else if (msg.role === "assistant" && typeof msg.content === "string") {
206
- events.push({ type: "message", role: "assistant", content: msg.content });
207
- } else if (msg.role === "assistant" && Array.isArray(msg.content)) {
208
- for (const block of msg.content) {
209
- if (block.type === "text" && block.text) {
210
- events.push({ type: "message", role: "assistant", content: block.text });
211
- } else if (block.type === "tool_use") {
212
- events.push({
213
- type: "tool_use",
214
- tool_name: block.name,
215
- tool_input: block.input
216
- });
217
- }
218
- }
219
- }
220
- }
221
- } catch {
222
- return [];
223
- }
224
- return events;
225
- }
226
-
227
- // src/utils/transcript-parsers/index.ts
228
- var parsers = [codex_jsonl_exports, cursor_jsonl_exports, roo_code_json_exports, claude_jsonl_exports, continue_json_exports];
229
- function parseTranscriptAuto(path) {
230
- for (const parser of parsers) {
231
- if (parser.canParse(path)) return parser.parse(path);
232
- }
233
- return [];
234
- }
235
-
236
- // src/utils/transcript.ts
237
- function parseTranscript(path) {
238
- return parseTranscriptAuto(path);
239
- }
240
- function findLatestTranscript() {
241
- const baseDir = getClaudeTranscriptsDir();
242
- if (!existsSync(baseDir)) return null;
243
- let latest = null;
244
- try {
245
- const dirs = readdirSync(baseDir).map((d) => join(baseDir, d)).filter((d) => statSync(d).isDirectory());
246
- for (const dir of dirs) {
247
- try {
248
- const files = readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
249
- for (const file of files) {
250
- const fullPath = join(dir, file);
251
- const mtime = statSync(fullPath).mtimeMs;
252
- if (!latest || mtime > latest.mtime) {
253
- latest = { path: fullPath, mtime };
254
- }
255
- }
256
- } catch {
257
- continue;
258
- }
259
- }
260
- } catch {
261
- return null;
262
- }
263
- return latest?.path ?? null;
264
- }
265
- function findAllClaudeTranscripts() {
266
- const baseDir = getClaudeTranscriptsDir();
267
- if (!existsSync(baseDir)) return [];
268
- const transcripts = [];
269
- try {
270
- const dirs = readdirSync(baseDir).map((d) => join(baseDir, d)).filter((d) => statSync(d).isDirectory());
271
- for (const dir of dirs) {
272
- try {
273
- const files = readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
274
- for (const file of files) {
275
- const fullPath = join(dir, file);
276
- if (statSync(fullPath).size > 100) {
277
- transcripts.push(fullPath);
278
- }
279
- }
280
- } catch {
281
- continue;
282
- }
283
- }
284
- } catch {
285
- }
286
- return transcripts;
287
- }
288
- function findAllContinueTranscripts() {
289
- const dir = getContinueSessionsDir();
290
- if (!existsSync(dir)) return [];
291
- try {
292
- return readdirSync(dir).filter((f) => f.endsWith(".json") && f !== "sessions.json").map((f) => join(dir, f)).filter((f) => statSync(f).size > 100);
293
- } catch {
294
- return [];
295
- }
296
- }
297
- function findAllCodexTranscripts() {
298
- const baseDir = join(homedir(), ".codex", "sessions");
299
- if (!existsSync(baseDir)) return [];
300
- const transcripts = [];
301
- function walkDir(dir) {
302
- try {
303
- for (const entry of readdirSync(dir)) {
304
- const full = join(dir, entry);
305
- const stat = statSync(full);
306
- if (stat.isDirectory()) {
307
- walkDir(full);
308
- } else if (entry.endsWith(".jsonl") && stat.size > 100) {
309
- transcripts.push(full);
310
- }
311
- }
312
- } catch {
313
- }
314
- }
315
- walkDir(baseDir);
316
- return transcripts;
317
- }
318
- function findAllCursorTranscripts() {
319
- const baseDir = join(homedir(), ".cursor", "projects");
320
- if (!existsSync(baseDir)) return [];
321
- const transcripts = [];
322
- try {
323
- for (const projectDir of readdirSync(baseDir)) {
324
- const agentDir = join(baseDir, projectDir, "agent-transcripts");
325
- if (!existsSync(agentDir)) continue;
326
- try {
327
- for (const sessionDir of readdirSync(agentDir)) {
328
- const sessionPath = join(agentDir, sessionDir);
329
- if (!statSync(sessionPath).isDirectory()) continue;
330
- try {
331
- for (const file of readdirSync(sessionPath)) {
332
- if (file.endsWith(".jsonl")) {
333
- const full = join(sessionPath, file);
334
- if (statSync(full).size > 100) {
335
- transcripts.push(full);
336
- }
337
- }
338
- }
339
- } catch {
340
- }
341
- }
342
- } catch {
343
- }
344
- }
345
- } catch {
346
- }
347
- return transcripts;
348
- }
349
- function findAllRooCodeTranscripts() {
350
- const possibleDirs = [
351
- join(homedir(), "Library", "Application Support", "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "tasks"),
352
- join(homedir(), ".config", "Code", "User", "globalStorage", "rooveterinaryinc.roo-cline", "tasks")
353
- ];
354
- const transcripts = [];
355
- for (const baseDir of possibleDirs) {
356
- if (!existsSync(baseDir)) continue;
357
- try {
358
- for (const taskDir of readdirSync(baseDir)) {
359
- const historyPath = join(baseDir, taskDir, "api_conversation_history.json");
360
- if (existsSync(historyPath) && statSync(historyPath).size > 100) {
361
- transcripts.push(historyPath);
362
- }
363
- }
364
- } catch {
365
- }
366
- }
367
- return transcripts;
368
- }
369
- function findAllGooseSessionIds() {
370
- const dbPath = join(homedir(), ".local", "share", "goose", "sessions", "sessions.db");
371
- if (!existsSync(dbPath)) return [];
372
- return [dbPath];
373
- }
374
- function getGooseDbPath() {
375
- return join(homedir(), ".local", "share", "goose", "sessions", "sessions.db");
376
- }
377
-
378
- export {
379
- parseTranscript,
380
- findLatestTranscript,
381
- findAllClaudeTranscripts,
382
- findAllContinueTranscripts,
383
- findAllCodexTranscripts,
384
- findAllCursorTranscripts,
385
- findAllRooCodeTranscripts,
386
- findAllGooseSessionIds,
387
- getGooseDbPath
388
- };