@cmdctrl/cursor-ide 0.1.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 (62) hide show
  1. package/dist/adapter/cdp-client.d.ts +66 -0
  2. package/dist/adapter/cdp-client.d.ts.map +1 -0
  3. package/dist/adapter/cdp-client.js +304 -0
  4. package/dist/adapter/cdp-client.js.map +1 -0
  5. package/dist/adapter/cursor-db.d.ts +114 -0
  6. package/dist/adapter/cursor-db.d.ts.map +1 -0
  7. package/dist/adapter/cursor-db.js +438 -0
  8. package/dist/adapter/cursor-db.js.map +1 -0
  9. package/dist/client/messages.d.ts +98 -0
  10. package/dist/client/messages.d.ts.map +1 -0
  11. package/dist/client/messages.js +6 -0
  12. package/dist/client/messages.js.map +1 -0
  13. package/dist/client/websocket.d.ts +103 -0
  14. package/dist/client/websocket.d.ts.map +1 -0
  15. package/dist/client/websocket.js +428 -0
  16. package/dist/client/websocket.js.map +1 -0
  17. package/dist/commands/register.d.ts +10 -0
  18. package/dist/commands/register.d.ts.map +1 -0
  19. package/dist/commands/register.js +175 -0
  20. package/dist/commands/register.js.map +1 -0
  21. package/dist/commands/start.d.ts +9 -0
  22. package/dist/commands/start.d.ts.map +1 -0
  23. package/dist/commands/start.js +86 -0
  24. package/dist/commands/start.js.map +1 -0
  25. package/dist/commands/status.d.ts +5 -0
  26. package/dist/commands/status.d.ts.map +1 -0
  27. package/dist/commands/status.js +75 -0
  28. package/dist/commands/status.js.map +1 -0
  29. package/dist/commands/stop.d.ts +5 -0
  30. package/dist/commands/stop.d.ts.map +1 -0
  31. package/dist/commands/stop.js +59 -0
  32. package/dist/commands/stop.js.map +1 -0
  33. package/dist/config/config.d.ts +68 -0
  34. package/dist/config/config.d.ts.map +1 -0
  35. package/dist/config/config.js +189 -0
  36. package/dist/config/config.js.map +1 -0
  37. package/dist/index.d.ts +3 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +34 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/session-discovery.d.ts +22 -0
  42. package/dist/session-discovery.d.ts.map +1 -0
  43. package/dist/session-discovery.js +90 -0
  44. package/dist/session-discovery.js.map +1 -0
  45. package/dist/session-watcher.d.ts +62 -0
  46. package/dist/session-watcher.d.ts.map +1 -0
  47. package/dist/session-watcher.js +210 -0
  48. package/dist/session-watcher.js.map +1 -0
  49. package/package.json +40 -0
  50. package/src/adapter/cdp-client.ts +296 -0
  51. package/src/adapter/cursor-db.ts +486 -0
  52. package/src/client/messages.ts +138 -0
  53. package/src/client/websocket.ts +486 -0
  54. package/src/commands/register.ts +201 -0
  55. package/src/commands/start.ts +106 -0
  56. package/src/commands/status.ts +83 -0
  57. package/src/commands/stop.ts +58 -0
  58. package/src/config/config.ts +167 -0
  59. package/src/index.ts +39 -0
  60. package/src/session-discovery.ts +115 -0
  61. package/src/session-watcher.ts +253 -0
  62. package/tsconfig.json +19 -0
