@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.
- package/dist/adapter/cdp-client.d.ts +66 -0
- package/dist/adapter/cdp-client.d.ts.map +1 -0
- package/dist/adapter/cdp-client.js +304 -0
- package/dist/adapter/cdp-client.js.map +1 -0
- package/dist/adapter/cursor-db.d.ts +114 -0
- package/dist/adapter/cursor-db.d.ts.map +1 -0
- package/dist/adapter/cursor-db.js +438 -0
- package/dist/adapter/cursor-db.js.map +1 -0
- package/dist/client/messages.d.ts +98 -0
- package/dist/client/messages.d.ts.map +1 -0
- package/dist/client/messages.js +6 -0
- package/dist/client/messages.js.map +1 -0
- package/dist/client/websocket.d.ts +103 -0
- package/dist/client/websocket.d.ts.map +1 -0
- package/dist/client/websocket.js +428 -0
- package/dist/client/websocket.js.map +1 -0
- package/dist/commands/register.d.ts +10 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +175 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/start.d.ts +9 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +86 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +75 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +5 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +59 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/config/config.d.ts +68 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +189 -0
- package/dist/config/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/session-discovery.d.ts +22 -0
- package/dist/session-discovery.d.ts.map +1 -0
- package/dist/session-discovery.js +90 -0
- package/dist/session-discovery.js.map +1 -0
- package/dist/session-watcher.d.ts +62 -0
- package/dist/session-watcher.d.ts.map +1 -0
- package/dist/session-watcher.js +210 -0
- package/dist/session-watcher.js.map +1 -0
- package/package.json +40 -0
- package/src/adapter/cdp-client.ts +296 -0
- package/src/adapter/cursor-db.ts +486 -0
- package/src/client/messages.ts +138 -0
- package/src/client/websocket.ts +486 -0
- package/src/commands/register.ts +201 -0
- package/src/commands/start.ts +106 -0
- package/src/commands/status.ts +83 -0
- package/src/commands/stop.ts +58 -0
- package/src/config/config.ts +167 -0
- package/src/index.ts +39 -0
- package/src/session-discovery.ts +115 -0
- package/src/session-watcher.ts +253 -0
- 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":"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"}
|
|
@@ -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"}
|