@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,168 @@
|
|
|
1
|
+
import { cp, mkdtemp, mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
4
|
+
import { resolveExtensionInstallPath } from './extensionBundle';
|
|
5
|
+
import type { ExtensionState } from './trial';
|
|
6
|
+
|
|
7
|
+
export const LINKED_EXTENSION_DIRNAME = 'cursor-pool.extension-0.5.6';
|
|
8
|
+
const RUNTIME_EXTENSION_ID = 'cursor-pool.cursorpool';
|
|
9
|
+
const STALE_EXTENSION_IDS = new Set([
|
|
10
|
+
RUNTIME_EXTENSION_ID,
|
|
11
|
+
'keg1255.cursorpool',
|
|
12
|
+
'cursor-pool.@cursor-pool/extension',
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
export type LinkedExtensionState = Extract<ExtensionState, 'linked' | 'missing'>;
|
|
16
|
+
|
|
17
|
+
export type LinkExtensionBundleOptions = {
|
|
18
|
+
sourceBundlePath: string;
|
|
19
|
+
cursorExtensionsDir: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type LinkExtensionBundleResult = {
|
|
23
|
+
state: LinkedExtensionState;
|
|
24
|
+
linkedPath: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type LinkedExtensionSnapshot = {
|
|
28
|
+
root: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
async function exists(path: string) {
|
|
32
|
+
try {
|
|
33
|
+
await stat(path);
|
|
34
|
+
return true;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async function readRuntimeManifest(linkedPath: string) {
|
|
44
|
+
const manifest = JSON.parse(await readFile(join(linkedPath, 'package.json'), 'utf8')) as {
|
|
45
|
+
publisher?: unknown;
|
|
46
|
+
name?: unknown;
|
|
47
|
+
version?: unknown;
|
|
48
|
+
};
|
|
49
|
+
const publisher = typeof manifest.publisher === 'string' ? manifest.publisher : 'cursor-pool';
|
|
50
|
+
const name = typeof manifest.name === 'string' ? manifest.name : 'cursorpool';
|
|
51
|
+
const version = typeof manifest.version === 'string' ? manifest.version : '0.5.6';
|
|
52
|
+
return { id: `${publisher}.${name}`, version };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function refreshCursorExtensionsIndex(cursorExtensionsDir: string, linkedPath: string) {
|
|
56
|
+
const indexPath = join(resolveExtensionInstallPath(cursorExtensionsDir), 'extensions.json');
|
|
57
|
+
if (!(await exists(indexPath))) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const entries = JSON.parse(await readFile(indexPath, 'utf8')) as Array<{
|
|
62
|
+
identifier?: { id?: string };
|
|
63
|
+
relativeLocation?: string;
|
|
64
|
+
}>;
|
|
65
|
+
const manifest = await readRuntimeManifest(linkedPath);
|
|
66
|
+
const nextEntries = entries.filter((entry) => {
|
|
67
|
+
const id = entry.identifier?.id;
|
|
68
|
+
return (
|
|
69
|
+
!STALE_EXTENSION_IDS.has(id ?? '') &&
|
|
70
|
+
entry.relativeLocation !== LINKED_EXTENSION_DIRNAME &&
|
|
71
|
+
entry.relativeLocation !== 'keg1255.cursorpool-1.0.52'
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
nextEntries.push({
|
|
76
|
+
identifier: { id: manifest.id },
|
|
77
|
+
location: {
|
|
78
|
+
$mid: 1,
|
|
79
|
+
path: linkedPath,
|
|
80
|
+
scheme: 'file',
|
|
81
|
+
},
|
|
82
|
+
relativeLocation: LINKED_EXTENSION_DIRNAME,
|
|
83
|
+
version: manifest.version,
|
|
84
|
+
});
|
|
85
|
+
await writeFile(indexPath, `${JSON.stringify(nextEntries, null, 2)}\n`, 'utf8');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function assertSafeLinkedExtensionPath(linkedPath: string) {
|
|
89
|
+
const resolvedLinkedPath = resolve(linkedPath);
|
|
90
|
+
const parentSegments = dirname(resolvedLinkedPath).split(/[\\/]+/).filter(Boolean);
|
|
91
|
+
const hasExtensionsParent = parentSegments.some(
|
|
92
|
+
(segment) => segment === 'extensions' || segment === 'Extensions',
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
if (basename(resolvedLinkedPath) !== LINKED_EXTENSION_DIRNAME || !hasExtensionsParent) {
|
|
96
|
+
throw new Error(
|
|
97
|
+
`Unsafe linked extension path for recursive removal: ${linkedPath}. Expected an extensions/${LINKED_EXTENSION_DIRNAME} bundle path.`,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function linkedExtensionPathForDir(cursorExtensionsDir: string) {
|
|
103
|
+
return join(resolveExtensionInstallPath(cursorExtensionsDir), LINKED_EXTENSION_DIRNAME);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export async function getLinkedExtensionState(linkedPath: string | undefined): Promise<LinkedExtensionState> {
|
|
107
|
+
if (!linkedPath) {
|
|
108
|
+
return 'missing';
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const resolvedLinkedPath = resolveExtensionInstallPath(linkedPath);
|
|
112
|
+
const manifestPath = join(resolvedLinkedPath, 'package.json');
|
|
113
|
+
const entryPath = join(resolvedLinkedPath, 'dist/extension.js');
|
|
114
|
+
return (await exists(manifestPath)) && (await exists(entryPath)) ? 'linked' : 'missing';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export async function linkExtensionBundle({
|
|
118
|
+
sourceBundlePath,
|
|
119
|
+
cursorExtensionsDir,
|
|
120
|
+
}: LinkExtensionBundleOptions): Promise<LinkExtensionBundleResult> {
|
|
121
|
+
const resolvedSourceBundlePath = resolveExtensionInstallPath(sourceBundlePath);
|
|
122
|
+
const linkedPath = linkedExtensionPathForDir(cursorExtensionsDir);
|
|
123
|
+
|
|
124
|
+
if ((await getLinkedExtensionState(resolvedSourceBundlePath)) === 'missing') {
|
|
125
|
+
return { state: 'missing', linkedPath };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
await removeLinkedExtensionBundle(linkedPath);
|
|
129
|
+
await mkdir(dirname(linkedPath), { recursive: true });
|
|
130
|
+
await cp(resolvedSourceBundlePath, linkedPath, { recursive: true });
|
|
131
|
+
await refreshCursorExtensionsIndex(cursorExtensionsDir, linkedPath);
|
|
132
|
+
|
|
133
|
+
return { state: 'linked', linkedPath };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export async function removeLinkedExtensionBundle(linkedPath: string) {
|
|
137
|
+
const resolvedLinkedPath = resolveExtensionInstallPath(linkedPath);
|
|
138
|
+
assertSafeLinkedExtensionPath(resolvedLinkedPath);
|
|
139
|
+
await rm(resolvedLinkedPath, { recursive: true, force: true });
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export async function snapshotLinkedExtensionBundle(
|
|
143
|
+
linkedPath: string,
|
|
144
|
+
): Promise<LinkedExtensionSnapshot | null> {
|
|
145
|
+
const resolvedLinkedPath = resolveExtensionInstallPath(linkedPath);
|
|
146
|
+
|
|
147
|
+
if (!(await exists(resolvedLinkedPath))) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const snapshotRoot = await mkdtemp(join(tmpdir(), 'cursor-pool-linked-extension-snapshot-'));
|
|
152
|
+
await cp(resolvedLinkedPath, snapshotRoot, { recursive: true });
|
|
153
|
+
return { root: snapshotRoot };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export async function restoreLinkedExtensionSnapshot(
|
|
157
|
+
linkedPath: string,
|
|
158
|
+
snapshot: LinkedExtensionSnapshot | null | undefined,
|
|
159
|
+
) {
|
|
160
|
+
if (!snapshot) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const resolvedLinkedPath = resolveExtensionInstallPath(linkedPath);
|
|
165
|
+
await removeLinkedExtensionBundle(resolvedLinkedPath);
|
|
166
|
+
await mkdir(dirname(resolvedLinkedPath), { recursive: true });
|
|
167
|
+
await cp(snapshot.root, resolvedLinkedPath, { recursive: true });
|
|
168
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const packageRole = 'cli';
|
|
2
|
+
export { detectEnvironment } from './environment';
|
|
3
|
+
export { findCursor } from './cursor';
|
|
4
|
+
export { resolveCompatEntry } from './compat';
|
|
5
|
+
export { install } from './install';
|
|
6
|
+
export { repair } from './repair';
|
|
7
|
+
export { status } from './status';
|
|
8
|
+
export { restore } from './restore';
|
|
9
|
+
export { uninstall } from './uninstall';
|
|
10
|
+
export { clearDiagnostics, diagnostics } from './diagnostics';
|
|
11
|
+
export { launchCommand, launchStatus } from './launch';
|
|
12
|
+
export { confirmRealOperation, formatRealOperationSummary } from './confirm';
|
|
13
|
+
export { resolveCursorTarget } from './target';
|
|
14
|
+
export {
|
|
15
|
+
DEFAULT_INSTALL_RECORD_FILE,
|
|
16
|
+
deleteInstallRecord,
|
|
17
|
+
installIdForAppPath,
|
|
18
|
+
installRecordPath,
|
|
19
|
+
isInstallRecordStale,
|
|
20
|
+
readInstallRecord,
|
|
21
|
+
writeInstallRecord,
|
|
22
|
+
} from './installRecord';
|
|
23
|
+
export type { InstallMode, InstallRecord, InstallRecordOptions } from './installRecord';
|