@cursorpool-dev/cli 0.5.6 → 0.5.9
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/node_modules/@cursor-pool/extension/dist/extension.js +1 -1
- package/node_modules/@cursor-pool/extension/package.json +3 -3
- package/node_modules/@cursor-pool/extension/src/api.ts +1 -1
- package/node_modules/@cursor-pool/extension/test/panel.test.ts +1 -1
- package/node_modules/@cursor-pool/patcher/package.json +2 -2
- package/node_modules/@cursor-pool/patcher/src/marker.ts +72 -3
- package/node_modules/@cursor-pool/patcher/src/workbenchAuthGateMarker.ts +128 -14
- package/node_modules/@cursor-pool/patcher/test/patchCursorAgentExec.test.ts +102 -7
- package/node_modules/@cursor-pool/patcher/test/patchCursorWorkbench.test.ts +193 -0
- package/node_modules/@cursor-pool/service/package.json +2 -2
- package/node_modules/@cursor-pool/service/src/server.ts +1 -0
- package/node_modules/@cursor-pool/service/test/server.test.ts +1 -0
- package/node_modules/@cursor-pool/shared/package.json +1 -1
- package/node_modules/@cursor-pool/shared/test/manifest.test.ts +6 -6
- package/node_modules/@esbuild/linux-x64/README.md +3 -0
- package/node_modules/@esbuild/linux-x64/bin/esbuild +0 -0
- package/node_modules/@esbuild/linux-x64/package.json +20 -0
- package/node_modules/esbuild/LICENSE.md +21 -0
- package/node_modules/esbuild/README.md +3 -0
- package/node_modules/esbuild/bin/esbuild +223 -0
- package/node_modules/esbuild/install.js +300 -0
- package/node_modules/esbuild/lib/main.d.ts +716 -0
- package/node_modules/esbuild/lib/main.js +2532 -0
- package/node_modules/esbuild/package.json +74 -0
- package/node_modules/tsx/LICENSE +21 -0
- package/node_modules/tsx/README.md +32 -0
- package/node_modules/tsx/dist/cjs/api/index.cjs +1 -0
- package/node_modules/tsx/dist/cjs/api/index.d.cts +35 -0
- package/node_modules/tsx/dist/cjs/api/index.d.mts +35 -0
- package/node_modules/tsx/dist/cjs/api/index.mjs +1 -0
- package/node_modules/tsx/dist/cjs/index.cjs +1 -0
- package/node_modules/tsx/dist/cjs/index.mjs +1 -0
- package/node_modules/tsx/dist/cli.cjs +54 -0
- package/node_modules/tsx/dist/cli.mjs +55 -0
- package/node_modules/tsx/dist/client-D3mGB526.cjs +1 -0
- package/node_modules/tsx/dist/client-D_mPDF5S.mjs +1 -0
- package/node_modules/tsx/dist/esm/api/index.cjs +1 -0
- package/node_modules/tsx/dist/esm/api/index.d.cts +35 -0
- package/node_modules/tsx/dist/esm/api/index.d.mts +35 -0
- package/node_modules/tsx/dist/esm/api/index.mjs +1 -0
- package/node_modules/tsx/dist/esm/index.cjs +1 -0
- package/node_modules/tsx/dist/esm/index.mjs +1 -0
- package/node_modules/tsx/dist/get-pipe-path-D4YM6rQt.cjs +1 -0
- package/node_modules/tsx/dist/get-pipe-path-_tAJyU_v.mjs +1 -0
- package/node_modules/tsx/dist/index-BWFBUo6r.cjs +1 -0
- package/node_modules/tsx/dist/index-D9F1FXzN.cjs +14 -0
- package/node_modules/tsx/dist/index-XurvG3JN.mjs +14 -0
- package/node_modules/tsx/dist/index-gbaejti9.mjs +1 -0
- package/node_modules/tsx/dist/lexer-DQCqS3nf.mjs +3 -0
- package/node_modules/tsx/dist/lexer-DgIbo0BU.cjs +3 -0
- package/node_modules/tsx/dist/loader.cjs +1 -0
- package/node_modules/tsx/dist/loader.mjs +1 -0
- package/node_modules/tsx/dist/node-features-B9BBLzwu.mjs +1 -0
- package/node_modules/tsx/dist/node-features-CQLdkVE6.cjs +1 -0
- package/node_modules/tsx/dist/package-CGdS2_oX.cjs +1 -0
- package/node_modules/tsx/dist/package-DyJMwVU5.mjs +1 -0
- package/node_modules/tsx/dist/patch-repl.cjs +1 -0
- package/node_modules/tsx/dist/patch-repl.mjs +1 -0
- package/node_modules/tsx/dist/preflight.cjs +1 -0
- package/node_modules/tsx/dist/preflight.mjs +1 -0
- package/node_modules/tsx/dist/register-BOkp8V6j.cjs +10 -0
- package/node_modules/tsx/dist/register-BnTWPeIB.mjs +10 -0
- package/node_modules/tsx/dist/register-CHVGxKtC.cjs +2 -0
- package/node_modules/tsx/dist/register-D_B8UL5H.mjs +2 -0
- package/node_modules/tsx/dist/repl.cjs +3 -0
- package/node_modules/tsx/dist/repl.mjs +3 -0
- package/node_modules/tsx/dist/require-CjvaJWEr.cjs +1 -0
- package/node_modules/tsx/dist/require-DzmC1hVr.mjs +1 -0
- package/node_modules/tsx/dist/suppress-warnings.cjs +1 -0
- package/node_modules/tsx/dist/suppress-warnings.mjs +1 -0
- package/node_modules/tsx/dist/temporary-directory-B83uKxJF.cjs +1 -0
- package/node_modules/tsx/dist/temporary-directory-BDDVQOvU.mjs +1 -0
- package/node_modules/tsx/dist/types-Cxp8y2TL.d.ts +5 -0
- package/node_modules/tsx/package.json +67 -0
- package/package.json +9 -6
- package/src/autostart.ts +5 -1
- package/src/compat.ts +103 -29
- package/src/cursor.ts +59 -3
- package/src/extensionBundle.ts +1 -1
- package/src/extensionLink.ts +3 -3
- package/src/install.ts +118 -19
- package/src/platform.ts +3 -3
- package/src/repair.ts +2 -1
- package/src/serviceProcess.ts +2 -1
- package/src/trial.ts +2 -2
- package/test/autostart.test.ts +23 -2
- package/test/compat.test.ts +108 -9
- package/test/cursor-pool-bin.test.ts +1 -0
- package/test/cursor.test.ts +60 -1
- package/test/extensionLink.test.ts +24 -1
- package/test/install.test.ts +127 -2
- package/test/serviceProcess.test.ts +10 -1
- package/test/trial.test.ts +15 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
2
|
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
4
|
+
import { isAbsolute, join, relative } from 'node:path';
|
|
5
5
|
import test from 'node:test';
|
|
6
6
|
import {
|
|
7
7
|
getLinkedExtensionState,
|
|
@@ -123,6 +123,29 @@ test('linkExtensionBundle refreshes Cursor extensions index with runtime extensi
|
|
|
123
123
|
}
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
+
test('linkExtensionBundle writes an absolute linked extension location for relative cursor extensions dir', async () => {
|
|
127
|
+
const tempDir = await mkdtemp(join(process.cwd(), '.cursor-pool-extension-link-relative-'));
|
|
128
|
+
const sourceBundlePath = await createSourceBundle(tempDir);
|
|
129
|
+
const cursorExtensionsDir = join(tempDir, 'Extensions');
|
|
130
|
+
const relativeCursorExtensionsDir = relative(process.cwd(), cursorExtensionsDir);
|
|
131
|
+
await mkdir(cursorExtensionsDir, { recursive: true });
|
|
132
|
+
await writeFile(join(cursorExtensionsDir, 'extensions.json'), '[]\n', 'utf8');
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const result = await linkExtensionBundle({
|
|
136
|
+
sourceBundlePath,
|
|
137
|
+
cursorExtensionsDir: relativeCursorExtensionsDir,
|
|
138
|
+
});
|
|
139
|
+
const index = JSON.parse(await readFile(join(cursorExtensionsDir, 'extensions.json'), 'utf8'));
|
|
140
|
+
|
|
141
|
+
assert.equal(isAbsolute(result.linkedPath), true);
|
|
142
|
+
assert.equal(isAbsolute(index.at(-1).location.path), true);
|
|
143
|
+
assert.equal(index.at(-1).location.path, result.linkedPath);
|
|
144
|
+
} finally {
|
|
145
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
126
149
|
test('linkExtensionBundle reports missing when source bundle is absent', async () => {
|
|
127
150
|
const tempDir = await mkdtemp(join(tmpdir(), 'cursor-pool-extension-link-missing-'));
|
|
128
151
|
const cursorExtensionsDir = join(tempDir, 'Extensions');
|
package/test/install.test.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
2
|
import { createHash } from 'node:crypto';
|
|
3
|
-
import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
import test from 'node:test';
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
CURSOR_POOL_AGENT_EXEC_PROVIDER_REGISTER_ANCHOR,
|
|
9
9
|
CURSOR_POOL_PATCH_MARKER,
|
|
10
10
|
} from '../../patcher/src/marker';
|
|
11
|
-
import { writeRuntimeInfo } from '../../service/src/runtime';
|
|
11
|
+
import { readRuntimeInfo, writeRuntimeInfo } from '../../service/src/runtime';
|
|
12
12
|
import type { CompatibilityManifestEntry } from '../../shared/src/manifest';
|
|
13
13
|
import { buildCompatManifestSignature } from '../src/compat';
|
|
14
14
|
import { getExtensionState } from '../src/extensionBundle';
|
|
@@ -225,6 +225,7 @@ test('install reports Cursor version, simulated extension, service, patch, and h
|
|
|
225
225
|
|
|
226
226
|
test('install detects Linux Cursor AppImage layout under usr/share/cursor', async () => {
|
|
227
227
|
const fixture = await createLinuxFixtureApp();
|
|
228
|
+
const launcherFile = join(fixture.tempDir, 'bin/cursor-pool-cursor');
|
|
228
229
|
|
|
229
230
|
try {
|
|
230
231
|
const output = await install({
|
|
@@ -235,14 +236,20 @@ test('install detects Linux Cursor AppImage layout under usr/share/cursor', asyn
|
|
|
235
236
|
backupDir: fixture.backupDir,
|
|
236
237
|
trialRecordDir: join(fixture.tempDir, 'trials'),
|
|
237
238
|
extensionInstallPath: join(fixture.tempDir, 'extensions/cursor-pool-status'),
|
|
239
|
+
linuxLauncherFile: launcherFile,
|
|
238
240
|
compatEntries: [fixture.compatEntry],
|
|
239
241
|
stopServiceAfterInstall: true,
|
|
240
242
|
});
|
|
241
243
|
|
|
242
244
|
assert.match(output, /Cursor 3\.6\.31/);
|
|
243
245
|
assert.match(output, /patch: applied/);
|
|
246
|
+
assert.match(output, /launcher: .*cursor-pool-cursor/);
|
|
244
247
|
assert.match(output, /health: ok/);
|
|
245
248
|
assert.match(await readFile(fixture.targetPath, 'utf8'), new RegExp(CURSOR_POOL_PATCH_MARKER));
|
|
249
|
+
const launcher = await readFile(launcherFile, 'utf8');
|
|
250
|
+
assert.match(launcher, /AppRun/);
|
|
251
|
+
assert.match(launcher, /--no-sandbox/);
|
|
252
|
+
assert.equal((await stat(launcherFile)).mode & 0o111, 0o111);
|
|
246
253
|
} finally {
|
|
247
254
|
await rm(fixture.tempDir, { recursive: true, force: true });
|
|
248
255
|
}
|
|
@@ -350,6 +357,124 @@ test('install persists API base URL and installs user autostart for real client
|
|
|
350
357
|
}
|
|
351
358
|
});
|
|
352
359
|
|
|
360
|
+
test('Linux real install falls back to user systemd when detached service startup is unhealthy', async () => {
|
|
361
|
+
const fixture = await createLinuxFixtureApp();
|
|
362
|
+
const configFile = join(fixture.tempDir, 'client-config.json');
|
|
363
|
+
const cursorExtensionsDir = join(fixture.tempDir, 'real-extensions');
|
|
364
|
+
const installRecordFile = join(fixture.tempDir, 'install.json');
|
|
365
|
+
const launcherFile = join(fixture.tempDir, 'bin/cursor-pool-cursor');
|
|
366
|
+
const calls: string[] = [];
|
|
367
|
+
|
|
368
|
+
try {
|
|
369
|
+
const output = await install({
|
|
370
|
+
realAppPath: fixture.appPath,
|
|
371
|
+
yes: true,
|
|
372
|
+
platform: 'linux',
|
|
373
|
+
arch: process.arch,
|
|
374
|
+
runtimeFile: fixture.runtimeFile,
|
|
375
|
+
backupDir: fixture.backupDir,
|
|
376
|
+
installRecordFile,
|
|
377
|
+
cursorExtensionsDir,
|
|
378
|
+
clientConfigFile: configFile,
|
|
379
|
+
linuxLauncherFile: launcherFile,
|
|
380
|
+
compatEntries: [fixture.compatEntry],
|
|
381
|
+
startDetachedService: async () => {
|
|
382
|
+
calls.push('detached');
|
|
383
|
+
throw new Error('Detached service failed to become healthy');
|
|
384
|
+
},
|
|
385
|
+
installUserAutostart: async (options) => {
|
|
386
|
+
calls.push('autostart');
|
|
387
|
+
await writeRuntimeInfo(
|
|
388
|
+
{ host: '127.0.0.1', port: 56393, runtimeId: 'systemd-runtime' },
|
|
389
|
+
{ runtimeFile: options.runtimeFile },
|
|
390
|
+
);
|
|
391
|
+
return { state: 'installed' as const };
|
|
392
|
+
},
|
|
393
|
+
fetchHealth: async (url) => {
|
|
394
|
+
calls.push(`health:${url}`);
|
|
395
|
+
return { ok: true, healthy: true };
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
assert.deepEqual(calls, [
|
|
400
|
+
'detached',
|
|
401
|
+
'autostart',
|
|
402
|
+
'health:http://127.0.0.1:56393/health',
|
|
403
|
+
'health:http://127.0.0.1:56393/health',
|
|
404
|
+
]);
|
|
405
|
+
assert.match(output, /mode: real/);
|
|
406
|
+
assert.match(output, /service: running 127\.0\.0\.1:56393/);
|
|
407
|
+
assert.match(output, /autostart: installed/);
|
|
408
|
+
assert.match(output, /health: ok/);
|
|
409
|
+
assert.deepEqual(await readRuntimeInfo({ runtimeFile: fixture.runtimeFile }), {
|
|
410
|
+
host: '127.0.0.1',
|
|
411
|
+
port: 56393,
|
|
412
|
+
runtimeId: 'systemd-runtime',
|
|
413
|
+
});
|
|
414
|
+
} finally {
|
|
415
|
+
await rm(fixture.tempDir, { recursive: true, force: true });
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
test('Linux real install waits for delayed user systemd runtime during fallback', async () => {
|
|
420
|
+
const fixture = await createLinuxFixtureApp();
|
|
421
|
+
const configFile = join(fixture.tempDir, 'client-config.json');
|
|
422
|
+
const cursorExtensionsDir = join(fixture.tempDir, 'real-extensions');
|
|
423
|
+
const installRecordFile = join(fixture.tempDir, 'install.json');
|
|
424
|
+
const launcherFile = join(fixture.tempDir, 'bin/cursor-pool-cursor');
|
|
425
|
+
const calls: string[] = [];
|
|
426
|
+
|
|
427
|
+
try {
|
|
428
|
+
const output = await install({
|
|
429
|
+
realAppPath: fixture.appPath,
|
|
430
|
+
yes: true,
|
|
431
|
+
platform: 'linux',
|
|
432
|
+
arch: process.arch,
|
|
433
|
+
runtimeFile: fixture.runtimeFile,
|
|
434
|
+
backupDir: fixture.backupDir,
|
|
435
|
+
installRecordFile,
|
|
436
|
+
cursorExtensionsDir,
|
|
437
|
+
clientConfigFile: configFile,
|
|
438
|
+
linuxLauncherFile: launcherFile,
|
|
439
|
+
compatEntries: [fixture.compatEntry],
|
|
440
|
+
startDetachedService: async () => {
|
|
441
|
+
calls.push('detached');
|
|
442
|
+
throw new Error('Detached service failed to become healthy');
|
|
443
|
+
},
|
|
444
|
+
installUserAutostart: async (options) => {
|
|
445
|
+
calls.push('autostart');
|
|
446
|
+
setTimeout(() => {
|
|
447
|
+
void writeRuntimeInfo(
|
|
448
|
+
{ host: '127.0.0.1', port: 56394, runtimeId: 'delayed-systemd-runtime' },
|
|
449
|
+
{ runtimeFile: options.runtimeFile },
|
|
450
|
+
);
|
|
451
|
+
}, 100);
|
|
452
|
+
return { state: 'installed' as const };
|
|
453
|
+
},
|
|
454
|
+
fetchHealth: async (url) => {
|
|
455
|
+
calls.push(`health:${url}`);
|
|
456
|
+
return { ok: true, healthy: true };
|
|
457
|
+
},
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
assert.match(output, /service: running 127\.0\.0\.1:56394/);
|
|
461
|
+
assert.match(output, /autostart: installed/);
|
|
462
|
+
assert.match(output, /health: ok/);
|
|
463
|
+
assert.deepEqual(await readRuntimeInfo({ runtimeFile: fixture.runtimeFile }), {
|
|
464
|
+
host: '127.0.0.1',
|
|
465
|
+
port: 56394,
|
|
466
|
+
runtimeId: 'delayed-systemd-runtime',
|
|
467
|
+
});
|
|
468
|
+
assert.deepEqual(calls.slice(0, 3), [
|
|
469
|
+
'detached',
|
|
470
|
+
'autostart',
|
|
471
|
+
'health:http://127.0.0.1:56394/health',
|
|
472
|
+
]);
|
|
473
|
+
} finally {
|
|
474
|
+
await rm(fixture.tempDir, { recursive: true, force: true });
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
|
|
353
478
|
test('real-mode install writes install record and reports real mode', async () => {
|
|
354
479
|
const fixture = await createFixtureApp();
|
|
355
480
|
const installRecordFile = join(fixture.tempDir, 'install.json');
|
|
@@ -6,10 +6,19 @@ import { fileURLToPath } from 'node:url';
|
|
|
6
6
|
import test from 'node:test';
|
|
7
7
|
import { readRuntimeInfo } from '../../service/src/runtime';
|
|
8
8
|
import { startServer } from '../../service/src/server';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
DEFAULT_DETACHED_SERVICE_STARTUP_TIMEOUT_MS,
|
|
11
|
+
startDetachedService,
|
|
12
|
+
stopRuntimeService,
|
|
13
|
+
waitForRuntimeHealth,
|
|
14
|
+
} from '../src/serviceProcess';
|
|
10
15
|
|
|
11
16
|
const cliRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
12
17
|
|
|
18
|
+
test('default detached service startup timeout allows slow Linux VMs', () => {
|
|
19
|
+
assert.equal(DEFAULT_DETACHED_SERVICE_STARTUP_TIMEOUT_MS, 30_000);
|
|
20
|
+
});
|
|
21
|
+
|
|
13
22
|
test('startDetachedService starts a service discoverable by runtime file', async () => {
|
|
14
23
|
const tempDir = await mkdtemp(join(tmpdir(), 'cursor-pool-detached-service-'));
|
|
15
24
|
const runtimeFile = join(tempDir, 'runtime.json');
|
package/test/trial.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from 'node:assert/strict';
|
|
2
2
|
import { mkdir, mkdtemp, readFile, rm, symlink } from 'node:fs/promises';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
4
|
+
import { join, relative, resolve } from 'node:path';
|
|
5
5
|
import test from 'node:test';
|
|
6
6
|
import {
|
|
7
7
|
assertDisposableCursorAppPath,
|
|
@@ -55,6 +55,20 @@ test('assertDisposableCursorAppPath accepts a disposable app copy path', () => {
|
|
|
55
55
|
);
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
+
test('assertDisposableCursorAppPath normalizes relative disposable app paths to absolute paths', async () => {
|
|
59
|
+
const tempDir = await mkdtemp(join(process.cwd(), '.cursor-pool-relative-app-path-'));
|
|
60
|
+
const appPath = join(tempDir, 'Cursor-Trial.app');
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
await mkdir(appPath, { recursive: true });
|
|
64
|
+
const relativeAppPath = relative(process.cwd(), appPath);
|
|
65
|
+
|
|
66
|
+
assert.equal(assertDisposableCursorAppPath(relativeAppPath), resolve(appPath));
|
|
67
|
+
} finally {
|
|
68
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
|
|
58
72
|
test('assertDisposableCursorAppPath rejects non app bundle paths', () => {
|
|
59
73
|
assert.throws(
|
|
60
74
|
() => assertDisposableCursorAppPath('/Users/example/Desktop/Cursor-Pool-Trial'),
|