@cmdctrl/cursor-cli 0.1.1

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 (57) hide show
  1. package/dist/adapter/cursor-cli.d.ts +36 -0
  2. package/dist/adapter/cursor-cli.d.ts.map +1 -0
  3. package/dist/adapter/cursor-cli.js +332 -0
  4. package/dist/adapter/cursor-cli.js.map +1 -0
  5. package/dist/adapter/events.d.ts +33 -0
  6. package/dist/adapter/events.d.ts.map +1 -0
  7. package/dist/adapter/events.js +53 -0
  8. package/dist/adapter/events.js.map +1 -0
  9. package/dist/client/messages.d.ts +50 -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 +69 -0
  14. package/dist/client/websocket.d.ts.map +1 -0
  15. package/dist/client/websocket.js +272 -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 +173 -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 +49 -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 +39 -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 +42 -0
  32. package/dist/commands/stop.js.map +1 -0
  33. package/dist/commands/update.d.ts +2 -0
  34. package/dist/commands/update.d.ts.map +1 -0
  35. package/dist/commands/update.js +72 -0
  36. package/dist/commands/update.js.map +1 -0
  37. package/dist/config/config.d.ts +60 -0
  38. package/dist/config/config.d.ts.map +1 -0
  39. package/dist/config/config.js +176 -0
  40. package/dist/config/config.js.map +1 -0
  41. package/dist/index.d.ts +3 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +50 -0
  44. package/dist/index.js.map +1 -0
  45. package/package.json +38 -0
  46. package/src/adapter/cursor-cli.ts +370 -0
  47. package/src/adapter/events.ts +77 -0
  48. package/src/client/messages.ts +75 -0
  49. package/src/client/websocket.ts +308 -0
  50. package/src/commands/register.ts +199 -0
  51. package/src/commands/start.ts +64 -0
  52. package/src/commands/status.ts +46 -0
  53. package/src/commands/stop.ts +47 -0
  54. package/src/commands/update.ts +73 -0
  55. package/src/config/config.ts +146 -0
  56. package/src/index.ts +56 -0
  57. package/tsconfig.json +19 -0
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DaemonClient = void 0;
7
+ const ws_1 = __importDefault(require("ws"));
8
+ const url_1 = require("url");
9
+ const cursor_cli_1 = require("../adapter/cursor-cli");
10
+ const fs_1 = require("fs");
11
+ const path_1 = require("path");
12
+ const MAX_RECONNECT_DELAY = 30000; // 30 seconds
13
+ const INITIAL_RECONNECT_DELAY = 1000; // 1 second
14
+ const PING_INTERVAL = 30000; // 30 seconds
15
+ class DaemonClient {
16
+ ws = null;
17
+ config;
18
+ credentials;
19
+ reconnectDelay = INITIAL_RECONNECT_DELAY;
20
+ reconnectTimer = null;
21
+ pingTimer = null;
22
+ shouldReconnect = true;
23
+ adapter;
24
+ constructor(config, credentials) {
25
+ this.config = config;
26
+ this.credentials = credentials;
27
+ this.adapter = new cursor_cli_1.CursorAdapter(this.sendEvent.bind(this));
28
+ }
29
+ /**
30
+ * Connect to the CmdCtrl server via WebSocket
31
+ */
32
+ async connect() {
33
+ return new Promise((resolve, reject) => {
34
+ const serverUrl = new url_1.URL(this.config.serverUrl);
35
+ const wsProtocol = serverUrl.protocol === 'https:' ? 'wss:' : 'ws:';
36
+ const wsUrl = `${wsProtocol}//${serverUrl.host}/ws/daemon`;
37
+ console.log(`Connecting to ${wsUrl}...`);
38
+ // Read version from package.json
39
+ let daemonVersion = 'unknown';
40
+ try {
41
+ const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', 'package.json'), 'utf-8'));
42
+ daemonVersion = pkg.version;
43
+ }
44
+ catch {
45
+ try {
46
+ const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, '..', '..', 'package.json'), 'utf-8'));
47
+ daemonVersion = pkg.version;
48
+ }
49
+ catch { /* use default */ }
50
+ }
51
+ this.ws = new ws_1.default(wsUrl, {
52
+ headers: {
53
+ Authorization: `Bearer ${this.credentials.accessToken}`,
54
+ 'X-Device-ID': this.config.deviceId,
55
+ 'X-Agent-Type': 'cursor_cli',
56
+ 'X-Daemon-Version': daemonVersion,
57
+ }
58
+ });
59
+ this.ws.on('open', () => {
60
+ console.log('WebSocket connected');
61
+ this.reconnectDelay = INITIAL_RECONNECT_DELAY;
62
+ this.startPingInterval();
63
+ this.sendStatus();
64
+ resolve();
65
+ });
66
+ this.ws.on('message', (data) => {
67
+ this.handleMessage(data.toString());
68
+ });
69
+ this.ws.on('close', (code, reason) => {
70
+ console.log(`WebSocket closed: ${code} ${reason}`);
71
+ this.stopPingInterval();
72
+ this.scheduleReconnect();
73
+ });
74
+ this.ws.on('error', (err) => {
75
+ console.error('WebSocket error:', err.message);
76
+ if (this.ws?.readyState === ws_1.default.CONNECTING) {
77
+ reject(err);
78
+ }
79
+ // For established connections, the 'close' event usually follows 'error',
80
+ // but if the connection was killed abruptly, we may not get a clean close.
81
+ // Force close the socket to ensure 'close' event fires and triggers reconnect.
82
+ if (this.ws?.readyState === ws_1.default.OPEN) {
83
+ this.ws.terminate();
84
+ }
85
+ });
86
+ });
87
+ }
88
+ /**
89
+ * Disconnect from server
90
+ */
91
+ async disconnect() {
92
+ this.shouldReconnect = false;
93
+ if (this.reconnectTimer) {
94
+ clearTimeout(this.reconnectTimer);
95
+ this.reconnectTimer = null;
96
+ }
97
+ this.stopPingInterval();
98
+ // Stop all running tasks
99
+ await this.adapter.stopAll();
100
+ if (this.ws) {
101
+ this.ws.close(1000, 'Daemon shutting down');
102
+ this.ws = null;
103
+ }
104
+ }
105
+ /**
106
+ * Send a message to the server
107
+ */
108
+ send(message) {
109
+ if (this.ws?.readyState === ws_1.default.OPEN) {
110
+ this.ws.send(JSON.stringify(message));
111
+ }
112
+ }
113
+ /**
114
+ * Send an event for a task
115
+ */
116
+ sendEvent(taskId, eventType, data) {
117
+ this.send({
118
+ type: 'event',
119
+ task_id: taskId,
120
+ event_type: eventType,
121
+ ...data
122
+ });
123
+ }
124
+ /**
125
+ * Send current status to server
126
+ */
127
+ sendStatus() {
128
+ this.send({
129
+ type: 'status',
130
+ running_tasks: this.adapter.getRunningTasks()
131
+ });
132
+ }
133
+ /**
134
+ * Handle incoming message from server
135
+ */
136
+ handleMessage(raw) {
137
+ let msg;
138
+ try {
139
+ msg = JSON.parse(raw);
140
+ }
141
+ catch {
142
+ console.error('Failed to parse message:', raw);
143
+ return;
144
+ }
145
+ switch (msg.type) {
146
+ case 'ping':
147
+ this.send({ type: 'pong' });
148
+ break;
149
+ case 'task_start':
150
+ this.handleTaskStart(msg);
151
+ break;
152
+ case 'task_resume':
153
+ this.handleTaskResume(msg);
154
+ break;
155
+ case 'task_cancel':
156
+ this.handleTaskCancel(msg);
157
+ break;
158
+ case 'version_status':
159
+ this.handleVersionStatus(msg);
160
+ break;
161
+ default:
162
+ console.warn('Unknown message type:', msg.type);
163
+ }
164
+ }
165
+ /**
166
+ * Handle task_start message
167
+ */
168
+ async handleTaskStart(msg) {
169
+ console.log(`Starting task ${msg.task_id}: ${msg.instruction.substring(0, 50)}...`);
170
+ try {
171
+ await this.adapter.startTask(msg.task_id, msg.instruction, msg.project_path);
172
+ }
173
+ catch (err) {
174
+ console.error(`Failed to start task ${msg.task_id}:`, err);
175
+ this.sendEvent(msg.task_id, 'ERROR', {
176
+ error: err.message
177
+ });
178
+ }
179
+ }
180
+ /**
181
+ * Handle task_resume message
182
+ */
183
+ async handleTaskResume(msg) {
184
+ console.log(`Resuming task ${msg.task_id} with session ${msg.session_id}`);
185
+ try {
186
+ await this.adapter.resumeTask(msg.task_id, msg.session_id, msg.message, msg.project_path);
187
+ }
188
+ catch (err) {
189
+ console.error(`Failed to resume task ${msg.task_id}:`, err);
190
+ this.sendEvent(msg.task_id, 'ERROR', {
191
+ error: err.message
192
+ });
193
+ }
194
+ }
195
+ /**
196
+ * Handle task_cancel message
197
+ */
198
+ async handleTaskCancel(msg) {
199
+ console.log(`Cancelling task ${msg.task_id}`);
200
+ await this.adapter.cancelTask(msg.task_id);
201
+ }
202
+ /**
203
+ * Handle version_status message from server
204
+ */
205
+ handleVersionStatus(msg) {
206
+ if (msg.status === 'update_required') {
207
+ console.error(`\n✖ Daemon version ${msg.your_version} is no longer supported (minimum: ${msg.min_version})`);
208
+ console.error(` Run: cmdctrl-cursor-cli update`);
209
+ if (msg.changelog_url)
210
+ console.error(` Changelog: ${msg.changelog_url}`);
211
+ if (msg.message)
212
+ console.error(` ${msg.message}`);
213
+ console.error('');
214
+ this.shouldReconnect = false;
215
+ process.exit(1);
216
+ }
217
+ else if (msg.status === 'update_available') {
218
+ console.warn(`\n⚠ Update available: v${msg.latest_version} (you have v${msg.your_version})`);
219
+ console.warn(` Run: cmdctrl-cursor-cli update`);
220
+ if (msg.changelog_url)
221
+ console.warn(` Changelog: ${msg.changelog_url}`);
222
+ console.warn('');
223
+ }
224
+ }
225
+ /**
226
+ * Schedule reconnection with exponential backoff
227
+ */
228
+ scheduleReconnect() {
229
+ if (!this.shouldReconnect) {
230
+ return;
231
+ }
232
+ console.log(`Reconnecting in ${this.reconnectDelay / 1000}s...`);
233
+ this.reconnectTimer = setTimeout(async () => {
234
+ try {
235
+ await this.connect();
236
+ }
237
+ catch {
238
+ // Increase delay with exponential backoff
239
+ this.reconnectDelay = Math.min(this.reconnectDelay * 2, MAX_RECONNECT_DELAY);
240
+ this.scheduleReconnect();
241
+ }
242
+ }, this.reconnectDelay);
243
+ }
244
+ /**
245
+ * Start ping interval to keep connection alive
246
+ */
247
+ startPingInterval() {
248
+ this.pingTimer = setInterval(() => {
249
+ if (this.ws?.readyState === ws_1.default.OPEN) {
250
+ this.ws.ping();
251
+ }
252
+ }, PING_INTERVAL);
253
+ }
254
+ /**
255
+ * Stop ping interval
256
+ */
257
+ stopPingInterval() {
258
+ if (this.pingTimer) {
259
+ clearInterval(this.pingTimer);
260
+ this.pingTimer = null;
261
+ }
262
+ }
263
+ /**
264
+ * Refresh access token using refresh token
265
+ */
266
+ async refreshToken() {
267
+ console.log('Token refresh not yet implemented');
268
+ return false;
269
+ }
270
+ }
271
+ exports.DaemonClient = DaemonClient;
272
+ //# sourceMappingURL=websocket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/client/websocket.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ interface RegisterOptions {
2
+ server: string;
3
+ name?: string;
4
+ }
5
+ /**
6
+ * Register command - implements GitHub CLI style device auth flow
7
+ */
8
+ export declare function register(options: RegisterOptions): Promise<void>;
9
+ export {};
10
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAaA,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA4GD;;GAEG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAuEtE"}
@@ -0,0 +1,173 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.register = register;
37
+ const os = __importStar(require("os"));
38
+ const http = __importStar(require("http"));
39
+ const https = __importStar(require("https"));
40
+ const url_1 = require("url");
41
+ const config_1 = require("../config/config");
42
+ /**
43
+ * Make an HTTP(S) request
44
+ */
45
+ function request(url, method, body) {
46
+ return new Promise((resolve, reject) => {
47
+ const parsed = new url_1.URL(url);
48
+ const client = parsed.protocol === 'https:' ? https : http;
49
+ const options = {
50
+ hostname: parsed.hostname,
51
+ port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80),
52
+ path: parsed.pathname + parsed.search,
53
+ method,
54
+ headers: {
55
+ 'Content-Type': 'application/json',
56
+ Accept: 'application/json'
57
+ }
58
+ };
59
+ const req = client.request(options, (res) => {
60
+ let data = '';
61
+ res.on('data', (chunk) => (data += chunk));
62
+ res.on('end', () => {
63
+ try {
64
+ const parsed = data ? JSON.parse(data) : {};
65
+ resolve({ status: res.statusCode || 0, data: parsed });
66
+ }
67
+ catch {
68
+ resolve({ status: res.statusCode || 0, data: {} });
69
+ }
70
+ });
71
+ });
72
+ req.on('error', reject);
73
+ if (body) {
74
+ req.write(JSON.stringify(body));
75
+ }
76
+ req.end();
77
+ });
78
+ }
79
+ /**
80
+ * Poll for token completion (after user verifies in browser)
81
+ */
82
+ async function pollForToken(serverUrl, deviceCode, interval, expiresIn) {
83
+ const startTime = Date.now();
84
+ const expiresAt = startTime + expiresIn * 1000;
85
+ while (Date.now() < expiresAt) {
86
+ await new Promise((resolve) => setTimeout(resolve, interval * 1000));
87
+ try {
88
+ const response = await request(`${serverUrl}/api/devices/token`, 'POST', {
89
+ deviceCode
90
+ });
91
+ if (response.status === 200) {
92
+ return response.data;
93
+ }
94
+ // 400 with "authorization_pending" means keep polling
95
+ const data = response.data;
96
+ if (response.status === 400 && data.error === 'authorization_pending') {
97
+ process.stdout.write('.');
98
+ continue;
99
+ }
100
+ // Other errors should stop polling
101
+ if (response.status >= 400) {
102
+ console.error('\nError polling for token:', data);
103
+ return null;
104
+ }
105
+ }
106
+ catch (err) {
107
+ console.error('\nError polling for token:', err);
108
+ return null;
109
+ }
110
+ }
111
+ console.error('\nDevice code expired. Please try again.');
112
+ return null;
113
+ }
114
+ /**
115
+ * Register command - implements GitHub CLI style device auth flow
116
+ */
117
+ async function register(options) {
118
+ const serverUrl = options.server.replace(/\/$/, ''); // Remove trailing slash
119
+ const deviceName = options.name || `${os.hostname()}-cursor`;
120
+ // Check if already registered
121
+ if ((0, config_1.isRegistered)()) {
122
+ const config = (0, config_1.readConfig)();
123
+ console.log(`Already registered as "${config?.deviceName}" (${config?.deviceId})`);
124
+ console.log(`Server: ${config?.serverUrl}`);
125
+ console.log(`\nTo re-register, run: ${process.argv[1]} unregister`);
126
+ return;
127
+ }
128
+ console.log(`Registering Cursor CLI device "${deviceName}" with ${serverUrl}...\n`);
129
+ // Step 1: Request device code
130
+ let codeResponse;
131
+ try {
132
+ const response = await request(`${serverUrl}/api/devices/code`, 'POST', {
133
+ deviceName,
134
+ hostname: os.hostname(),
135
+ agentType: 'cursor_cli'
136
+ });
137
+ if (response.status !== 200) {
138
+ console.error('Failed to get device code:', response.data);
139
+ process.exit(1);
140
+ }
141
+ codeResponse = response.data;
142
+ }
143
+ catch (err) {
144
+ console.error('Failed to connect to server:', err);
145
+ process.exit(1);
146
+ }
147
+ // Step 2: Display instructions to user
148
+ console.log('To complete registration, open this URL in your browser:\n');
149
+ console.log(` ${codeResponse.verificationUrl}\n`);
150
+ console.log('Waiting for verification...');
151
+ // Step 3: Poll for completion
152
+ const tokenResponse = await pollForToken(serverUrl, codeResponse.deviceCode, codeResponse.interval, codeResponse.expiresIn);
153
+ if (!tokenResponse) {
154
+ process.exit(1);
155
+ }
156
+ // Step 4: Save config and credentials
157
+ const config = {
158
+ serverUrl,
159
+ deviceId: tokenResponse.deviceId,
160
+ deviceName
161
+ };
162
+ const credentials = {
163
+ accessToken: tokenResponse.accessToken,
164
+ refreshToken: tokenResponse.refreshToken,
165
+ expiresAt: Date.now() + tokenResponse.expiresIn * 1000
166
+ };
167
+ (0, config_1.writeConfig)(config);
168
+ (0, config_1.writeCredentials)(credentials);
169
+ console.log('\n\nRegistration complete!');
170
+ console.log(`Device ID: ${tokenResponse.deviceId}`);
171
+ console.log(`\nRun 'cmdctrl-cursor-cli start' to connect to the server.`);
172
+ }
173
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ interface StartOptions {
2
+ foreground?: boolean;
3
+ }
4
+ /**
5
+ * Start the daemon
6
+ */
7
+ export declare function start(options: StartOptions): Promise<void>;
8
+ export {};
9
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AASA,UAAU,YAAY;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;GAEG;AACH,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ChE"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.start = start;
4
+ const config_1 = require("../config/config");
5
+ const websocket_1 = require("../client/websocket");
6
+ /**
7
+ * Start the daemon
8
+ */
9
+ async function start(options) {
10
+ // Check if registered
11
+ if (!(0, config_1.isRegistered)()) {
12
+ console.error('Device not registered. Run "cmdctrl-cursor-cli-daemon register" first.');
13
+ process.exit(1);
14
+ }
15
+ // Check if already running
16
+ if ((0, config_1.isDaemonRunning)()) {
17
+ console.error('Daemon is already running. Use "cmdctrl-cursor-cli-daemon stop" to stop it.');
18
+ process.exit(1);
19
+ }
20
+ const config = (0, config_1.readConfig)();
21
+ const credentials = (0, config_1.readCredentials)();
22
+ console.log(`Starting Cursor CLI daemon for device "${config.deviceName}"...`);
23
+ console.log(`Server: ${config.serverUrl}`);
24
+ // Write PID file
25
+ (0, config_1.writePidFile)(process.pid);
26
+ // Create and connect client
27
+ const client = new websocket_1.DaemonClient(config, credentials);
28
+ // Handle shutdown signals
29
+ const shutdown = async (signal) => {
30
+ console.log(`\nReceived ${signal}, shutting down...`);
31
+ await client.disconnect();
32
+ process.exit(0);
33
+ };
34
+ process.on('SIGINT', () => shutdown('SIGINT'));
35
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
36
+ try {
37
+ await client.connect();
38
+ console.log('Cursor CLI daemon connected and ready for tasks.');
39
+ // In foreground mode, just keep running
40
+ if (options.foreground) {
41
+ console.log('Running in foreground. Press Ctrl+C to stop.');
42
+ }
43
+ }
44
+ catch (err) {
45
+ console.error('Failed to connect:', err);
46
+ process.exit(1);
47
+ }
48
+ }
49
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":";;AAgBA,sBA+CC;AA/DD,6CAM0B;AAC1B,mDAAmD;AAMnD;;GAEG;AACI,KAAK,UAAU,KAAK,CAAC,OAAqB;IAC/C,sBAAsB;IACtB,IAAI,CAAC,IAAA,qBAAY,GAAE,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;QACxF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,2BAA2B;IAC3B,IAAI,IAAA,wBAAe,GAAE,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAG,CAAC;IAC7B,MAAM,WAAW,GAAG,IAAA,wBAAe,GAAG,CAAC;IAEvC,OAAO,CAAC,GAAG,CAAC,0CAA0C,MAAM,CAAC,UAAU,MAAM,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAE3C,iBAAiB;IACjB,IAAA,qBAAY,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE1B,4BAA4B;IAC5B,MAAM,MAAM,GAAG,IAAI,wBAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAErD,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;QACxC,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,oBAAoB,CAAC,CAAC;QACtD,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IAEjD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAEhE,wCAAwC;QACxC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Show daemon status
3
+ */
4
+ export declare function status(): Promise<void>;
5
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAkC5C"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.status = status;
4
+ const config_1 = require("../config/config");
5
+ /**
6
+ * Show daemon status
7
+ */
8
+ async function status() {
9
+ if (!(0, config_1.isRegistered)()) {
10
+ console.log('Status: Not registered');
11
+ console.log('\nRun "cmdctrl-cursor-cli-daemon register" to register this device.');
12
+ return;
13
+ }
14
+ const config = (0, config_1.readConfig)();
15
+ const credentials = (0, config_1.readCredentials)();
16
+ const running = (0, config_1.isDaemonRunning)();
17
+ const pid = (0, config_1.readPidFile)();
18
+ console.log('Cursor CLI Daemon Status');
19
+ console.log('========================');
20
+ console.log(`Device Name: ${config.deviceName}`);
21
+ console.log(`Device ID: ${config.deviceId}`);
22
+ console.log(`Server: ${config.serverUrl}`);
23
+ console.log();
24
+ console.log(`Daemon: ${running ? `Running (PID ${pid})` : 'Stopped'}`);
25
+ if (credentials) {
26
+ const expiresIn = credentials.expiresAt - Date.now();
27
+ const expired = expiresIn <= 0;
28
+ console.log(`Token: ${expired ? 'Expired' : 'Valid'}`);
29
+ if (!expired) {
30
+ const hours = Math.floor(expiresIn / 1000 / 60 / 60);
31
+ const minutes = Math.floor((expiresIn / 1000 / 60) % 60);
32
+ console.log(`Expires in: ${hours}h ${minutes}m`);
33
+ }
34
+ }
35
+ if (!running) {
36
+ console.log('\nRun "cmdctrl-cursor-cli-daemon start" to start the daemon.');
37
+ }
38
+ }
39
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":";;AAWA,wBAkCC;AA7CD,6CAM0B;AAE1B;;GAEG;AACI,KAAK,UAAU,MAAM;IAC1B,IAAI,CAAC,IAAA,qBAAY,GAAE,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAC;QACnF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAG,CAAC;IAC7B,MAAM,WAAW,GAAG,IAAA,wBAAe,GAAE,CAAC;IACtC,MAAM,OAAO,GAAG,IAAA,wBAAe,GAAE,CAAC;IAClC,MAAM,GAAG,GAAG,IAAA,oBAAW,GAAE,CAAC;IAE1B,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,CAAC,CAAC,gBAAgB,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAE5E,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,SAAS,GAAG,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,SAAS,IAAI,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;YACzD,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,KAAK,OAAO,GAAG,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Stop the daemon
3
+ */
4
+ export declare function stop(): Promise<void>;
5
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAqC1C"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.stop = stop;
4
+ const config_1 = require("../config/config");
5
+ /**
6
+ * Stop the daemon
7
+ */
8
+ async function stop() {
9
+ if (!(0, config_1.isDaemonRunning)()) {
10
+ console.log('Daemon is not running.');
11
+ return;
12
+ }
13
+ const pid = (0, config_1.readPidFile)();
14
+ if (!pid) {
15
+ console.log('Could not find daemon PID.');
16
+ return;
17
+ }
18
+ console.log(`Stopping Cursor CLI daemon (PID ${pid})...`);
19
+ try {
20
+ // Send SIGTERM to gracefully shutdown
21
+ process.kill(pid, 'SIGTERM');
22
+ // Wait a bit for graceful shutdown
23
+ await new Promise(resolve => setTimeout(resolve, 1000));
24
+ // Check if still running
25
+ try {
26
+ process.kill(pid, 0);
27
+ // Still running, send SIGKILL
28
+ console.log('Daemon not responding, force killing...');
29
+ process.kill(pid, 'SIGKILL');
30
+ }
31
+ catch {
32
+ // Process is gone
33
+ }
34
+ (0, config_1.deletePidFile)();
35
+ console.log('Daemon stopped.');
36
+ }
37
+ catch (err) {
38
+ console.error('Failed to stop daemon:', err);
39
+ (0, config_1.deletePidFile)();
40
+ }
41
+ }
42
+ //# sourceMappingURL=stop.js.map