@cursorpool-dev/cli 0.5.9 → 0.5.11

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 (33) hide show
  1. package/node_modules/@cursor-pool/extension/dist/extension.js +1 -1
  2. package/node_modules/@cursor-pool/extension/package.json +3 -3
  3. package/node_modules/@cursor-pool/extension/src/api.ts +1 -1
  4. package/node_modules/@cursor-pool/extension/test/panel.test.ts +1 -1
  5. package/node_modules/@cursor-pool/patcher/package.json +2 -2
  6. package/node_modules/@cursor-pool/patcher/src/workbenchAuthGateMarker.ts +28 -8
  7. package/node_modules/@cursor-pool/patcher/test/patchCursorWorkbench.test.ts +11 -0
  8. package/node_modules/@cursor-pool/service/package.json +2 -2
  9. package/node_modules/@cursor-pool/shared/package.json +1 -1
  10. package/node_modules/@cursor-pool/shared/test/manifest.test.ts +6 -6
  11. package/node_modules/@esbuild/linux-arm64/README.md +3 -0
  12. package/node_modules/@esbuild/linux-arm64/bin/esbuild +0 -0
  13. package/node_modules/@esbuild/linux-arm64/package.json +20 -0
  14. package/package.json +5 -5
  15. package/src/compat.ts +94 -15
  16. package/src/cursor.ts +45 -4
  17. package/src/extensionBundle.ts +1 -1
  18. package/src/extensionLink.ts +2 -2
  19. package/src/install.ts +2 -1
  20. package/src/patchSet.ts +46 -4
  21. package/src/platform.ts +3 -3
  22. package/src/repair.ts +9 -5
  23. package/src/restore.ts +13 -6
  24. package/src/status.ts +5 -3
  25. package/src/target.ts +12 -0
  26. package/src/uninstall.ts +6 -2
  27. package/test/compat.test.ts +90 -0
  28. package/test/cursor.test.ts +54 -0
  29. package/test/e2e-install.test.ts +36 -0
  30. package/test/patchSet.test.ts +71 -0
  31. package/test/repair.test.ts +131 -0
  32. package/test/restore.test.ts +59 -3
  33. package/test/target.test.ts +28 -0
@@ -2153,7 +2153,7 @@ function buildExtensionDeviceInfo() {
2153
2153
  name: hostname(),
2154
2154
  os: osPlatform(),
2155
2155
  arch: arch(),
2156
- extensionVersion: "0.5.9"
2156
+ extensionVersion: "0.5.11"
2157
2157
  };
2158
2158
  }
2159
2159
  function serviceUrl(runtime, path) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cursor-pool/extension",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "displayName": "Cursor Pool 平台模式",
5
5
  "publisher": "cursor-pool",
6
6
  "engines": {
@@ -21,8 +21,8 @@
21
21
  "./runtime": "./src/runtime.ts"
22
22
  },
23
23
  "dependencies": {
24
- "@cursor-pool/service": "0.5.9",
25
- "@cursor-pool/shared": "0.5.9"
24
+ "@cursor-pool/service": "0.5.11",
25
+ "@cursor-pool/shared": "0.5.11"
26
26
  },