@@ -0,0 +1,66 @@
1
+ export interface CDPTarget {
2
+ id: string;
3
+ title: string;
4
+ url: string;
5
+ webSocketDebuggerUrl: string;
6
+ }
7
+ /**
8
+ * Chrome DevTools Protocol client for Cursor IDE
9
+ * Connects to Cursor's remote debugging port and allows sending messages
10
+ */
11
+ export declare class CDPClient {
12
+ private ws;
13
+ private msgId;
14
+ private pendingRequests;
15
+ private reconnecting;
16
+ /**
17
+ * Check if CDP is available (Cursor running with --remote-debugging-port)
18
+ */
19
+ isAvailable(): Promise<boolean>;
20
+ /**
21
+ * Get available CDP targets (Cursor windows/pages)
22
+ */
23
+ getTargets(): Promise<CDPTarget[]>;
24
+ /**
25
+ * Connect to Cursor via CDP WebSocket
26
+ */
27
+ connect(): Promise<void>;
28
+ /**
29
+ * Disconnect from CDP
30
+ */
31
+ disconnect(): void;
32
+ /**
33
+ * Check if connected to CDP
34
+ */
35
+ isConnected(): boolean;
36
+ /**
37
+ * Send a CDP command and wait for response
38
+ */
39
+ private sendCommand;
40
+ /**
41
+ * Evaluate JavaScript in the Cursor page context
42
+ */
43
+ evaluate(expression: string): Promise<unknown>;
44
+ /**
45
+ * Send a message to Cursor's chat composer
46
+ * 1. Focus the composer input
47
+ * 2. Clear any existing text
48
+ * 3. Insert the new message
49
+ * 4. Press Enter to submit
50
+ */
51
+ sendMessage(text: string): Promise<boolean>;
52
+ /**
53
+ * Check if the composer panel is open
54
+ */
55
+ isComposerOpen(): Promise<boolean>;
56
+ /**
57
+ * Toggle the composer panel open/closed (Cmd+I)
58
+ */
59
+ toggleComposer(): Promise<void>;
60
+ /**
61
+ * Get the current Cursor window title (useful for detecting active project)
62
+ */
63
+ getWindowTitle(): Promise<string | null>;
64
+ }
65
+ export declare function getCDPClient(): CDPClient;
66
+ //# sourceMappingURL=cdp-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdp-client.d.ts","sourceRoot":"","sources":["../../src/adapter/cdp-client.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,eAAe,CAGlB;IACL,OAAO,CAAC,YAAY,CAAS;IAE7B;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IASrC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAwBxC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsD9B;;OAEG;IACH,UAAU,IAAI,IAAI;IAQlB;;OAEG;IACH,WAAW,IAAI,OAAO;IAItB;;OAEG;YACW,WAAW;IAsBzB;;OAEG;IACG,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQpD;;;;;;OAMG;IACG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDjD;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC;IAkBxC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBrC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAS/C;AAKD,wBAAgB,YAAY,IAAI,SAAS,CAKxC"}
@@ -0,0 +1,304 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.CDPClient = void 0;
40
+ exports.getCDPClient = getCDPClient;
41
+ const ws_1 = __importDefault(require("ws"));
42
+ const http = __importStar(require("http"));
43
+ const config_1 = require("../config/config");
44
+ /**
45
+ * Chrome DevTools Protocol client for Cursor IDE
46
+ * Connects to Cursor's remote debugging port and allows sending messages
47
+ */
48
+ class CDPClient {
49
+ ws = null;
50
+ msgId = 1;
51
+ pendingRequests = new Map();
52
+ reconnecting = false;
53
+ /**
54
+ * Check if CDP is available (Cursor running with --remote-debugging-port)
55
+ */
56
+ async isAvailable() {
57
+ try {
58
+ const targets = await this.getTargets();
59
+ return targets.length > 0;
60
+ }
61
+ catch {
62
+ return false;
63
+ }
64
+ }
65
+ /**
66
+ * Get available CDP targets (Cursor windows/pages)
67
+ */
68
+ async getTargets() {
69
+ return new Promise((resolve, reject) => {
70
+ const req = http.get(`${config_1.CDP_URL}/json`, (res) => {
71
+ let data = '';
72
+ res.on('data', (chunk) => { data += chunk; });
73
+ res.on('end', () => {
74
+ try {
75
+ const targets = JSON.parse(data);
76
+ resolve(targets);
77
+ }
78
+ catch (err) {
79
+ reject(new Error(`Failed to parse CDP targets: ${err}`));
80
+ }
81
+ });
82
+ });
83
+ req.on('error', (err) => {
84
+ reject(new Error(`CDP not available: ${err.message}`));
85
+ });
86
+ req.setTimeout(3000, () => {
87
+ req.destroy();
88
+ reject(new Error('CDP connection timeout'));
89
+ });
90
+ });
91
+ }
92
+ /**
93
+ * Connect to Cursor via CDP WebSocket
94
+ */
95
+ async connect() {
96
+ if (this.ws && this.ws.readyState === ws_1.default.OPEN) {
97
+ return; // Already connected
98
+ }
99
+ const targets = await this.getTargets();
100
+ if (targets.length === 0) {
101
+ throw new Error('No CDP targets available. Is Cursor running with --remote-debugging-port=9222?');
102
+ }
103
+ // Find the main Cursor window (usually the workbench)
104
+ const target = targets.find(t => t.url.includes('workbench.html')) || targets[0];
105
+ return new Promise((resolve, reject) => {
106
+ this.ws = new ws_1.default(target.webSocketDebuggerUrl);
107
+ this.ws.on('open', async () => {
108
+ console.log('[CDP] Connected to Cursor');
109
+ // Enable required domains
110
+ await this.sendCommand('Runtime.enable');
111
+ resolve();
112
+ });
113
+ this.ws.on('message', (data) => {
114
+ try {
115
+ const msg = JSON.parse(data.toString());
116
+ if (msg.id !== undefined && this.pendingRequests.has(msg.id)) {
117
+ const pending = this.pendingRequests.get(msg.id);
118
+ this.pendingRequests.delete(msg.id);
119
+ if (msg.error) {
120
+ pending.reject(new Error(msg.error.message));
121
+ }
122
+ else {
123
+ pending.resolve(msg.result);
124
+ }
125
+ }
126
+ // Events (no id) are ignored for now
127
+ }
128
+ catch {
129
+ // Ignore parse errors
130
+ }
131
+ });
132
+ this.ws.on('error', (err) => {
133
+ console.error('[CDP] WebSocket error:', err.message);
134
+ reject(err);
135
+ });
136
+ this.ws.on('close', () => {
137
+ console.log('[CDP] Disconnected from Cursor');
138
+ this.ws = null;
139
+ this.pendingRequests.clear();
140
+ });
141
+ });
142
+ }
143
+ /**
144
+ * Disconnect from CDP
145
+ */
146
+ disconnect() {
147
+ if (this.ws) {
148
+ this.ws.close();
149
+ this.ws = null;
150
+ }
151
+ this.pendingRequests.clear();
152
+ }
153
+ /**
154
+ * Check if connected to CDP
155
+ */
156
+ isConnected() {
157
+ return this.ws !== null && this.ws.readyState === ws_1.default.OPEN;
158
+ }
159
+ /**
160
+ * Send a CDP command and wait for response
161
+ */
162
+ async sendCommand(method, params) {
163
+ if (!this.ws || this.ws.readyState !== ws_1.default.OPEN) {
164
+ throw new Error('CDP not connected');
165
+ }
166
+ const id = this.msgId++;
167
+ const msg = { id, method, params };
168
+ return new Promise((resolve, reject) => {
169
+ this.pendingRequests.set(id, { resolve, reject });
170
+ this.ws.send(JSON.stringify(msg));
171
+ // Timeout after 10 seconds
172
+ setTimeout(() => {
173
+ if (this.pendingRequests.has(id)) {
174
+ this.pendingRequests.delete(id);
175
+ reject(new Error(`CDP command timeout: ${method}`));
176
+ }
177
+ }, 10000);
178
+ });
179
+ }
180
+ /**
181
+ * Evaluate JavaScript in the Cursor page context
182
+ */
183
+ async evaluate(expression) {
184
+ const result = await this.sendCommand('Runtime.evaluate', {
185
+ expression,
186
+ returnByValue: true,
187
+ });
188
+ return result?.result?.value;
189
+ }
190
+ /**
191
+ * Send a message to Cursor's chat composer
192
+ * 1. Focus the composer input
193
+ * 2. Clear any existing text
194
+ * 3. Insert the new message
195
+ * 4. Press Enter to submit
196
+ */
197
+ async sendMessage(text) {
198
+ if (!this.isConnected()) {
199
+ await this.connect();
200
+ }
201
+ try {
202
+ // Focus the composer input
203
+ const focusResult = await this.evaluate(`
204
+ (function() {
205
+ const input = document.querySelector('.aislash-editor-input');
206
+ if (!input) return { success: false, error: 'Composer input not found' };
207
+ input.focus();
208
+ // Select all to clear existing text
209
+ const sel = window.getSelection();
210
+ if (sel) sel.selectAllChildren(input);
211
+ return { success: true };
212
+ })()
213
+ `);
214
+ if (!focusResult?.success) {
215
+ console.error('[CDP] Failed to focus composer:', focusResult?.error);
216
+ return false;
217
+ }
218
+ // Insert the text
219
+ await this.sendCommand('Input.insertText', { text });
220
+ // Press Enter to submit
221
+ await this.sendCommand('Input.dispatchKeyEvent', {
222
+ type: 'keyDown',
223
+ key: 'Enter',
224
+ code: 'Enter',
225
+ windowsVirtualKeyCode: 13,
226
+ nativeVirtualKeyCode: 13,
227
+ });
228
+ await this.sendCommand('Input.dispatchKeyEvent', {
229
+ type: 'keyUp',
230
+ key: 'Enter',
231
+ code: 'Enter',
232
+ });
233
+ console.log(`[CDP] Message sent: ${text.substring(0, 50)}...`);
234
+ return true;
235
+ }
236
+ catch (err) {
237
+ console.error('[CDP] Failed to send message:', err);
238
+ return false;
239
+ }
240
+ }
241
+ /**
242
+ * Check if the composer panel is open
243
+ */
244
+ async isComposerOpen() {
245
+ if (!this.isConnected()) {
246
+ return false;
247
+ }
248
+ try {
249
+ const result = await this.evaluate(`
250
+ (function() {
251
+ const input = document.querySelector('.aislash-editor-input');
252
+ return input !== null;
253
+ })()
254
+ `);
255
+ return result === true;
256
+ }
257
+ catch {
258
+ return false;
259
+ }
260
+ }
261
+ /**
262
+ * Toggle the composer panel open/closed (Cmd+I)
263
+ */
264
+ async toggleComposer() {
265
+ if (!this.isConnected()) {
266
+ await this.connect();
267
+ }
268
+ // Simulate Cmd+I
269
+ await this.sendCommand('Input.dispatchKeyEvent', {
270
+ type: 'keyDown',
271
+ key: 'i',
272
+ code: 'KeyI',
273
+ modifiers: 4, // Meta/Cmd
274
+ });
275
+ await this.sendCommand('Input.dispatchKeyEvent', {
276
+ type: 'keyUp',
277
+ key: 'i',
278
+ code: 'KeyI',
279
+ });
280
+ }
281
+ /**
282
+ * Get the current Cursor window title (useful for detecting active project)
283
+ */
284
+ async getWindowTitle() {
285
+ try {
286
+ const targets = await this.getTargets();
287
+ const target = targets.find(t => t.url.includes('workbench.html'));
288
+ return target?.title || null;
289
+ }
290
+ catch {
291
+ return null;
292
+ }
293
+ }
294
+ }
295
+ exports.CDPClient = CDPClient;
296
+ // Singleton instance
297
+ let cdpClientInstance = null;
298
+ function getCDPClient() {
299
+ if (!cdpClientInstance) {
300
+ cdpClientInstance = new CDPClient();
301
+ }
302
+ return cdpClientInstance;
303
+ }
304
+ //# sourceMappingURL=cdp-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdp-client.js","sourceRoot":"","sources":["../../src/adapter/cdp-client.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkSA,oCAKC;AAvSD,4CAA2B;AAC3B,2CAA6B;AAC7B,6CAA2C;AAS3C;;;GAGG;AACH,MAAa,SAAS;IACZ,EAAE,GAAqB,IAAI,CAAC;IAC5B,KAAK,GAAG,CAAC,CAAC;IACV,eAAe,GAAG,IAAI,GAAG,EAG7B,CAAC;IACG,YAAY,GAAG,KAAK,CAAC;IAE7B;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,gBAAO,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC9C,IAAI,IAAI,GAAG,EAAE,CAAC;gBACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC9C,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;oBACjB,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAgB,CAAC;wBAChD,OAAO,CAAC,OAAO,CAAC,CAAC;oBACnB,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,CAAC,IAAI,KAAK,CAAC,gCAAgC,GAAG,EAAE,CAAC,CAAC,CAAC;oBAC3D,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACtB,MAAM,CAAC,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACzD,CAAC,CAAC,CAAC;YACH,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE;gBACxB,GAAG,CAAC,OAAO,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,YAAS,CAAC,IAAI,EAAE,CAAC;YACrD,OAAO,CAAC,oBAAoB;QAC9B,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QACxC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;QACpG,CAAC;QAED,sDAAsD;QACtD,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;QAEjF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,EAAE,GAAG,IAAI,YAAS,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;YAErD,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;gBAC5B,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;gBACzC,0BAA0B;gBAC1B,MAAM,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;gBACzC,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC7B,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;oBACxC,IAAI,GAAG,CAAC,EAAE,KAAK,SAAS,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;wBAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;wBAClD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBACpC,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;4BACd,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;wBAC/C,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;wBAC9B,CAAC;oBACH,CAAC;oBACD,qCAAqC;gBACvC,CAAC;gBAAC,MAAM,CAAC;oBACP,sBAAsB;gBACxB,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC1B,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBACrD,MAAM,CAAC,GAAG,CAAC,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;gBAC9C,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;gBACf,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;YAC/B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,UAAU;QACR,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,YAAS,CAAC,IAAI,CAAC;IACnE,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,MAAgC;QACxE,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,UAAU,KAAK,YAAS,CAAC,IAAI,EAAE,CAAC;YACtD,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAEnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YAClD,IAAI,CAAC,EAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;YAEnC,2BAA2B;YAC3B,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;oBACjC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBAChC,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC,EAAE,KAAK,CAAC,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,UAAkB;QAC/B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE;YACxD,UAAU;YACV,aAAa,EAAE,IAAI;SACpB,CAAqC,CAAC;QACvC,OAAO,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC;IAC/B,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,WAAW,CAAC,IAAY;QAC5B,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QAED,IAAI,CAAC;YACH,2BAA2B;YAC3B,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;;;;;;;;;;OAUvC,CAAyC,CAAC;YAE3C,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,CAAC;gBAC1B,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;gBACrE,OAAO,KAAK,CAAC;YACf,CAAC;YAED,kBAAkB;YAClB,MAAM,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;YAErD,wBAAwB;YACxB,MAAM,IAAI,CAAC,WAAW,CAAC,wBAAwB,EAAE;gBAC/C,IAAI,EAAE,SAAS;gBACf,GAAG,EAAE,OAAO;gBACZ,IAAI,EAAE,OAAO;gBACb,qBAAqB,EAAE,EAAE;gBACzB,oBAAoB,EAAE,EAAE;aACzB,CAAC,CAAC;YACH,MAAM,IAAI,CAAC,WAAW,CAAC,wBAAwB,EAAE;gBAC/C,IAAI,EAAE,OAAO;gBACb,GAAG,EAAE,OAAO;gBACZ,IAAI,EAAE,OAAO;aACd,CAAC,CAAC;YAEH,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;YAC/D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;YACpD,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;;;;;OAKlC,CAAC,CAAC;YACH,OAAO,MAAM,KAAK,IAAI,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QAED,iBAAiB;QACjB,MAAM,IAAI,CAAC,WAAW,CAAC,wBAAwB,EAAE;YAC/C,IAAI,EAAE,SAAS;YACf,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,MAAM;YACZ,SAAS,EAAE,CAAC,EAAE,WAAW;SAC1B,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,WAAW,CAAC,wBAAwB,EAAE;YAC/C,IAAI,EAAE,OAAO;YACb,GAAG,EAAE,GAAG;YACR,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACnE,OAAO,MAAM,EAAE,KAAK,IAAI,IAAI,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF;AA9QD,8BA8QC;AAED,qBAAqB;AACrB,IAAI,iBAAiB,GAAqB,IAAI,CAAC;AAE/C,SAAgB,YAAY;IAC1B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,iBAAiB,GAAG,IAAI,SAAS,EAAE,CAAC;IACtC,CAAC;IACD,OAAO,iBAAiB,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,114 @@
1
+ export interface ComposerInfo {
2
+ composerId: string;
3
+ name: string;
4
+ createdAt: number;
5
+ lastUpdatedAt: number;
6
+ unifiedMode: string;
7
+ contextUsagePercent: number;
8
+ projectPath?: string;
9
+ }
10
+ export interface ComposerData {
11
+ allComposers: ComposerInfo[];
12
+ fullConversationHeadersOnly?: Array<{
13
+ bubbleId: string;
14
+ type: number;
15
+ }>;
16
+ }
17
+ export interface BubbleData {
18
+ _v: number;
19
+ type: number;
20
+ bubbleId: string;
21
+ text: string;
22
+ createdAt: string;
23
+ tokenCount?: {
24
+ inputTokens: number;
25
+ outputTokens: number;
26
+ };
27
+ toolResults?: unknown[];
28
+ codebaseContextChunks?: unknown[];
29
+ allThinkingBlocks?: unknown[];
30
+ }
31
+ export interface MessageEntry {
32
+ uuid: string;
33
+ role: 'USER' | 'AGENT';
34
+ content: string;
35
+ timestamp: string;
36
+ }
37
+ /**
38
+ * Cursor SQLite Database Reader
39
+ * Reads conversation data from Cursor's local storage
40
+ */
41
+ export declare class CursorDB {
42
+ private globalDb;
43
+ private lastOpenAttempt;
44
+ private lastRefresh;
45
+ private readonly RETRY_INTERVAL;
46
+ private readonly REFRESH_INTERVAL;
47
+ /**
48
+ * Check if the Cursor database exists
49
+ */
50
+ static exists(): boolean;
51
+ /**
52
+ * Open the global storage database (read-only)
53
+ * Periodically refreshes the connection to see WAL updates from Cursor
54
+ */
55
+ private openGlobalDb;
56
+ /**
57
+ * Close database connections
58
+ */
59
+ close(): void;
60
+ /**
61
+ * Extract project path from composer context
62
+ * Looks at fileSelections and folderSelections for path info
63
+ */
64
+ private extractProjectPath;
65
+ /**
66
+ * Find project root from a file path
67
+ * Looks for common project markers (package.json, .git, go.mod, etc.)
68
+ */
69
+ private findProjectRoot;
70
+ /**
71
+ * Get all composers (conversation sessions)
72
+ */
73
+ getComposers(): ComposerInfo[];
74
+ /**
75
+ * Get composer data including conversation headers
76
+ */
77
+ getComposerData(composerId: string): ComposerData | null;
78
+ /**
79
+ * Get all bubbles (messages) for a composer
80
+ */
81
+ getBubbles(composerId: string): BubbleData[];
82
+ /**
83
+ * Get the latest bubble for a composer (optimized - uses SQL sorting)
84
+ */
85
+ getLatestBubble(composerId: string): BubbleData | null;
86
+ /**
87
+ * Get messages for a session in a format compatible with CmdCtrl API
88
+ * @param composerId The composer/session ID
89
+ * @param limit Maximum number of messages to return
90
+ * @param beforeUuid Return messages before this UUID (for backward pagination)
91
+ * @param afterUuid Return messages after this UUID (for incremental/forward fetches)
92
+ */
93
+ getMessages(composerId: string, limit?: number, beforeUuid?: string, afterUuid?: string): {
94
+ messages: MessageEntry[];
95
+ hasMore: boolean;
96
+ oldestUuid?: string;
97
+ newestUuid?: string;
98
+ };
99
+ /**
100
+ * Get the count of bubbles for a composer
101
+ */
102
+ getBubbleCount(composerId: string): number;
103
+ /**
104
+ * Get workspace storage paths that contain state.vscdb files
105
+ */
106
+ getWorkspaceStoragePaths(): string[];
107
+ /**
108
+ * Try to determine the project path for a workspace storage hash
109
+ * This is a best-effort attempt based on workspace.json if it exists
110
+ */
111
+ getWorkspaceProjectPath(workspaceHash: string): string | null;
112
+ }
113
+ export declare function getCursorDB(): CursorDB;
114
+ //# sourceMappingURL=cursor-db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor-db.d.ts","sourceRoot":"","sources":["../../src/adapter/cursor-db.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,YAAY,EAAE,CAAC;IAC7B,2BAA2B,CAAC,EAAE,KAAK,CAAC;QAClC,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB,qBAAqB,CAAC,EAAE,OAAO,EAAE,CAAC;IAClC,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAQ;IACvC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IAEzC;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,OAAO;IAIxB;;;OAGG;IACH,OAAO,CAAC,YAAY;IA6CpB;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA6B1B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAkBvB;;OAEG;IACH,YAAY,IAAI,YAAY,EAAE;IAqD9B;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAuBxD;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE;IAmC5C;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IA2BtD;;;;;;OAMG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,SAAK,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG;QACpF,QAAQ,EAAE,YAAY,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IA8DD;;OAEG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAkB1C;;OAEG;IACH,wBAAwB,IAAI,MAAM,EAAE;IAqBpC;;;OAGG;IACH,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;CAyB9D;AAKD,wBAAgB,WAAW,IAAI,QAAQ,CAKtC"}