@cursorpool-dev/cli 0.5.6
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/bin/cursor-pool.mjs +9 -0
- package/bin/cursor-pool.ts +169 -0
- package/node_modules/@cursor-pool/extension/dist/extension.js +2910 -0
- package/node_modules/@cursor-pool/extension/package.json +64 -0
- package/node_modules/@cursor-pool/extension/resources/cursor-pool.svg +6 -0
- package/node_modules/@cursor-pool/extension/src/api.ts +545 -0
- package/node_modules/@cursor-pool/extension/src/extension.ts +104 -0
- package/node_modules/@cursor-pool/extension/src/index.ts +1 -0
- package/node_modules/@cursor-pool/extension/src/panel.ts +569 -0
- package/node_modules/@cursor-pool/extension/src/runtime.ts +22 -0
- package/node_modules/@cursor-pool/extension/test/panel.test.ts +1785 -0
- package/node_modules/@cursor-pool/patcher/package.json +17 -0
- package/node_modules/@cursor-pool/patcher/src/alwaysLocalMarker.ts +86 -0
- package/node_modules/@cursor-pool/patcher/src/hash.ts +7 -0
- package/node_modules/@cursor-pool/patcher/src/index.ts +55 -0
- package/node_modules/@cursor-pool/patcher/src/marker.ts +159 -0
- package/node_modules/@cursor-pool/patcher/src/patchCursorAgentExec.ts +154 -0
- package/node_modules/@cursor-pool/patcher/src/patchCursorAlwaysLocal.ts +142 -0
- package/node_modules/@cursor-pool/patcher/src/patchCursorWorkbenchAuthGate.ts +140 -0
- package/node_modules/@cursor-pool/patcher/src/restoreCursorAgentExec.ts +52 -0
- package/node_modules/@cursor-pool/patcher/src/restoreCursorAlwaysLocal.ts +52 -0
- package/node_modules/@cursor-pool/patcher/src/restoreCursorWorkbenchAuthGate.ts +70 -0
- package/node_modules/@cursor-pool/patcher/src/workbenchAuthGateMarker.ts +243 -0
- package/node_modules/@cursor-pool/patcher/test/patchCursorAgentExec.test.ts +630 -0
- package/node_modules/@cursor-pool/patcher/test/patchCursorAlwaysLocal.test.ts +144 -0
- package/node_modules/@cursor-pool/patcher/test/patchCursorWorkbench.test.ts +770 -0
- package/node_modules/@cursor-pool/patcher/test/restoreCursorAgentExec.test.ts +139 -0
- package/node_modules/@cursor-pool/service/package.json +17 -0
- package/node_modules/@cursor-pool/service/src/canary.ts +61 -0
- package/node_modules/@cursor-pool/service/src/diagnostics.ts +385 -0
- package/node_modules/@cursor-pool/service/src/entry.ts +161 -0
- package/node_modules/@cursor-pool/service/src/health.ts +10 -0
- package/node_modules/@cursor-pool/service/src/index.ts +29 -0
- package/node_modules/@cursor-pool/service/src/metadata.ts +22 -0
- package/node_modules/@cursor-pool/service/src/platformSession.ts +1178 -0
- package/node_modules/@cursor-pool/service/src/requestCheck.ts +81 -0
- package/node_modules/@cursor-pool/service/src/requestGate.ts +100 -0
- package/node_modules/@cursor-pool/service/src/requestGateway.ts +441 -0
- package/node_modules/@cursor-pool/service/src/runtime.ts +48 -0
- package/node_modules/@cursor-pool/service/src/server.ts +939 -0
- package/node_modules/@cursor-pool/service/src/takeover.ts +111 -0
- package/node_modules/@cursor-pool/service/test/canary.test.ts +140 -0
- package/node_modules/@cursor-pool/service/test/diagnostics.test.ts +506 -0
- package/node_modules/@cursor-pool/service/test/metadata.test.ts +63 -0
- package/node_modules/@cursor-pool/service/test/platformSession.test.ts +2428 -0
- package/node_modules/@cursor-pool/service/test/requestCheck.test.ts +152 -0
- package/node_modules/@cursor-pool/service/test/requestGate.test.ts +207 -0
- package/node_modules/@cursor-pool/service/test/requestGateway.test.ts +466 -0
- package/node_modules/@cursor-pool/service/test/runtime.test.ts +47 -0
- package/node_modules/@cursor-pool/service/test/server.test.ts +2570 -0
- package/node_modules/@cursor-pool/shared/package.json +17 -0
- package/node_modules/@cursor-pool/shared/src/clientConfig.ts +49 -0
- package/node_modules/@cursor-pool/shared/src/index.ts +14 -0
- package/node_modules/@cursor-pool/shared/src/manifest.ts +36 -0
- package/node_modules/@cursor-pool/shared/src/metadata.ts +19 -0
- package/node_modules/@cursor-pool/shared/src/paths.ts +5 -0
- package/node_modules/@cursor-pool/shared/src/runtime.ts +3 -0
- package/node_modules/@cursor-pool/shared/test/index.test.ts +56 -0
- package/node_modules/@cursor-pool/shared/test/manifest.test.ts +65 -0
- package/node_modules/@cursor-pool/shared/test/metadata.test.ts +25 -0
- package/node_modules/@cursor-pool/shared/test/runtime.test.ts +8 -0
- package/package.json +28 -0
- package/src/adHocResign.ts +65 -0
- package/src/autostart.ts +240 -0
- package/src/compat.ts +282 -0
- package/src/confirm.ts +76 -0
- package/src/cursor.ts +94 -0
- package/src/diagnostics.ts +558 -0
- package/src/environment.ts +18 -0
- package/src/extensionBundle.ts +111 -0
- package/src/extensionLink.ts +168 -0
- package/src/index.ts +23 -0
- package/src/install.ts +614 -0
- package/src/installRecord.ts +105 -0
- package/src/launch.ts +182 -0
- package/src/patchSet.ts +182 -0
- package/src/platform.ts +132 -0
- package/src/repair.ts +383 -0
- package/src/restore.ts +153 -0
- package/src/serviceCommands.ts +79 -0
- package/src/serviceProcess.ts +188 -0
- package/src/status.ts +241 -0
- package/src/target.ts +37 -0
- package/src/trial.ts +133 -0
- package/src/uninstall.ts +213 -0
- package/test/autostart.test.ts +151 -0
- package/test/compat.test.ts +192 -0
- package/test/confirm.test.ts +114 -0
- package/test/cursor-pool-bin.test.ts +658 -0
- package/test/cursor.test.ts +20 -0
- package/test/diagnostics.test.ts +709 -0
- package/test/e2e-install.test.ts +773 -0
- package/test/extensionBundle.test.ts +161 -0
- package/test/extensionLink.test.ts +209 -0
- package/test/install.test.ts +862 -0
- package/test/installRecord.test.ts +107 -0
- package/test/launch.test.ts +138 -0
- package/test/platform.test.ts +226 -0
- package/test/repair.test.ts +575 -0
- package/test/restore.test.ts +211 -0
- package/test/serviceCommands.test.ts +135 -0
- package/test/serviceProcess.test.ts +280 -0
- package/test/status.test.ts +615 -0
- package/test/target.test.ts +49 -0
- package/test/trial.test.ts +146 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname } from 'node:path';
|
|
4
|
+
import { readRuntimeInfo, resolveRuntimeFile, type RuntimeInfo } from './runtime';
|
|
5
|
+
import { startServer } from './server';
|
|
6
|
+
|
|
7
|
+
function readOption(args: string[], name: string) {
|
|
8
|
+
const index = args.indexOf(name);
|
|
9
|
+
return index === -1 ? undefined : args[index + 1];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const runtimeFile = readOption(process.argv.slice(2), '--runtime-file');
|
|
13
|
+
const clientConfigFile = readOption(process.argv.slice(2), '--config-file');
|
|
14
|
+
let activeService: Awaited<ReturnType<typeof startServer>> | undefined;
|
|
15
|
+
let releaseStartLock: (() => Promise<void>) | undefined;
|
|
16
|
+
const keepAlive = setInterval(() => {}, 2 ** 30);
|
|
17
|
+
|
|
18
|
+
function delay(ms: number) {
|
|
19
|
+
return new Promise((resolveDelay) => setTimeout(resolveDelay, ms));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function fetchRuntimeHealth(runtime: RuntimeInfo | null) {
|
|
23
|
+
if (!runtime) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
const response = await fetch(`http://${runtime.host}:${runtime.port}/health`);
|
|
29
|
+
const health = (await response.json()) as { ok?: unknown; runtimeId?: unknown };
|
|
30
|
+
return response.ok && health.ok === true && health.runtimeId === runtime.runtimeId;
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function readLockPid(lockDir: string) {
|
|
37
|
+
try {
|
|
38
|
+
const pid = Number(await readFile(`${lockDir}/owner.json`, 'utf8').then((content) => JSON.parse(content).pid));
|
|
39
|
+
return Number.isInteger(pid) && pid > 0 ? pid : null;
|
|
40
|
+
} catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function isProcessAlive(pid: number) {
|
|
46
|
+
try {
|
|
47
|
+
process.kill(pid, 0);
|
|
48
|
+
return true;
|
|
49
|
+
} catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function waitForHealthyRuntime(resolvedRuntimeFile: string, timeoutMs = 5000) {
|
|
55
|
+
const startedAt = Date.now();
|
|
56
|
+
while (Date.now() - startedAt < timeoutMs) {
|
|
57
|
+
const runtime = await readRuntimeInfo({ runtimeFile: resolvedRuntimeFile });
|
|
58
|
+
if (await fetchRuntimeHealth(runtime)) {
|
|
59
|
+
return runtime;
|
|
60
|
+
}
|
|
61
|
+
await delay(50);
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function acquireStartLock(resolvedRuntimeFile: string) {
|
|
67
|
+
const lockDir = `${resolvedRuntimeFile}.start.lock`;
|
|
68
|
+
const startedAt = Date.now();
|
|
69
|
+
|
|
70
|
+
for (;;) {
|
|
71
|
+
const existingRuntime = await readRuntimeInfo({ runtimeFile: resolvedRuntimeFile });
|
|
72
|
+
if (await fetchRuntimeHealth(existingRuntime)) {
|
|
73
|
+
return { release: null, runtime: existingRuntime };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
await mkdir(lockDir, { recursive: false });
|
|
78
|
+
await writeFile(
|
|
79
|
+
`${lockDir}/owner.json`,
|
|
80
|
+
`${JSON.stringify({ pid: process.pid, createdAt: new Date().toISOString() })}\n`,
|
|
81
|
+
'utf8',
|
|
82
|
+
);
|
|
83
|
+
return {
|
|
84
|
+
release: async () => {
|
|
85
|
+
await rm(lockDir, { recursive: true, force: true });
|
|
86
|
+
},
|
|
87
|
+
runtime: null,
|
|
88
|
+
};
|
|
89
|
+
} catch (error) {
|
|
90
|
+
if ((error as NodeJS.ErrnoException).code !== 'EEXIST') {
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const ownerPid = await readLockPid(lockDir);
|
|
95
|
+
if (ownerPid !== null && !isProcessAlive(ownerPid)) {
|
|
96
|
+
await rm(lockDir, { recursive: true, force: true });
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const runtime = await waitForHealthyRuntime(resolvedRuntimeFile, 250);
|
|
101
|
+
if (runtime) {
|
|
102
|
+
return { release: null, runtime };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (Date.now() - startedAt > 5000) {
|
|
106
|
+
throw new Error(`another Cursor Pool service is still starting for ${resolvedRuntimeFile}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function writeRuntime(runtime: RuntimeInfo) {
|
|
113
|
+
process.stdout.write(`${JSON.stringify(runtime)}\n`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async function main() {
|
|
117
|
+
const resolvedRuntimeFile = resolveRuntimeFile(runtimeFile);
|
|
118
|
+
await mkdir(dirname(resolvedRuntimeFile), { recursive: true });
|
|
119
|
+
|
|
120
|
+
const lock = await acquireStartLock(resolvedRuntimeFile);
|
|
121
|
+
if (lock.runtime) {
|
|
122
|
+
writeRuntime(lock.runtime);
|
|
123
|
+
clearInterval(keepAlive);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
releaseStartLock = lock.release ?? undefined;
|
|
128
|
+
try {
|
|
129
|
+
const service = await startServer({
|
|
130
|
+
runtimeFile: resolvedRuntimeFile,
|
|
131
|
+
clientConfigFile,
|
|
132
|
+
onShutdown() {
|
|
133
|
+
clearInterval(keepAlive);
|
|
134
|
+
process.exit(0);
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
activeService = service;
|
|
138
|
+
writeRuntime({
|
|
139
|
+
host: service.host,
|
|
140
|
+
port: service.port,
|
|
141
|
+
runtimeId: service.runtimeId,
|
|
142
|
+
});
|
|
143
|
+
} finally {
|
|
144
|
+
await releaseStartLock?.();
|
|
145
|
+
releaseStartLock = undefined;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
main().catch((error) => {
|
|
150
|
+
process.stderr.write(`${(error as Error).message}\n`);
|
|
151
|
+
clearInterval(keepAlive);
|
|
152
|
+
process.exitCode = 1;
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
process.once('SIGTERM', () => {
|
|
156
|
+
void activeService?.stop().finally(async () => {
|
|
157
|
+
await releaseStartLock?.();
|
|
158
|
+
clearInterval(keepAlive);
|
|
159
|
+
process.exit(0);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const packageRole = 'service';
|
|
2
|
+
export { buildHealth } from './health';
|
|
3
|
+
export { sanitizeExtensionStatus, sanitizeServiceMetadata } from './metadata';
|
|
4
|
+
export {
|
|
5
|
+
DEFAULT_PLATFORM_SESSION_FILE,
|
|
6
|
+
loginWithPassword,
|
|
7
|
+
loginWithCode,
|
|
8
|
+
logoutPlatform,
|
|
9
|
+
platformStatus,
|
|
10
|
+
resolvePlatformSessionFile,
|
|
11
|
+
sendHeartbeat,
|
|
12
|
+
} from './platformSession';
|
|
13
|
+
export type {
|
|
14
|
+
HeartbeatPayload,
|
|
15
|
+
LoginWithPasswordOptions,
|
|
16
|
+
LoginWithCodeOptions,
|
|
17
|
+
LogoutPlatformOptions,
|
|
18
|
+
PlatformDeviceInput,
|
|
19
|
+
PlatformDeviceSummary,
|
|
20
|
+
PlatformSession,
|
|
21
|
+
PlatformSessionOptions,
|
|
22
|
+
PlatformStatus,
|
|
23
|
+
PlatformUserSummary,
|
|
24
|
+
SendHeartbeatOptions,
|
|
25
|
+
} from './platformSession';
|
|
26
|
+
export { readRuntimeInfo, resolveRuntimeFile, writeRuntimeInfo } from './runtime';
|
|
27
|
+
export { createRequestCheckStore, sanitizeAgentRequestCheck } from './requestCheck';
|
|
28
|
+
export type { AgentRequestCheck, AgentRequestCheckInput } from './requestCheck';
|
|
29
|
+
export { startServer } from './server';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { sanitizeRequestMetadata } from '@cursor-pool/shared/metadata';
|
|
2
|
+
|
|
3
|
+
const EXTENSION_STATUS_KEYS = ['connected', 'cursorVersion', 'clientVersion'] as const;
|
|
4
|
+
|
|
5
|
+
export type ServiceMetadata = Record<string, unknown>;
|
|
6
|
+
|
|
7
|
+
export function sanitizeServiceMetadata(input: Record<string, unknown>): ServiceMetadata {
|
|
8
|
+
return {
|
|
9
|
+
model: 'unknown',
|
|
10
|
+
...sanitizeRequestMetadata(input),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function sanitizeExtensionStatus(input: Record<string, unknown>): Record<string, unknown> {
|
|
15
|
+
const output: Record<string, unknown> = {};
|
|
16
|
+
for (const key of EXTENSION_STATUS_KEYS) {
|
|
17
|
+
if (input[key] !== undefined) {
|
|
18
|
+
output[key] = input[key];
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return output;
|
|
22
|
+
}
|