27
27
  "contributes": {
28
28
  "viewsContainers": {
@@ -114,7 +114,7 @@ export function buildExtensionDeviceInfo() {
114
114
  name: hostname(),
115
115
  os: osPlatform(),
116
116
  arch: arch(),
117
- extensionVersion: '0.5.9',
117
+ extensionVersion: '0.5.11',
118
118
  };
119
119
  }
120
120
 
@@ -1655,7 +1655,7 @@ test('API can login and logout through local service platform routes', async ()
1655
1655
  assert.equal(typeof (requests[0]?.body.device as Record<string, unknown>).name, 'string');
1656
1656
  assert.equal(typeof (requests[0]?.body.device as Record<string, unknown>).os, 'string');
1657
1657
  assert.equal(typeof (requests[0]?.body.device as Record<string, unknown>).arch, 'string');
1658
- assert.equal((requests[0]?.body.device as Record<string, unknown>).extensionVersion, '0.5.9');
1658
+ assert.equal((requests[0]?.body.device as Record<string, unknown>).extensionVersion, '0.5.11');
1659
1659
  assert.equal(requests[1]?.method, 'POST');
1660
1660
  assert.equal(requests[1]?.url, '/platform/logout');
1661
1661
  } finally {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cursor-pool/patcher",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "exports": {
@@ -9,7 +9,7 @@
9
9
  "./marker": "./src/marker.ts"
10
10
  },
11
11
  "dependencies": {
12
- "@cursor-pool/shared": "0.5.9"
12
+ "@cursor-pool/shared": "0.5.11"
13
13
  },
14
14
  "scripts": {
15
15
  "test": "tsx --test test/*.test.ts"
@@ -1,5 +1,5 @@
1
1
  export const CURSOR_POOL_WORKBENCH_AUTH_GATE_MARKER =
2
- 'CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V18_MAC34_BOTTOM_BAR';
2
+ 'CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V19_LOGGED_OUT_GLASS';
3
3
  export const CURSOR_POOL_WORKBENCH_AUTH_GATE_BEGIN_MARKER =
4
4
  `/* ${CURSOR_POOL_WORKBENCH_AUTH_GATE_MARKER}: begin */`;
5
5
  export const CURSOR_POOL_WORKBENCH_AUTH_GATE_END_MARKER =
@@ -22,6 +22,8 @@ export const CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE =
22
22
  '__cursorPoolWorkbenchRuntimeBaseUrl';
23
23
  export const CURSOR_POOL_WORKBENCH_PREFLIGHT_SIGNATURE =
24
24
  '__cursorPoolWorkbenchPlatformModePreflight';
25
+ export const CURSOR_POOL_WORKBENCH_LOGGED_OUT_GLASS_SIGNATURE =
26
+ '__cursorPoolWorkbenchLoggedOutGlassBypass';
25
27
 
26
28
  export const CURSOR_WORKBENCH_COMPOSER_AUTH_GATE_ANCHOR =
27
29
  'get when(){return p()&&!fzC},get fallback(){return he(DGC,{})}';
@@ -68,6 +70,8 @@ export const CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_MAC_3_7 =
68
70
  'if(wv.localMode){try{h.onNetworkPhaseStart?.()}catch(f){this.logService.warn("[AgentClientService] onNetworkPhaseStart callback failed in local mode",f)}return this.runLocalAgentInExtensionHost(n,e,t,i,r,o,c,d,h)}return this.client.run(n,e,t,i,r,s,o,a,c,d,h)';
69
71
  export const CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_MAC_3_4 =
70
72
  'if(U0.localMode){try{f.onNetworkPhaseStart?.()}catch(v){this.logService.warn("[AgentClientService] onNetworkPhaseStart callback failed in local mode",v)}return this.runLocalAgentInExtensionHost(e,t,i,r,s,a,u,d,f)}return this.client.run(e,t,i,r,s,o,a,l,u,d,f)';
73
+ export const CURSOR_WORKBENCH_LOGGED_OUT_GLASS_ROOT_ANCHOR_MAC_3_7 =
74
+ 'Te=M?$(ETI,{alertDialogStackSize:H,isWindowFullScreen:V,renderRootErrorFallback:ne,useOpaqueSplashBackground:J,workspace:r,workspaceCollectionService:s}):$(swI,{workspace:r})';
71
75
 
72
76
  function buildPlatformModeGuardBootstrapExpression() {
73
77
  return '((globalThis.__cursorPoolEnsurePlatformModeGuard||(globalThis.__cursorPoolEnsurePlatformModeGuard=()=>{try{if(globalThis.__cursorPoolPlatformModeGuardReady)return;globalThis.__cursorPoolPlatformModeGuardReady=!0;globalThis.__cursorPoolRuntimeBaseUrl=()=>{try{const e="http://127.0.0.1:56393",t=process?.env?.CURSOR_POOL_RUNTIME_BASE_URL;if(typeof t=="string"&&/^http:\\/\\/127\\.0\\.0\\.1:[1-9][0-9]{0,4}$/.test(t)){const r=Number(t.slice(t.lastIndexOf(":")+1));if(r>0&&r<65536)return t}if(typeof require!="function")return e;const r=require("node:fs"),o=require("node:os"),n=require("node:path"),i=process?.env?.CURSOR_POOL_RUNTIME_FILE||n.join(o.homedir(),".cursor-pool","runtime.json");if(!r.existsSync(i))return e;const s=JSON.parse(r.readFileSync(i,"utf8"));return s?.host==="127.0.0.1"&&Number.isInteger(s?.port)&&s.port>0&&s.port<65536?`http://127.0.0.1:${s.port}`:e}catch{return "http://127.0.0.1:56393"}};globalThis.__cursorPoolReadVerifiedPlatformModeCache=()=>{try{const e=Number(globalThis.localStorage?.getItem("cursorPoolPlatformModeCheckedAt")||"0");return Date.now()-e<3e5?globalThis.localStorage?.getItem("cursorPoolPlatformModeActive")==="1":!1}catch{return!1}};globalThis.__cursorPoolReadSessionPlatformModeActive=()=>{try{if(typeof require!="function")return null;const e=require("node:fs"),t=require("node:os"),r=require("node:path"),o=process?.env?.CURSOR_POOL_PLATFORM_SESSION_FILE||r.join(t.homedir(),".cursor-pool","session.json");if(!e.existsSync(o))return null;const n=JSON.parse(e.readFileSync(o,"utf8")),i=n?.session;return n?.device?.status==="active"&&n?.platformMode==="active"&&typeof n?.activeProductId==="string"&&typeof n?.platformModeStartedAt==="string"||i?.device?.status==="active"&&i?.mode?.state==="active"}catch{return null}};globalThis.__cursorPoolReadPlatformModeActive=()=>{try{return globalThis.__cursorPoolReadSessionPlatformModeActive?.()===!0||globalThis.__cursorPoolReadVerifiedPlatformModeCache?.()===!0}catch{return!1}};globalThis.__cursorPoolPlatformModeActiveCache=globalThis.__cursorPoolReadPlatformModeActive(),globalThis.__cursorPoolRefreshPlatformModeActive=()=>{try{if(globalThis.__cursorPoolPlatformModeRefreshInFlight||typeof globalThis.fetch!="function")return;const e=globalThis.__cursorPoolRuntimeBaseUrl?.();if(!e)return;globalThis.__cursorPoolPlatformModeRefreshInFlight=!0,globalThis.fetch(`${e}/platform/status`).then(e=>e.ok?e.json():null).then(e=>{const t=e?.mode?.state==="active",r=globalThis.__cursorPoolPlatformModeActiveCache===!0;globalThis.__cursorPoolPlatformModeActiveCache=t;try{globalThis.localStorage?.setItem("cursorPoolPlatformModeActive",t?"1":"0"),globalThis.localStorage?.setItem("cursorPoolPlatformModeCheckedAt",String(Date.now()))}catch{}t!==r&&typeof globalThis.setTimeout=="function"&&globalThis.setTimeout(()=>globalThis.location?.reload?.(),50)}).catch(()=>{const e=globalThis.__cursorPoolPlatformModeActiveCache===!0;globalThis.__cursorPoolPlatformModeActiveCache=globalThis.__cursorPoolReadPlatformModeActive?.()===!0;try{globalThis.localStorage?.setItem("cursorPoolPlatformModeActive",globalThis.__cursorPoolPlatformModeActiveCache?"1":"0")}catch{}e!==globalThis.__cursorPoolPlatformModeActiveCache&&typeof globalThis.setTimeout=="function"&&globalThis.setTimeout(()=>globalThis.location?.reload?.(),50)}).finally(()=>{globalThis.__cursorPoolPlatformModeRefreshInFlight=!1})}catch{}},globalThis.__cursorPoolIsPlatformModeActive=()=>{try{globalThis.__cursorPoolEnsurePlatformModeGuard?.();return globalThis.__cursorPoolPlatformModeActiveCache===!0}catch{return!1}},globalThis.__cursorPoolRefreshPlatformModeActive(),globalThis.__cursorPoolPlatformModeRefreshTimer||typeof globalThis.setInterval!="function"||(globalThis.__cursorPoolPlatformModeRefreshTimer=globalThis.setInterval(globalThis.__cursorPoolRefreshPlatformModeActive,1e3))}catch{}}))(),globalThis.__cursorPoolIsPlatformModeActive?.()===true)';
@@ -99,7 +103,10 @@ export function containsCursorWorkbenchAuthGateMarker(content: string) {
99
103
  .includes(CURSOR_POOL_WORKBENCH_AGENT_EDITOR_CURSOR_AI_LOGIN_SIGNATURE) &&
100
104
  content
101
105
  .slice(beginIndex, endIndex)
102
- .includes(CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE)
106
+ .includes(CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE) &&
107
+ content
108
+ .slice(beginIndex, endIndex)
109
+ .includes(CURSOR_POOL_WORKBENCH_LOGGED_OUT_GLASS_SIGNATURE)
103
110
  );
104
111
  }
105
112
 
@@ -107,6 +114,7 @@ export function containsAnyCursorWorkbenchAuthGateMarkerText(content: string) {
107
114
  return (
108
115
  content.includes(CURSOR_POOL_WORKBENCH_AUTH_GATE_MARKER) ||
109
116
  content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V17_PLATFORM_PREFLIGHT') ||
117
+ content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V18_MAC34_BOTTOM_BAR') ||
110
118
  content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V16_SELF_BOOTSTRAP_PLATFORM_GUARD') ||
111
119
  content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V15_RENDERER_STORAGE_GUARD') ||
112
120
  content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V14_EXPLICIT_TAKEOVER_SWITCH') ||
@@ -123,7 +131,8 @@ export function containsAnyCursorWorkbenchAuthGateMarkerText(content: string) {
123
131
  content.includes(CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_SIGNATURE) ||
124
132
  content.includes(CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SUBMIT_SIGNATURE) ||
125
133
  content.includes(CURSOR_POOL_WORKBENCH_AGENT_EDITOR_CURSOR_AI_LOGIN_SIGNATURE) ||
126
- content.includes(CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE)
134
+ content.includes(CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE) ||
135
+ content.includes(CURSOR_POOL_WORKBENCH_LOGGED_OUT_GLASS_SIGNATURE)
127
136
  );
128
137
  }
129
138
 
@@ -136,6 +145,7 @@ export function buildCursorWorkbenchAuthGatePatchSnippet() {
136
145
  ["${CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SUBMIT_SIGNATURE}"]:true,
137
146
  ["${CURSOR_POOL_WORKBENCH_AGENT_EDITOR_CURSOR_AI_LOGIN_SIGNATURE}"]:true,
138
147
  ["${CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE}"]:true,
148
+ ["${CURSOR_POOL_WORKBENCH_LOGGED_OUT_GLASS_SIGNATURE}"]:true,
139
149
  ["${CURSOR_POOL_WORKBENCH_NATIVE_LOCAL_AGENT_SIGNATURE}"]:(${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION},void 0),
140
150
  ${CURSOR_POOL_WORKBENCH_AUTH_GATE_END_MARKER}`;
141
151
  }
@@ -311,14 +321,24 @@ export function injectCursorWorkbenchAuthGatePatch(content: string) {
311
321
  `get when(){return (v()||${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION})&&!HG1},get fallback(){return re(s71,{})},get children(){return re(u$1,`,
312
322
  )
313
323
  : withAgentEditorSubmitGate;
324
+
325
+ const withLoggedOutGlassGate = withAgentEditorCursorAiLoginGate.includes(
326
+ CURSOR_WORKBENCH_LOGGED_OUT_GLASS_ROOT_ANCHOR_MAC_3_7,
327
+ )
328
+ ? withAgentEditorCursorAiLoginGate.replace(
329
+ CURSOR_WORKBENCH_LOGGED_OUT_GLASS_ROOT_ANCHOR_MAC_3_7,
330
+ `Te=M||${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}?$(ETI,{alertDialogStackSize:H,isWindowFullScreen:V,renderRootErrorFallback:ne,useOpaqueSplashBackground:J,workspace:r,workspaceCollectionService:s}):$(swI,{workspace:r})`,
331
+ )
332
+ : withAgentEditorCursorAiLoginGate;
333
+
314
334
  const submitGateAnchor = [
315
335
  CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR,
316
336
  CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_LINUX_3_6,
317
337
  CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_7,
318
338
  CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4,
319
339
  CURSOR_WORKBENCH_MAIN_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4,
320
- ].find((anchor) => withAgentEditorCursorAiLoginGate.includes(anchor));
321
- const submitGateIndex = submitGateAnchor ? withAgentEditorCursorAiLoginGate.indexOf(submitGateAnchor) : -1;
340
+ ].find((anchor) => withLoggedOutGlassGate.includes(anchor));
341
+ const submitGateIndex = submitGateAnchor ? withLoggedOutGlassGate.indexOf(submitGateAnchor) : -1;
322
342
  const mac34SubmitReplacement = buildComposerSubmitAuthGateReplacement(
323
343
  CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4,
324
344
  );
@@ -327,7 +347,7 @@ export function injectCursorWorkbenchAuthGatePatch(content: string) {
327
347
  );
328
348
  if (
329
349
  submitGateIndex < 0 &&
330
- !(isMac34ComposerPatch && withAgentEditorCursorAiLoginGate.includes(mac34SubmitReplacement))
350
+ !(isMac34ComposerPatch && withLoggedOutGlassGate.includes(mac34SubmitReplacement))
331
351
  ) {
332
352
  throw new Error('Cursor Workbench composer submit auth gate anchor was not found.');
333
353
  }
@@ -336,10 +356,10 @@ export function injectCursorWorkbenchAuthGatePatch(content: string) {
336
356
  ? buildComposerSubmitAuthGateReplacement(submitGateAnchor)
337
357
  : '';
338
358
  const withSubmitGate = submitGateIndex >= 0
339
- ? `${withAgentEditorCursorAiLoginGate.slice(0, submitGateIndex)}${submitGateReplacement}${withAgentEditorCursorAiLoginGate.slice(
359
+ ? `${withLoggedOutGlassGate.slice(0, submitGateIndex)}${submitGateReplacement}${withLoggedOutGlassGate.slice(
340
360
  submitGateIndex + submitGateAnchor!.length,
341
361
  )}`
342
- : withAgentEditorCursorAiLoginGate;
362
+ : withLoggedOutGlassGate;
343
363
 
344
364
  const agentLoopIndex = withSubmitGate.indexOf(CURSOR_WORKBENCH_AGENT_LOOP_RUN_ANCHOR);
345
365
  if (
@@ -57,6 +57,8 @@ const agentClientRunLocalModeAnchorMac37 =
57
57
  'if(wv.localMode){try{h.onNetworkPhaseStart?.()}catch(f){this.logService.warn("[AgentClientService] onNetworkPhaseStart callback failed in local mode",f)}return this.runLocalAgentInExtensionHost(n,e,t,i,r,o,c,d,h)}return this.client.run(n,e,t,i,r,s,o,a,c,d,h)';
58
58
  const agentClientRunLocalModeAnchorMac34 =
59
59
  'if(U0.localMode){try{f.onNetworkPhaseStart?.()}catch(v){this.logService.warn("[AgentClientService] onNetworkPhaseStart callback failed in local mode",v)}return this.runLocalAgentInExtensionHost(e,t,i,r,s,a,u,d,f)}return this.client.run(e,t,i,r,s,o,a,l,u,d,f)';
60
+ const loggedOutGlassRootAnchorMac37 =
61
+ 'Te=M?$(ETI,{alertDialogStackSize:H,isWindowFullScreen:V,renderRootErrorFallback:ne,useOpaqueSplashBackground:J,workspace:r,workspaceCollectionService:s}):$(swI,{workspace:r})';
60
62
  const agentLoopRunAnchor = 'await this.agentClientService.run(te,H,$e,Ne,Ce,T,ze,me,we,[],ct)';
61
63
  const buildFlagsLocalModeAnchor = 'localMode:!1';
62
64
  const localProviderConfigAnchor =
@@ -82,6 +84,7 @@ function workbenchFixtureMac37(extra = '') {
82
84
  `function composer(){return ge(Mt,{${composerSendButtonAuthGateAnchorMac37}"controls"}})}`,
83
85
  `async function submit(){${composerSubmitAuthGateAnchorMac37};return "submitted";}`,
84
86
  `function bottomBar(){return ie(ct,{${agentEditorBottomBarAuthGateAnchorMac37}{})}}`,
87
+ `function root(){let Te;${loggedOutGlassRootAnchorMac37};return Te}`,
85
88
  `const flags={${buildFlagsLocalModeAnchor}}`,
86
89
  localProviderConfigAnchorMac37,
87
90
  `async function agentClientRun(){const h={...m,isRunningInTest:m.isRunningInTest??this.environmentService.enableSmokeTestDriver===!0,clientSupportsInlineImages:!0};${agentClientRunLocalModeAnchorMac37}}`,
@@ -190,6 +193,7 @@ test('workbench auth gate patch supports Cursor 3.7 macOS composer and local age
190
193
  assert.equal(patched.includes(composerSendButtonAuthGateAnchorMac37), false);
191
194
  assert.equal(patched.includes(composerSubmitAuthGateAnchorMac37), false);
192
195
  assert.equal(patched.includes(agentEditorBottomBarAuthGateAnchorMac37), false);
196
+ assert.equal(patched.includes(loggedOutGlassRootAnchorMac37), false);
193
197
  assert.equal(patched.includes(localProviderConfigAnchorMac37), false);
194
198
  assert.equal(patched.includes(agentClientRunLocalModeAnchorMac37), false);
195
199
  assert.equal(
@@ -212,6 +216,13 @@ test('workbench auth gate patch supports Cursor 3.7 macOS composer and local age
212
216
  ),
213
217
  true,
214
218
  );
219
+ assert.equal(
220
+ patched.includes(
221
+ 'Te=M||((globalThis.__cursorPoolEnsurePlatformModeGuard||(globalThis.__cursorPoolEnsurePlatformModeGuard=()=>{',
222
+ ),
223
+ true,
224
+ );
225
+ assert.equal(patched.includes(':$(swI,{workspace:r})'), true);
215
226
  assert.equal(patched.includes('||wv.localMode)'), true);
216
227
  assert.equal(patched.includes('return this.runLocalAgentInExtensionHost(n,e,t,i,r,o,c,d,h)'), true);
217
228
  assert.equal(patched.includes('return this.client.run(n,e,t,i,r,s,o,a,c,d,h)'), true);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cursor-pool/service",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "exports": {
@@ -9,7 +9,7 @@
9
9
  "./platformSession": "./src/platformSession.ts"
10
10
  },
11
11
  "dependencies": {
12
- "@cursor-pool/shared": "0.5.9"
12
+ "@cursor-pool/shared": "0.5.11"
13
13
  },
14
14
  "scripts": {
15
15
  "test": "tsx --test test/*.test.ts"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cursor-pool/shared",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "exports": {
@@ -20,9 +20,9 @@ test('compatibility manifest entry captures patch compatibility metadata', () =>
20
20
  patchStrategy: 'replace-marker',
21
21
  verifyMarker: 'cursor-pool',
22
22
  restoreStrategy: 'backup',
23
- minCliVersion: '0.5.9',
24
- minExtensionVersion: '0.5.9',
25
- minServiceVersion: '0.5.9',
23
+ minCliVersion: '0.5.11',
24
+ minExtensionVersion: '0.5.11',
25
+ minServiceVersion: '0.5.11',
26
26
  requiresWritableAppBundle: true,
27
27
  requiresAdHocResign: true,
28
28
  userMessage: 'Supported Cursor build.',
@@ -45,9 +45,9 @@ test('compatibility manifest envelope captures signed rule payload', () => {
45
45
  patchStrategy: 'replace-marker',
46
46
  verifyMarker: 'cursor-pool',
47
47
  restoreStrategy: 'backup',
48
- minCliVersion: '0.5.9',
49
- minExtensionVersion: '0.5.9',
50
- minServiceVersion: '0.5.9',
48
+ minCliVersion: '0.5.11',
49
+ minExtensionVersion: '0.5.11',
50
+ minServiceVersion: '0.5.11',
51
51
  requiresWritableAppBundle: true,
52
52
  requiresAdHocResign: false,
53
53
  userMessage: 'Supported Cursor build.',
@@ -0,0 +1,3 @@
1
+ # esbuild
2
+
3
+ This is the Linux ARM 64-bit binary for esbuild, a JavaScript bundler and minifier. See https://github.com/evanw/esbuild for details.
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@esbuild/linux-arm64",
3
+ "version": "0.28.0",
4
+ "description": "The Linux ARM 64-bit binary for esbuild, a JavaScript bundler.",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/evanw/esbuild.git"
8
+ },
9
+ "license": "MIT",
10
+ "preferUnplugged": true,
11
+ "engines": {
12
+ "node": ">=18"
13
+ },
14
+ "os": [
15
+ "linux"
16
+ ],
17
+ "cpu": [
18
+ "arm64"
19
+ ]
20
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cursorpool-dev/cli",
3
- "version": "0.5.9",
3
+ "version": "0.5.11",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "bin": {
@@ -12,10 +12,10 @@
12
12
  "dependencies": {
13
13
  "esbuild": "~0.28.0",
14
14
  "tsx": "^4.22.3",
15
- "@cursor-pool/patcher": "0.5.9",
16
- "@cursor-pool/service": "0.5.9",
17
- "@cursor-pool/extension": "0.5.9",
18
- "@cursor-pool/shared": "0.5.9"
15
+ "@cursor-pool/extension": "0.5.11",
16
+ "@cursor-pool/service": "0.5.11",
17
+ "@cursor-pool/patcher": "0.5.11",
18
+ "@cursor-pool/shared": "0.5.11"
19
19
  },
20
20
  "bundledDependencies": [
21
21
  "@cursor-pool/extension",
package/src/compat.ts CHANGED
@@ -9,6 +9,9 @@ import { CURSOR_AGENT_EXEC_RELATIVE_PATH } from '@cursor-pool/patcher';
9
9
  import type { CliEnvironment } from './environment';
10
10
  import type { CursorInfo } from './cursor';
11
11
 
12
+ const LINUX_DEB_AGENT_EXEC_RELATIVE_PATH =
13
+ 'resources/app/extensions/cursor-agent-exec/dist/main.js';
14
+
12
15
  export const DEFAULT_COMPAT_ENTRIES: CompatibilityManifestEntry[] = [
13
16
  {
14
17
  platform: 'darwin',
@@ -22,9 +25,9 @@ export const DEFAULT_COMPAT_ENTRIES: CompatibilityManifestEntry[] = [
22
25
  patchStrategy: 'cursor-agent-exec-snippet',
23
26
  verifyMarker: 'cursor-pool',
24
27
  restoreStrategy: 'external-backup',
25
- minCliVersion: '0.5.9',
26
- minExtensionVersion: '0.5.9',
27
- minServiceVersion: '0.5.9',
28
+ minCliVersion: '0.5.11',
29
+ minExtensionVersion: '0.5.11',
30
+ minServiceVersion: '0.5.11',
28
31
  requiresWritableAppBundle: true,
29
32
  requiresAdHocResign: true,
30
33
  userMessage: 'Cursor 3.4.x is supported for MVP-0.',
@@ -41,9 +44,9 @@ export const DEFAULT_COMPAT_ENTRIES: CompatibilityManifestEntry[] = [
41
44
  patchStrategy: 'cursor-agent-exec-snippet',
42
45
  verifyMarker: 'cursor-pool',
43
46
  restoreStrategy: 'external-backup',
44
- minCliVersion: '0.5.9',
45
- minExtensionVersion: '0.5.9',
46
- minServiceVersion: '0.5.9',
47
+ minCliVersion: '0.5.11',
48
+ minExtensionVersion: '0.5.11',
49
+ minServiceVersion: '0.5.11',
47
50
  requiresWritableAppBundle: true,
48
51
  requiresAdHocResign: true,
49
52
  userMessage: 'Cursor 3.5.x is supported for MVP-0.',
@@ -60,9 +63,9 @@ export const DEFAULT_COMPAT_ENTRIES: CompatibilityManifestEntry[] = [
60
63
  patchStrategy: 'cursor-agent-exec-snippet',
61
64
  verifyMarker: 'cursor-pool',
62
65
  restoreStrategy: 'external-backup',
63
- minCliVersion: '0.5.9',
64
- minExtensionVersion: '0.5.9',
65
- minServiceVersion: '0.5.9',
66
+ minCliVersion: '0.5.11',
67
+ minExtensionVersion: '0.5.11',
68
+ minServiceVersion: '0.5.11',
66
69
  requiresWritableAppBundle: true,
67
70
  requiresAdHocResign: true,
68
71
  userMessage: 'Cursor 3.5.x is supported for MVP-0 under Rosetta-launched installers.',
@@ -79,9 +82,9 @@ export const DEFAULT_COMPAT_ENTRIES: CompatibilityManifestEntry[] = [
79
82
  patchStrategy: 'cursor-agent-exec-snippet',
80
83
  verifyMarker: 'cursor-pool',
81
84
  restoreStrategy: 'external-backup',
82
- minCliVersion: '0.5.9',
83
- minExtensionVersion: '0.5.9',
84
- minServiceVersion: '0.5.9',
85
+ minCliVersion: '0.5.11',
86
+ minExtensionVersion: '0.5.11',
87
+ minServiceVersion: '0.5.11',
85
88
  requiresWritableAppBundle: true,
86
89
  requiresAdHocResign: true,
87
90
  userMessage: 'Cursor 3.6.x is supported for MVP-0.',
@@ -98,9 +101,9 @@ export const DEFAULT_COMPAT_ENTRIES: CompatibilityManifestEntry[] = [
98
101
  patchStrategy: 'cursor-agent-exec-snippet',
99
102
  verifyMarker: 'cursor-pool',
100
103
  restoreStrategy: 'external-backup',
101
- minCliVersion: '0.5.9',
102
- minExtensionVersion: '0.5.9',
103
- minServiceVersion: '0.5.9',
104
+ minCliVersion: '0.5.11',
105
+ minExtensionVersion: '0.5.11',
106
+ minServiceVersion: '0.5.11',
104
107
  requiresWritableAppBundle: true,
105
108
  requiresAdHocResign: true,
106
109
  userMessage: 'Cursor 3.7.x is supported for MVP-0.',
@@ -124,6 +127,82 @@ export const DEFAULT_COMPAT_ENTRIES: CompatibilityManifestEntry[] = [
124
127
  requiresAdHocResign: false,
125
128
  userMessage: 'Cursor 3.6.31 Linux x64 AppImage is supported.',
126
129
  },
130
+ {
131
+ platform: 'linux',
132
+ arch: 'arm64',
133
+ cursorVersion: '3.4',
134
+ cursorCommit: '*',
135
+ supportStatus: 'supported',
136
+ targetRelativePath: LINUX_DEB_AGENT_EXEC_RELATIVE_PATH,
137
+ expectedSha256: '4ccb7526e5ece8f6a98a99724a048977698cbf52cb2033ec06f2b5a0a085fe71',
138
+ structureSignature: 'linux-arm64-deb-cursor-3-4-family',
139
+ patchStrategy: 'cursor-agent-exec-snippet',
140
+ verifyMarker: 'cursor-pool',
141
+ restoreStrategy: 'external-backup',
142
+ minCliVersion: '0.5.10',
143
+ minExtensionVersion: '0.5.10',
144
+ minServiceVersion: '0.5.10',
145
+ requiresWritableAppBundle: true,
146
+ requiresAdHocResign: false,
147
+ userMessage: 'Cursor 3.4.x Linux arm64 deb installs are supported.',
148
+ },
149
+ {
150
+ platform: 'linux',
151
+ arch: 'arm64',
152
+ cursorVersion: '3.5',
153
+ cursorCommit: '*',
154
+ supportStatus: 'supported',
155
+ targetRelativePath: LINUX_DEB_AGENT_EXEC_RELATIVE_PATH,
156
+ expectedSha256: 'cb18f0237278884a39e2ce2b8664255e12689ad0803c20096c38e86c36acc51f',
157
+ structureSignature: 'linux-arm64-deb-cursor-3-5-family',
158
+ patchStrategy: 'cursor-agent-exec-snippet',
159
+ verifyMarker: 'cursor-pool',
160
+ restoreStrategy: 'external-backup',
161
+ minCliVersion: '0.5.10',
162
+ minExtensionVersion: '0.5.10',
163
+ minServiceVersion: '0.5.10',
164
+ requiresWritableAppBundle: true,
165
+ requiresAdHocResign: false,
166
+ userMessage: 'Cursor 3.5.x Linux arm64 deb installs are supported.',
167
+ },
168
+ {
169
+ platform: 'linux',
170
+ arch: 'arm64',
171
+ cursorVersion: '3.6',
172
+ cursorCommit: '*',
173
+ supportStatus: 'supported',
174
+ targetRelativePath: LINUX_DEB_AGENT_EXEC_RELATIVE_PATH,
175
+ expectedSha256: '05bfa29eacb8271c378765ead4bf881f806b97549dd13367183aa7a9331c1131',
176
+ structureSignature: 'linux-arm64-deb-cursor-3-6-family',
177
+ patchStrategy: 'cursor-agent-exec-snippet',
178
+ verifyMarker: 'cursor-pool',
179
+ restoreStrategy: 'external-backup',
180
+ minCliVersion: '0.5.10',
181
+ minExtensionVersion: '0.5.10',
182
+ minServiceVersion: '0.5.10',
183
+ requiresWritableAppBundle: true,
184
+ requiresAdHocResign: false,
185
+ userMessage: 'Cursor 3.6.x Linux arm64 deb installs are supported.',
186
+ },
187
+ {
188
+ platform: 'linux',
189
+ arch: 'arm64',
190
+ cursorVersion: '3.7',
191
+ cursorCommit: '*',
192
+ supportStatus: 'supported',
193
+ targetRelativePath: LINUX_DEB_AGENT_EXEC_RELATIVE_PATH,
194
+ expectedSha256: '9ce7a2f40a98a27eb1b609a79e0e1707bad5fbb02493693f6f18945a7640dde4',
195
+ structureSignature: 'linux-arm64-deb-cursor-3-7-family',
196
+ patchStrategy: 'cursor-agent-exec-snippet',
197
+ verifyMarker: 'cursor-pool',
198
+ restoreStrategy: 'external-backup',
199
+ minCliVersion: '0.5.10',
200
+ minExtensionVersion: '0.5.10',
201
+ minServiceVersion: '0.5.10',
202
+ requiresWritableAppBundle: true,
203
+ requiresAdHocResign: false,
204
+ userMessage: 'Cursor 3.7.x Linux arm64 deb installs are supported.',
205
+ },
127
206
  ];
128
207
 
129
208
  export type ResolveCompatOptions = {
package/src/cursor.ts CHANGED
@@ -1,12 +1,17 @@
1
- import { execFile } from 'node:child_process';
1
+ import { execFile, execFileSync } from 'node:child_process';
2
2
  import { createHash } from 'node:crypto';
3
3
  import { promisify } from 'node:util';
4
4
  import { chmod, mkdir, readFile, rm, stat } from 'node:fs/promises';
5
- import { basename, join, win32 } from 'node:path';
5
+ import { basename, dirname, join, win32 } from 'node:path';
6
6
  import { homedir } from 'node:os';
7
7
 
8
8
  export const DEFAULT_MACOS_CURSOR_APP_PATH = '/Applications/Cursor.app';
9
9
  const execFileAsync = promisify(execFile);
10
+ type ExecFileForCursor = (
11
+ command: string,
12
+ args: string[],
13
+ ) => Promise<{ stdout: string }>;
14
+ type ExecFileSyncForCursor = (command: string, args: string[]) => string | Buffer;
10
15
 
11
16
  export type CursorInfo = {
12
17
  appPath: string;
@@ -20,6 +25,8 @@ export type FindCursorOptions = {
20
25
  platform?: NodeJS.Platform;
21
26
  env?: NodeJS.ProcessEnv;
22
27
  appImageExtract?: (appImagePath: string, outputRoot: string) => Promise<string>;
28
+ execFile?: ExecFileForCursor;
29
+ execFileSync?: ExecFileSyncForCursor;
23
30
  };
24
31
 
25
32
  type CursorProductJson = {
@@ -29,7 +36,17 @@ type CursorProductJson = {
29
36
  cursorCommit?: unknown;
30
37
  };
31
38
 
32
- export function defaultCursorAppPath(options: Pick<FindCursorOptions, 'platform' | 'env'> = {}) {
39
+ function inferLinuxCursorRoot(launcher: string) {
40
+ const binDir = dirname(launcher);
41
+ if (basename(binDir) === 'bin') {
42
+ return dirname(binDir);
43
+ }
44
+ throw new Error(`Cursor app auto-detection could not infer app root from ${launcher}`);
45
+ }
46
+
47
+ export function defaultCursorAppPath(
48
+ options: Pick<FindCursorOptions, 'platform' | 'env' | 'execFileSync'> = {},
49
+ ) {
33
50
  const platform = options.platform ?? process.platform;
34
51
  if (platform === 'darwin') {
35
52
  return DEFAULT_MACOS_CURSOR_APP_PATH;
@@ -41,15 +58,39 @@ export function defaultCursorAppPath(options: Pick<FindCursorOptions, 'platform'
41
58
  }
42
59
  return win32.join(localAppData, 'Programs', 'Cursor');
43
60
  }
61
+ if (platform === 'linux') {
62
+ const run = options.execFileSync ?? execFileSync;
63
+ const which = String(run('which', ['cursor'])).trim();
64
+ if (!which) {
65
+ throw new Error('Cursor app auto-detection could not find cursor on PATH');
66
+ }
67
+ const launcher = String(run('readlink', ['-f', which])).trim() || which;
68
+ return inferLinuxCursorRoot(launcher);
69
+ }
44
70
  throw new Error(`Cursor app auto-detection is not supported on ${platform}`);
45
71
  }
46
72
 
73
+ async function defaultLinuxCursorAppPath(options: Pick<FindCursorOptions, 'execFile'> = {}) {
74
+ const run = options.execFile ?? execFileAsync;
75
+ const which = (await run('which', ['cursor'])).stdout.trim();
76
+ if (!which) {
77
+ throw new Error('Cursor app auto-detection could not find cursor on PATH');
78
+ }
79
+ const launcher = (await run('readlink', ['-f', which])).stdout.trim() || which;
80
+ return inferLinuxCursorRoot(launcher);
81
+ }
82
+
47
83
  function readString(value: unknown) {
48
84
  return typeof value === 'string' && value.length > 0 ? value : undefined;
49
85
  }
50
86
 
51
87
  export async function findCursor(options: FindCursorOptions = {}): Promise<CursorInfo> {
52
- const rawAppPath = options.appPath ?? defaultCursorAppPath(options);
88
+ const platform = options.platform ?? process.platform;
89
+ const rawAppPath =
90
+ options.appPath ??
91
+ (platform === 'linux'
92
+ ? await defaultLinuxCursorAppPath(options)
93
+ : defaultCursorAppPath(options));
53
94
  const appPath = await resolveCursorAppPath(rawAppPath, options);
54
95
  const productJsonPath = await resolveProductJsonPath(appPath, options);
55
96
  const product = JSON.parse(await readFile(productJsonPath, 'utf8')) as CursorProductJson;
@@ -55,7 +55,7 @@ async function exists(path: string) {
55
55
  function buildRuntimeManifest(sourceManifest: Record<string, unknown>) {
56
56
  return {
57
57
  name: 'cursorpool',
58
- version: typeof sourceManifest.version === 'string' ? sourceManifest.version : '0.5.9',
58
+ version: typeof sourceManifest.version === 'string' ? sourceManifest.version : '0.5.11',
59
59
  displayName: 'Cursor Pool 平台模式',
60
60
  publisher: 'cursor-pool',
61
61
  type: sourceManifest.type,
@@ -4,7 +4,7 @@ import { basename, dirname, join, resolve } from 'node:path';
4
4
  import { resolveExtensionInstallPath } from './extensionBundle';
5
5
  import type { ExtensionState } from './trial';
6
6
 
7
- export const LINKED_EXTENSION_DIRNAME = 'cursor-pool.extension-0.5.9';
7
+ export const LINKED_EXTENSION_DIRNAME = 'cursor-pool.extension-0.5.11';
8
8
  const RUNTIME_EXTENSION_ID = 'cursor-pool.cursorpool';
9
9
  const STALE_EXTENSION_IDS = new Set([
10
10
  RUNTIME_EXTENSION_ID,
@@ -48,7 +48,7 @@ async function readRuntimeManifest(linkedPath: string) {
48
48
  };
49
49
  const publisher = typeof manifest.publisher === 'string' ? manifest.publisher : 'cursor-pool';
50
50
  const name = typeof manifest.name === 'string' ? manifest.name : 'cursorpool';
51
- const version = typeof manifest.version === 'string' ? manifest.version : '0.5.9';
51
+ const version = typeof manifest.version === 'string' ? manifest.version : '0.5.11';
52
52
  return { id: `${publisher}.${name}`, version };
53
53
  }
54
54
 
package/src/install.ts CHANGED
@@ -104,7 +104,7 @@ export type InstallOptions = FindCursorOptions &
104
104
  };
105
105
 
106
106
  const REAL_CURSOR_EXTENSIONS_DIR = '~/.cursor/extensions';
107
- const PACKAGE_VERSION = '0.5.9';
107
+ const PACKAGE_VERSION = '0.5.11';
108
108
  const AUTOSTART_SERVICE_STARTUP_TIMEOUT_MS = 30_000;
109
109
 
110
110
  function delay(ms: number) {
@@ -603,6 +603,7 @@ export async function install(options: InstallOptions = {}) {
603
603
  try {
604
604
  await restoreCursorSet(cursor.appPath, {
605
605
  backupDir: options.backupDir,
606
+ agentExecTargetRelativePath: compat.targetRelativePath,
606
607
  platform: environment.platform,
607
608
  restoreCursorAgentExec: options.restoreCursorAgentExec,
608
609
  restoreCursorAlwaysLocal: options.restoreCursorAlwaysLocal,