aspectcode 0.3.4 → 0.4.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.
Files changed (109) hide show
  1. package/dist/cli.d.ts +1 -2
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +1 -2
  4. package/dist/cli.js.map +1 -1
  5. package/dist/config.d.ts +0 -2
  6. package/dist/config.d.ts.map +1 -1
  7. package/dist/config.js.map +1 -1
  8. package/dist/diffSummary.d.ts +17 -0
  9. package/dist/diffSummary.d.ts.map +1 -0
  10. package/dist/diffSummary.js +49 -0
  11. package/dist/diffSummary.js.map +1 -0
  12. package/dist/main.d.ts.map +1 -1
  13. package/dist/main.js +13 -16
  14. package/dist/main.js.map +1 -1
  15. package/dist/optimize.d.ts +6 -3
  16. package/dist/optimize.d.ts.map +1 -1
  17. package/dist/optimize.js +85 -102
  18. package/dist/optimize.js.map +1 -1
  19. package/dist/pipeline.d.ts +5 -4
  20. package/dist/pipeline.d.ts.map +1 -1
  21. package/dist/pipeline.js +45 -10
  22. package/dist/pipeline.js.map +1 -1
  23. package/dist/summary.d.ts +15 -0
  24. package/dist/summary.d.ts.map +1 -0
  25. package/dist/summary.js +51 -0
  26. package/dist/summary.js.map +1 -0
  27. package/dist/ui/Dashboard.d.ts +15 -7
  28. package/dist/ui/Dashboard.d.ts.map +1 -1
  29. package/dist/ui/Dashboard.js +55 -24
  30. package/dist/ui/Dashboard.js.map +1 -1
  31. package/dist/ui/store.d.ts +33 -0
  32. package/dist/ui/store.d.ts.map +1 -1
  33. package/dist/ui/store.js +24 -1
  34. package/dist/ui/store.js.map +1 -1
  35. package/dist/ui/theme.d.ts +3 -3
  36. package/dist/ui/theme.js +3 -3
  37. package/dist/ui/theme.js.map +1 -1
  38. package/node_modules/@aspectcode/evaluator/dist/diagnosis.d.ts +33 -0
  39. package/node_modules/@aspectcode/evaluator/dist/diagnosis.d.ts.map +1 -0
  40. package/node_modules/@aspectcode/evaluator/dist/diagnosis.js +172 -0
  41. package/node_modules/@aspectcode/evaluator/dist/diagnosis.js.map +1 -0
  42. package/node_modules/@aspectcode/evaluator/dist/harvest/aider.d.ts +23 -0
  43. package/node_modules/@aspectcode/evaluator/dist/harvest/aider.d.ts.map +1 -0
  44. package/node_modules/@aspectcode/evaluator/dist/harvest/aider.js +125 -0
  45. package/node_modules/@aspectcode/evaluator/dist/harvest/aider.js.map +1 -0
  46. package/node_modules/@aspectcode/evaluator/dist/harvest/claudeCode.d.ts +17 -0
  47. package/node_modules/@aspectcode/evaluator/dist/harvest/claudeCode.d.ts.map +1 -0
  48. package/node_modules/@aspectcode/evaluator/dist/harvest/claudeCode.js +223 -0
  49. package/node_modules/@aspectcode/evaluator/dist/harvest/claudeCode.js.map +1 -0
  50. package/node_modules/@aspectcode/evaluator/dist/harvest/cline.d.ts +17 -0
  51. package/node_modules/@aspectcode/evaluator/dist/harvest/cline.d.ts.map +1 -0
  52. package/node_modules/@aspectcode/evaluator/dist/harvest/cline.js +179 -0
  53. package/node_modules/@aspectcode/evaluator/dist/harvest/cline.js.map +1 -0
  54. package/node_modules/@aspectcode/evaluator/dist/harvest/common.d.ts +39 -0
  55. package/node_modules/@aspectcode/evaluator/dist/harvest/common.d.ts.map +1 -0
  56. package/node_modules/@aspectcode/evaluator/dist/harvest/common.js +170 -0
  57. package/node_modules/@aspectcode/evaluator/dist/harvest/common.js.map +1 -0
  58. package/node_modules/@aspectcode/evaluator/dist/harvest/export.d.ts +23 -0
  59. package/node_modules/@aspectcode/evaluator/dist/harvest/export.d.ts.map +1 -0
  60. package/node_modules/@aspectcode/evaluator/dist/harvest/export.js +98 -0
  61. package/node_modules/@aspectcode/evaluator/dist/harvest/export.js.map +1 -0
  62. package/node_modules/@aspectcode/evaluator/dist/harvest/index.d.ts +29 -0
  63. package/node_modules/@aspectcode/evaluator/dist/harvest/index.d.ts.map +1 -0
  64. package/node_modules/@aspectcode/evaluator/dist/harvest/index.js +94 -0
  65. package/node_modules/@aspectcode/evaluator/dist/harvest/index.js.map +1 -0
  66. package/node_modules/@aspectcode/evaluator/dist/harvest/vscodeDb.d.ts +37 -0
  67. package/node_modules/@aspectcode/evaluator/dist/harvest/vscodeDb.d.ts.map +1 -0
  68. package/node_modules/@aspectcode/evaluator/dist/harvest/vscodeDb.js +473 -0
  69. package/node_modules/@aspectcode/evaluator/dist/harvest/vscodeDb.js.map +1 -0
  70. package/node_modules/@aspectcode/evaluator/dist/index.d.ts +49 -0
  71. package/node_modules/@aspectcode/evaluator/dist/index.d.ts.map +1 -0
  72. package/node_modules/@aspectcode/evaluator/dist/index.js +75 -0
  73. package/node_modules/@aspectcode/evaluator/dist/index.js.map +1 -0
  74. package/node_modules/@aspectcode/evaluator/dist/probes.d.ts +38 -0
  75. package/node_modules/@aspectcode/evaluator/dist/probes.d.ts.map +1 -0
  76. package/node_modules/@aspectcode/evaluator/dist/probes.js +229 -0
  77. package/node_modules/@aspectcode/evaluator/dist/probes.js.map +1 -0
  78. package/node_modules/@aspectcode/evaluator/dist/runner.d.ts +44 -0
  79. package/node_modules/@aspectcode/evaluator/dist/runner.d.ts.map +1 -0
  80. package/node_modules/@aspectcode/evaluator/dist/runner.js +186 -0
  81. package/node_modules/@aspectcode/evaluator/dist/runner.js.map +1 -0
  82. package/node_modules/@aspectcode/evaluator/dist/types.d.ts +176 -0
  83. package/node_modules/@aspectcode/evaluator/dist/types.d.ts.map +1 -0
  84. package/node_modules/@aspectcode/evaluator/dist/types.js +9 -0
  85. package/node_modules/@aspectcode/evaluator/dist/types.js.map +1 -0
  86. package/node_modules/@aspectcode/evaluator/package.json +41 -0
  87. package/node_modules/@aspectcode/optimizer/dist/agent.d.ts +12 -13
  88. package/node_modules/@aspectcode/optimizer/dist/agent.d.ts.map +1 -1
  89. package/node_modules/@aspectcode/optimizer/dist/agent.js +52 -110
  90. package/node_modules/@aspectcode/optimizer/dist/agent.js.map +1 -1
  91. package/node_modules/@aspectcode/optimizer/dist/index.d.ts +3 -3
  92. package/node_modules/@aspectcode/optimizer/dist/index.d.ts.map +1 -1
  93. package/node_modules/@aspectcode/optimizer/dist/index.js +3 -5
  94. package/node_modules/@aspectcode/optimizer/dist/index.js.map +1 -1
  95. package/node_modules/@aspectcode/optimizer/dist/prompts.d.ts +8 -21
  96. package/node_modules/@aspectcode/optimizer/dist/prompts.d.ts.map +1 -1
  97. package/node_modules/@aspectcode/optimizer/dist/prompts.js +36 -94
  98. package/node_modules/@aspectcode/optimizer/dist/prompts.js.map +1 -1
  99. package/node_modules/@aspectcode/optimizer/dist/providers/anthropic.d.ts.map +1 -1
  100. package/node_modules/@aspectcode/optimizer/dist/providers/anthropic.js +10 -1
  101. package/node_modules/@aspectcode/optimizer/dist/providers/anthropic.js.map +1 -1
  102. package/node_modules/@aspectcode/optimizer/dist/providers/openai.d.ts.map +1 -1
  103. package/node_modules/@aspectcode/optimizer/dist/providers/openai.js +10 -1
  104. package/node_modules/@aspectcode/optimizer/dist/providers/openai.js.map +1 -1
  105. package/node_modules/@aspectcode/optimizer/dist/types.d.ts +33 -24
  106. package/node_modules/@aspectcode/optimizer/dist/types.d.ts.map +1 -1
  107. package/node_modules/@aspectcode/optimizer/dist/types.js.map +1 -1
  108. package/node_modules/@aspectcode/optimizer/package.json +2 -2
  109. package/package.json +4 -3
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ /**
3
+ * Claude Code prompt harvester.
4
+ *
5
+ * Parses conversation JSONL files from `~/.claude/projects/<hash>/`.
6
+ * Each line is a JSON object with `type: "human" | "assistant" | "summary"`.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.harvestClaudeCode = harvestClaudeCode;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const os = __importStar(require("os"));
46
+ const crypto = __importStar(require("crypto"));
47
+ const common_1 = require("./common");
48
+ /**
49
+ * Harvest prompts from Claude Code's conversation history.
50
+ */
51
+ async function harvestClaudeCode(root, options) {
52
+ const log = options?.log ?? common_1.noopLogger;
53
+ const max = options?.max ?? common_1.DEFAULT_MAX_PER_SOURCE;
54
+ const projectDir = findProjectDir(root);
55
+ if (!projectDir) {
56
+ log.debug('claude-code: no project directory found');
57
+ return [];
58
+ }
59
+ const prompts = [];
60
+ // Find all JSONL conversation files
61
+ let files;
62
+ try {
63
+ files = fs.readdirSync(projectDir).filter((f) => f.endsWith('.jsonl'));
64
+ }
65
+ catch {
66
+ log.debug(`claude-code: cannot read ${projectDir}`);
67
+ return [];
68
+ }
69
+ for (const file of files) {
70
+ const filePath = path.join(projectDir, file);
71
+ try {
72
+ const parsed = parseClaudeCodeJsonl(filePath, root);
73
+ prompts.push(...parsed);
74
+ }
75
+ catch (err) {
76
+ log.debug(`claude-code: failed to parse ${file}: ${err}`);
77
+ }
78
+ }
79
+ log.debug(`claude-code: parsed ${prompts.length} conversation turns from ${files.length} files`);
80
+ return (0, common_1.filterRecent)(prompts, options?.since, max);
81
+ }
82
+ /**
83
+ * Find the Claude Code project directory for the given workspace root.
84
+ * Tries multiple hash strategies since the hash algorithm isn't documented.
85
+ */
86
+ function findProjectDir(root) {
87
+ const home = os.homedir();
88
+ const claudeBase = path.join(home, '.claude', 'projects');
89
+ if (!fs.existsSync(claudeBase))
90
+ return undefined;
91
+ // Strategy 1: Try common hash formats
92
+ const normalised = root.replace(/\\/g, '/');
93
+ const candidates = [
94
+ // MD5 of the path
95
+ crypto.createHash('md5').update(normalised).digest('hex'),
96
+ // SHA-256 truncated
97
+ crypto.createHash('sha256').update(normalised).digest('hex').slice(0, 32),
98
+ // URL-safe base64 of the path
99
+ Buffer.from(normalised).toString('base64url'),
100
+ // The path with slashes replaced by hyphens
101
+ normalised.replace(/\//g, '-').replace(/^-/, ''),
102
+ ];
103
+ for (const candidate of candidates) {
104
+ const dir = path.join(claudeBase, candidate);
105
+ if (fs.existsSync(dir))
106
+ return dir;
107
+ }
108
+ // Strategy 2: Scan all project directories for one that references this workspace
109
+ // (fallback — slower but more reliable)
110
+ try {
111
+ const dirs = fs.readdirSync(claudeBase);
112
+ for (const dir of dirs) {
113
+ const fullDir = path.join(claudeBase, dir);
114
+ const stat = fs.statSync(fullDir);
115
+ if (!stat.isDirectory())
116
+ continue;
117
+ // Check if any JSONL file in this directory mentions files from our workspace
118
+ const jsonlFiles = fs.readdirSync(fullDir).filter((f) => f.endsWith('.jsonl'));
119
+ if (jsonlFiles.length === 0)
120
+ continue;
121
+ // Quick heuristic: read first 2KB of the first file and check for workspace path
122
+ const sample = readHead(path.join(fullDir, jsonlFiles[0]), 2048);
123
+ if (sample.includes(normalised) || sample.includes(root.replace(/\\/g, '\\\\'))) {
124
+ return fullDir;
125
+ }
126
+ }
127
+ }
128
+ catch {
129
+ // Scanning failed, give up
130
+ }
131
+ return undefined;
132
+ }
133
+ function readHead(filePath, bytes) {
134
+ const fd = fs.openSync(filePath, 'r');
135
+ try {
136
+ const buf = Buffer.alloc(bytes);
137
+ const bytesRead = fs.readSync(fd, buf, 0, bytes, 0);
138
+ return buf.slice(0, bytesRead).toString('utf-8');
139
+ }
140
+ finally {
141
+ fs.closeSync(fd);
142
+ }
143
+ }
144
+ /**
145
+ * Parse a single Claude Code JSONL conversation file.
146
+ */
147
+ function parseClaudeCodeJsonl(filePath, root) {
148
+ const content = fs.readFileSync(filePath, 'utf-8');
149
+ const lines = content.split('\n').filter((l) => l.trim());
150
+ const prompts = [];
151
+ // Build a paired list of human → assistant turns
152
+ let pendingHuman;
153
+ for (const line of lines) {
154
+ let entry;
155
+ try {
156
+ entry = JSON.parse(line);
157
+ }
158
+ catch {
159
+ continue;
160
+ }
161
+ if (entry.type === 'human') {
162
+ const text = extractTextFromContent(entry.message?.content);
163
+ if (text) {
164
+ pendingHuman = {
165
+ text,
166
+ timestamp: entry.timestamp,
167
+ };
168
+ }
169
+ }
170
+ else if (entry.type === 'assistant' && pendingHuman) {
171
+ const text = extractTextFromContent(entry.message?.content);
172
+ const fileRefs = extractToolFileRefs(entry.message?.content);
173
+ if (text) {
174
+ const allText = pendingHuman.text + '\n' + text;
175
+ const allFiles = [
176
+ ...(0, common_1.extractFilePaths)(allText, root),
177
+ ...fileRefs,
178
+ ];
179
+ prompts.push({
180
+ source: 'claude-code',
181
+ timestamp: entry.timestamp || pendingHuman.timestamp,
182
+ userPrompt: pendingHuman.text,
183
+ assistantResponse: text,
184
+ filesReferenced: [...new Set(allFiles)],
185
+ });
186
+ }
187
+ pendingHuman = undefined;
188
+ }
189
+ }
190
+ return prompts;
191
+ }
192
+ /**
193
+ * Extract plain text from a Claude-style content array.
194
+ */
195
+ function extractTextFromContent(content) {
196
+ if (typeof content === 'string')
197
+ return content;
198
+ if (!Array.isArray(content))
199
+ return '';
200
+ return content
201
+ .filter((block) => block.type === 'text' && typeof block.text === 'string')
202
+ .map((block) => block.text)
203
+ .join('\n');
204
+ }
205
+ /**
206
+ * Extract file paths from tool_use blocks in Claude-style content.
207
+ */
208
+ function extractToolFileRefs(content) {
209
+ if (!Array.isArray(content))
210
+ return [];
211
+ const files = [];
212
+ for (const block of content) {
213
+ if (block.type === 'tool_use' && block.input) {
214
+ // Common tool patterns: Read (file_path), write_to_file (path), etc.
215
+ const filePath = block.input.file_path || block.input.path || block.input.file;
216
+ if (typeof filePath === 'string') {
217
+ files.push(filePath.replace(/\\/g, '/'));
218
+ }
219
+ }
220
+ }
221
+ return files;
222
+ }
223
+ //# sourceMappingURL=claudeCode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claudeCode.js","sourceRoot":"","sources":["../../src/harvest/claudeCode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Cline prompt harvester.
3
+ *
4
+ * Parses `api_conversation_history.json` files from Cline's globalStorage.
5
+ * Format mirrors the Anthropic Messages API: array of {role, content} objects.
6
+ */
7
+ import type { HarvestedPrompt } from '../types';
8
+ import type { OptLogger } from '../types';
9
+ /**
10
+ * Harvest prompts from Cline's conversation history.
11
+ */
12
+ export declare function harvestCline(root: string, options?: {
13
+ max?: number;
14
+ since?: Date;
15
+ log?: OptLogger;
16
+ }): Promise<HarvestedPrompt[]>;
17
+ //# sourceMappingURL=cline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cline.d.ts","sourceRoot":"","sources":["../../src/harvest/cline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAQhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAI1C;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,SAAS,CAAA;CAAE,GACxD,OAAO,CAAC,eAAe,EAAE,CAAC,CAiD5B"}
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ /**
3
+ * Cline prompt harvester.
4
+ *
5
+ * Parses `api_conversation_history.json` files from Cline's globalStorage.
6
+ * Format mirrors the Anthropic Messages API: array of {role, content} objects.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.harvestCline = harvestCline;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const common_1 = require("./common");
46
+ const CLINE_EXTENSION_ID = 'saoudrizwan.claude-dev';
47
+ /**
48
+ * Harvest prompts from Cline's conversation history.
49
+ */
50
+ async function harvestCline(root, options) {
51
+ const log = options?.log ?? common_1.noopLogger;
52
+ const max = options?.max ?? common_1.DEFAULT_MAX_PER_SOURCE;
53
+ const storageDir = (0, common_1.vscodeGlobalStoragePath)(CLINE_EXTENSION_ID);
54
+ const tasksDir = path.join(storageDir, 'tasks');
55
+ if (!fs.existsSync(tasksDir)) {
56
+ log.debug(`cline: no tasks directory at ${tasksDir}`);
57
+ return [];
58
+ }
59
+ const prompts = [];
60
+ let taskDirs;
61
+ try {
62
+ taskDirs = fs.readdirSync(tasksDir).filter((d) => {
63
+ return fs.statSync(path.join(tasksDir, d)).isDirectory();
64
+ });
65
+ }
66
+ catch {
67
+ log.debug(`cline: cannot read ${tasksDir}`);
68
+ return [];
69
+ }
70
+ // Sort by task ID (timestamp) descending to get most recent first
71
+ taskDirs.sort((a, b) => {
72
+ const na = parseInt(a, 10);
73
+ const nb = parseInt(b, 10);
74
+ if (isNaN(na) || isNaN(nb))
75
+ return b.localeCompare(a);
76
+ return nb - na;
77
+ });
78
+ for (const taskDir of taskDirs) {
79
+ const historyFile = path.join(tasksDir, taskDir, 'api_conversation_history.json');
80
+ if (!fs.existsSync(historyFile))
81
+ continue;
82
+ try {
83
+ const parsed = parseClineHistory(historyFile, taskDir, root);
84
+ prompts.push(...parsed);
85
+ }
86
+ catch (err) {
87
+ log.debug(`cline: failed to parse task ${taskDir}: ${err}`);
88
+ }
89
+ // Early exit if we already have enough
90
+ if (prompts.length >= max * 2)
91
+ break;
92
+ }
93
+ log.debug(`cline: parsed ${prompts.length} conversation turns from ${taskDirs.length} tasks`);
94
+ return (0, common_1.filterRecent)(prompts, options?.since, max);
95
+ }
96
+ /**
97
+ * Parse a single Cline api_conversation_history.json file.
98
+ */
99
+ function parseClineHistory(filePath, taskId, root) {
100
+ const content = fs.readFileSync(filePath, 'utf-8');
101
+ const messages = JSON.parse(content);
102
+ if (!Array.isArray(messages))
103
+ return [];
104
+ const prompts = [];
105
+ // Derive timestamp from task ID (it's milliseconds since epoch)
106
+ const taskTimestamp = parseInt(taskId, 10);
107
+ const timestamp = isNaN(taskTimestamp)
108
+ ? undefined
109
+ : new Date(taskTimestamp).toISOString();
110
+ // Pair user → assistant messages
111
+ for (let i = 0; i < messages.length; i++) {
112
+ const msg = messages[i];
113
+ if (msg.role !== 'user')
114
+ continue;
115
+ // Find the next assistant message
116
+ const next = messages[i + 1];
117
+ if (!next || next.role !== 'assistant')
118
+ continue;
119
+ const userText = extractTextFromClineContent(msg.content);
120
+ const assistantText = extractTextFromClineContent(next.content);
121
+ // Skip tool_result-only user messages (not real user prompts)
122
+ if (!userText || isToolResultOnly(msg.content))
123
+ continue;
124
+ if (!assistantText)
125
+ continue;
126
+ const fileRefs = [
127
+ ...(0, common_1.extractFilePaths)(userText + '\n' + assistantText, root),
128
+ ...extractToolFileRefs(next.content),
129
+ ];
130
+ prompts.push({
131
+ source: 'cline',
132
+ timestamp,
133
+ userPrompt: userText,
134
+ assistantResponse: assistantText,
135
+ filesReferenced: [...new Set(fileRefs)],
136
+ });
137
+ i++; // Skip the assistant message we just consumed
138
+ }
139
+ return prompts;
140
+ }
141
+ /**
142
+ * Extract plain text from Cline content blocks.
143
+ */
144
+ function extractTextFromClineContent(content) {
145
+ if (!Array.isArray(content))
146
+ return '';
147
+ return content
148
+ .filter((b) => b.type === 'text' && typeof b.text === 'string')
149
+ .map((b) => b.text)
150
+ .join('\n');
151
+ }
152
+ /**
153
+ * Check if a content array is only tool_result blocks (not a real user message).
154
+ */
155
+ function isToolResultOnly(content) {
156
+ if (!Array.isArray(content))
157
+ return false;
158
+ return content.every((b) => b.type === 'tool_result');
159
+ }
160
+ /**
161
+ * Extract file paths from tool_use blocks.
162
+ */
163
+ function extractToolFileRefs(content) {
164
+ if (!Array.isArray(content))
165
+ return [];
166
+ const files = [];
167
+ for (const block of content) {
168
+ if (block.type === 'tool_use' && block.input) {
169
+ const filePath = block.input.path ||
170
+ block.input.file_path ||
171
+ block.input.filePath;
172
+ if (typeof filePath === 'string') {
173
+ files.push(filePath.replace(/\\/g, '/'));
174
+ }
175
+ }
176
+ }
177
+ return files;
178
+ }
179
+ //# sourceMappingURL=cline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cline.js","sourceRoot":"","sources":["../../src/harvest/cline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Shared utilities for prompt harvesters.
3
+ */
4
+ import type { HarvestedPrompt, OptLogger } from '../types';
5
+ /** Default maximum prompts harvested per source. */
6
+ export declare const DEFAULT_MAX_PER_SOURCE = 50;
7
+ /**
8
+ * Extract workspace-relative file paths from a text block.
9
+ * Looks for paths that match common code patterns.
10
+ */
11
+ export declare function extractFilePaths(text: string, _root: string): string[];
12
+ /**
13
+ * Filter prompts to only include those relevant to the current workspace.
14
+ * A prompt is relevant if it references at least one file path that exists
15
+ * somewhere in the conversation text matching a known workspace file.
16
+ */
17
+ export declare function filterRecent(prompts: HarvestedPrompt[], since: Date | undefined, max: number): HarvestedPrompt[];
18
+ /**
19
+ * Resolve the VS Code-style globalStorage path for an extension.
20
+ */
21
+ export declare function vscodeGlobalStoragePath(extensionId: string): string;
22
+ /**
23
+ * Resolve the VS Code-style workspaceStorage path.
24
+ */
25
+ export declare function vscodeWorkspaceStoragePath(): string;
26
+ /**
27
+ * Resolve a VS Code fork's storage paths (Cursor, Windsurf).
28
+ * Returns [globalStoragePath, workspaceStoragePath].
29
+ */
30
+ export declare function vscodeForkStoragePaths(appName: string): [string, string];
31
+ /**
32
+ * No-op logger for when no logger is provided.
33
+ */
34
+ export declare const noopLogger: OptLogger;
35
+ /**
36
+ * Truncate a string to a maximum length, appending "…" if truncated.
37
+ */
38
+ export declare function truncate(text: string, max: number): string;
39
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/harvest/common.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE3D,oDAAoD;AACpD,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBtE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,eAAe,EAAE,EAC1B,KAAK,EAAE,IAAI,GAAG,SAAS,EACvB,GAAG,EAAE,MAAM,GACV,eAAe,EAAE,CAgBnB;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAYnE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAUnD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAexE;AAED;;GAEG;AACH,eAAO,MAAM,UAAU,EAAE,SAKxB,CAAC;AAEF;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAG1D"}
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ /**
3
+ * Shared utilities for prompt harvesters.
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.noopLogger = exports.DEFAULT_MAX_PER_SOURCE = void 0;
40
+ exports.extractFilePaths = extractFilePaths;
41
+ exports.filterRecent = filterRecent;
42
+ exports.vscodeGlobalStoragePath = vscodeGlobalStoragePath;
43
+ exports.vscodeWorkspaceStoragePath = vscodeWorkspaceStoragePath;
44
+ exports.vscodeForkStoragePaths = vscodeForkStoragePaths;
45
+ exports.truncate = truncate;
46
+ const path = __importStar(require("path"));
47
+ const os = __importStar(require("os"));
48
+ /** Default maximum prompts harvested per source. */
49
+ exports.DEFAULT_MAX_PER_SOURCE = 50;
50
+ /**
51
+ * Extract workspace-relative file paths from a text block.
52
+ * Looks for paths that match common code patterns.
53
+ */
54
+ function extractFilePaths(text, _root) {
55
+ // Match file-like patterns: word/word.ext, src/foo/bar.ts, etc.
56
+ const pathPattern = /(?:^|\s|`|"|')([a-zA-Z0-9_./-]+\.[a-zA-Z]{1,10})(?:\s|`|"|'|$|[),;:])/gm;
57
+ const found = new Set();
58
+ let match;
59
+ while ((match = pathPattern.exec(text)) !== null) {
60
+ const candidate = match[1];
61
+ // Filter out URLs, version numbers, etc.
62
+ if (candidate.includes('://'))
63
+ continue;
64
+ if (/^\d+\.\d+\.\d+/.test(candidate))
65
+ continue;
66
+ if (candidate.startsWith('.'))
67
+ continue;
68
+ // Normalise to forward slashes
69
+ const normalised = candidate.replace(/\\/g, '/');
70
+ found.add(normalised);
71
+ }
72
+ return [...found];
73
+ }
74
+ /**
75
+ * Filter prompts to only include those relevant to the current workspace.
76
+ * A prompt is relevant if it references at least one file path that exists
77
+ * somewhere in the conversation text matching a known workspace file.
78
+ */
79
+ function filterRecent(prompts, since, max) {
80
+ let filtered = prompts;
81
+ if (since) {
82
+ const sinceMs = since.getTime();
83
+ filtered = filtered.filter((p) => {
84
+ if (!p.timestamp)
85
+ return true; // Keep prompts without timestamps
86
+ return new Date(p.timestamp).getTime() >= sinceMs;
87
+ });
88
+ }
89
+ // Take most recent first (sort by timestamp descending if available)
90
+ filtered.sort((a, b) => {
91
+ const ta = a.timestamp ? new Date(a.timestamp).getTime() : 0;
92
+ const tb = b.timestamp ? new Date(b.timestamp).getTime() : 0;
93
+ return tb - ta;
94
+ });
95
+ return filtered.slice(0, max);
96
+ }
97
+ /**
98
+ * Resolve the VS Code-style globalStorage path for an extension.
99
+ */
100
+ function vscodeGlobalStoragePath(extensionId) {
101
+ const platform = os.platform();
102
+ const home = os.homedir();
103
+ let base;
104
+ if (platform === 'win32') {
105
+ base = path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'Code', 'User', 'globalStorage');
106
+ }
107
+ else if (platform === 'darwin') {
108
+ base = path.join(home, 'Library', 'Application Support', 'Code', 'User', 'globalStorage');
109
+ }
110
+ else {
111
+ base = path.join(home, '.config', 'Code', 'User', 'globalStorage');
112
+ }
113
+ return path.join(base, extensionId);
114
+ }
115
+ /**
116
+ * Resolve the VS Code-style workspaceStorage path.
117
+ */
118
+ function vscodeWorkspaceStoragePath() {
119
+ const platform = os.platform();
120
+ const home = os.homedir();
121
+ if (platform === 'win32') {
122
+ return path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'Code', 'User', 'workspaceStorage');
123
+ }
124
+ else if (platform === 'darwin') {
125
+ return path.join(home, 'Library', 'Application Support', 'Code', 'User', 'workspaceStorage');
126
+ }
127
+ else {
128
+ return path.join(home, '.config', 'Code', 'User', 'workspaceStorage');
129
+ }
130
+ }
131
+ /**
132
+ * Resolve a VS Code fork's storage paths (Cursor, Windsurf).
133
+ * Returns [globalStoragePath, workspaceStoragePath].
134
+ */
135
+ function vscodeForkStoragePaths(appName) {
136
+ const platform = os.platform();
137
+ const home = os.homedir();
138
+ let base;
139
+ if (platform === 'win32') {
140
+ base = path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), appName, 'User');
141
+ }
142
+ else if (platform === 'darwin') {
143
+ base = path.join(home, 'Library', 'Application Support', appName, 'User');
144
+ }
145
+ else {
146
+ base = path.join(home, '.config', appName, 'User');
147
+ }
148
+ return [
149
+ path.join(base, 'globalStorage', 'state.vscdb'),
150
+ path.join(base, 'workspaceStorage'),
151
+ ];
152
+ }
153
+ /**
154
+ * No-op logger for when no logger is provided.
155
+ */
156
+ exports.noopLogger = {
157
+ info() { },
158
+ warn() { },
159
+ error() { },
160
+ debug() { },
161
+ };
162
+ /**
163
+ * Truncate a string to a maximum length, appending "…" if truncated.
164
+ */
165
+ function truncate(text, max) {
166
+ if (text.length <= max)
167
+ return text;
168
+ return text.slice(0, max - 1) + '…';
169
+ }
170
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/harvest/common.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaH,4CAkBC;AAOD,oCAoBC;AAKD,0DAYC;AAKD,gEAUC;AAMD,wDAeC;AAeD,4BAGC;AA/HD,2CAA6B;AAC7B,uCAAyB;AAGzB,oDAAoD;AACvC,QAAA,sBAAsB,GAAG,EAAE,CAAC;AAEzC;;;GAGG;AACH,SAAgB,gBAAgB,CAAC,IAAY,EAAE,KAAa;IAC1D,gEAAgE;IAChE,MAAM,WAAW,GAAG,yEAAyE,CAAC;IAC9F,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhC,IAAI,KAA6B,CAAC;IAClC,OAAO,CAAC,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACjD,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,yCAAyC;QACzC,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;QACxC,IAAI,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,SAAS;QAC/C,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACxC,+BAA+B;QAC/B,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACjD,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAC1B,OAA0B,EAC1B,KAAuB,EACvB,GAAW;IAEX,IAAI,QAAQ,GAAG,OAAO,CAAC;IACvB,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAChC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/B,IAAI,CAAC,CAAC,CAAC,SAAS;gBAAE,OAAO,IAAI,CAAC,CAAC,kCAAkC;YACjE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,OAAO,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC;IACD,qEAAqE;IACrE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,MAAM,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7D,OAAO,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,SAAgB,uBAAuB,CAAC,WAAmB;IACzD,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,IAAI,IAAY,CAAC;IACjB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAClH,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5F,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;AACtC,CAAC;AAED;;GAEG;AACH,SAAgB,0BAA0B;IACxC,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACrH,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC/F,CAAC;SAAM,CAAC;QACN,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACxE,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAgB,sBAAsB,CAAC,OAAe;IACpD,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,IAAI,IAAY,CAAC;IACjB,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAClG,CAAC;SAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IACD,OAAO;QACL,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,EAAE,aAAa,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,kBAAkB,CAAC;KACpC,CAAC;AACJ,CAAC;AAED;;GAEG;AACU,QAAA,UAAU,GAAc;IACnC,IAAI,KAAI,CAAC;IACT,IAAI,KAAI,CAAC;IACT,KAAK,KAAI,CAAC;IACV,KAAK,KAAI,CAAC;CACX,CAAC;AAEF;;GAEG;AACH,SAAgB,QAAQ,CAAC,IAAY,EAAE,GAAW;IAChD,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;AACtC,CAAC"}