@cursorpool-dev/cli 0.5.6 → 0.5.8
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 +116 -46
- package/node_modules/@cursor-pool/extension/package.json +3 -3
- package/node_modules/@cursor-pool/extension/src/api.ts +17 -2
- package/node_modules/@cursor-pool/extension/src/panel.ts +26 -3
- package/node_modules/@cursor-pool/extension/test/panel.test.ts +34 -1
- package/node_modules/@cursor-pool/patcher/package.json +2 -2
- package/node_modules/@cursor-pool/patcher/src/marker.ts +5 -1
- package/node_modules/@cursor-pool/patcher/src/workbenchAuthGateMarker.ts +58 -7
- package/node_modules/@cursor-pool/patcher/test/patchCursorAgentExec.test.ts +20 -0
- package/node_modules/@cursor-pool/patcher/test/patchCursorWorkbench.test.ts +193 -2
- package/node_modules/@cursor-pool/service/package.json +2 -2
- package/node_modules/@cursor-pool/service/src/platformSession.ts +30 -7
- package/node_modules/@cursor-pool/service/src/server.ts +1 -0
- package/node_modules/@cursor-pool/service/test/platformSession.test.ts +5 -4
- package/node_modules/@cursor-pool/service/test/server.test.ts +130 -0
- package/node_modules/@cursor-pool/shared/package.json +1 -1
- package/node_modules/@cursor-pool/shared/src/manifest.ts +35 -0
- package/node_modules/@cursor-pool/shared/test/manifest.test.ts +43 -9
- package/node_modules/@cursor-pool/takeover-plans/package.json +12 -0
- package/node_modules/@cursor-pool/takeover-plans/src/index.ts +22 -0
- package/node_modules/@cursor-pool/takeover-plans/src/plans.ts +37 -0
- package/node_modules/@cursor-pool/takeover-plans/src/types.ts +9 -0
- package/node_modules/@cursor-pool/takeover-plans/test/registry.test.ts +23 -0
- 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 +11 -6
- package/src/autostart.ts +5 -1
- package/src/compat.ts +193 -47
- package/src/cursor.ts +59 -3
- package/src/extensionBundle.ts +1 -1
- package/src/extensionLink.ts +28 -7
- package/src/install.ts +176 -24
- package/src/installRecord.ts +2 -0
- package/src/patchSet.ts +12 -6
- package/src/platform.ts +3 -3
- package/src/repair.ts +10 -1
- package/src/restore.ts +12 -4
- package/src/serviceProcess.ts +2 -1
- package/src/status.ts +6 -0
- package/src/trial.ts +1 -0
- package/test/autostart.test.ts +23 -2
- package/test/compat.test.ts +238 -3
- package/test/cursor-pool-bin.test.ts +1 -0
- package/test/cursor.test.ts +60 -1
- package/test/e2e-install.test.ts +53 -0
- package/test/extensionLink.test.ts +48 -2
- package/test/install.test.ts +191 -6
- package/test/repair.test.ts +1 -0
- package/test/serviceProcess.test.ts +10 -1
- package/test/status.test.ts +1 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const CURSOR_POOL_WORKBENCH_AUTH_GATE_MARKER =
|
|
2
|
-
'
|
|
2
|
+
'CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V18_ROUTE_READY_GUARD';
|
|
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 =
|
|
@@ -27,8 +27,16 @@ export const CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR =
|
|
|
27
27
|
'if(!p()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(wV,"general");return}';
|
|
28
28
|
export const CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_LINUX_3_6 =
|
|
29
29
|
'if(!h()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(P5,"general");return}';
|
|
30
|
+
export const CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_7 =
|
|
31
|
+
'if(!h()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(a6,"general");return}';
|
|
32
|
+
export const CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4 =
|
|
33
|
+
'if(!t()){e.cursorAuthenticationService.login();return}';
|
|
30
34
|
export const CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_LINUX_3_6 =
|
|
31
35
|
'get when(){return t()},get fallback(){return(()=>{var R=x81();return fe(R,ie(lo,{keybinding:" \\u23CE",onClick:E,hintText:"Log in to use Cloud Agents",variant:"secondary",children:"Log in"})),R})()},get children(){return';
|
|
36
|
+
export const CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_7 =
|
|
37
|
+
'get when(){return t()},get fallback(){return(()=>{var R=Swx();return ge(R,ie(go,{keybinding:" \\u23CE",onClick:E,hintText:"Log in to use Cloud Agents",variant:"secondary",children:"Log in"})),R})()},get children(){return';
|
|
38
|
+
export const CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_4 =
|
|
39
|
+
'get when(){return t()},get fallback(){return(()=>{var R=npC();return ke(R,re(ea,{keybinding:" \\u23CE",onClick:E,hintText:"Log in to use Cloud Agents",variant:"secondary",children:"Log in"})),R})()},get children(){return';
|
|
32
40
|
export const CURSOR_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_AUTH_GATE_ANCHOR =
|
|
33
41
|
'get when(){return t()},get fallback(){return(()=>{var D=avx();return Pe(D,he(sl,{keybinding:" \\u23CE",onClick:T,hintText:"Log in to use Cloud Agents",variant:"secondary",children:"Log in"})),D})()},get children(){return';
|
|
34
42
|
export const CURSOR_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_LOGIN_ANCHOR =
|
|
@@ -44,9 +52,13 @@ export const CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR =
|
|
|
44
52
|
'if(L0.localMode){try{g.onNetworkPhaseStart?.()}catch(b){this.logService.warn("[AgentClientService] onNetworkPhaseStart callback failed in local mode",b)}return this.runLocalAgentInExtensionHost(e,t,i,r,s,a,d,h,g)}return this.client.run(e,t,i,r,s,o,a,u,d,h,g)';
|
|
45
53
|
export const CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_LINUX_3_6 =
|
|
46
54
|
'if(uv.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)';
|
|
55
|
+
export const CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_MAC_3_7 =
|
|
56
|
+
'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)';
|
|
57
|
+
export const CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_MAC_3_4 =
|
|
58
|
+
'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)';
|
|
47
59
|
|
|
48
60
|
function buildPlatformModeGuardBootstrapExpression() {
|
|
49
|
-
return '((globalThis.__cursorPoolEnsurePlatformModeGuard||(globalThis.__cursorPoolEnsurePlatformModeGuard=()=>{try{if(globalThis.__cursorPoolPlatformModeGuardReady)return;globalThis.__cursorPoolPlatformModeGuardReady=!0;globalThis.__cursorPoolRuntimeBaseUrl=()=>{try{const e="http://127.0.0.1:56393";if(typeof require!="function")return e;const t=require("node:fs"),r=require("node:os"),o=require("node:path"),n=process?.env?.CURSOR_POOL_RUNTIME_FILE||o.join(r.homedir(),".cursor-pool","runtime.json");if(!t.existsSync(n))return e;const i=JSON.parse(t.readFileSync(n,"utf8"));return i?.host==="127.0.0.1"&&Number.isInteger(i?.port)&&i.port>0&&i.port<65536?`http://127.0.0.1:${i.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?.
|
|
61
|
+
return '((globalThis.__cursorPoolEnsurePlatformModeGuard||(globalThis.__cursorPoolEnsurePlatformModeGuard=()=>{try{if(globalThis.__cursorPoolPlatformModeGuardReady)return;globalThis.__cursorPoolPlatformModeGuardReady=!0;globalThis.__cursorPoolRuntimeBaseUrl=()=>{try{const e="http://127.0.0.1:56393";if(typeof require!="function")return e;const t=require("node:fs"),r=require("node:os"),o=require("node:path"),n=process?.env?.CURSOR_POOL_RUNTIME_FILE||o.join(r.homedir(),".cursor-pool","runtime.json");if(!t.existsSync(n))return e;const i=JSON.parse(t.readFileSync(n,"utf8"));return i?.host==="127.0.0.1"&&Number.isInteger(i?.port)&&i.port>0&&i.port<65536?`http://127.0.0.1:${i.port}`:e}catch{return "http://127.0.0.1:56393"}};globalThis.__cursorPoolStatusAllowsTakeover=e=>{try{return e?.mode?.state==="active"&&e?.mode?.route?.state==="ready"}catch{return!1}};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?.routeToken,a=i&&Date.parse(i.expiresAt)>Date.now();return n?.device?.status==="active"&&n?.platformMode==="active"&&typeof n?.activeProductId==="string"&&typeof n?.platformModeStartedAt==="string"&&a}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=globalThis.__cursorPoolStatusAllowsTakeover?.(e)===!0,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)';
|
|
50
62
|
}
|
|
51
63
|
|
|
52
64
|
const CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION =
|
|
@@ -79,6 +91,7 @@ export function containsCursorWorkbenchAuthGateMarker(content: string) {
|
|
|
79
91
|
export function containsAnyCursorWorkbenchAuthGateMarkerText(content: string) {
|
|
80
92
|
return (
|
|
81
93
|
content.includes(CURSOR_POOL_WORKBENCH_AUTH_GATE_MARKER) ||
|
|
94
|
+
content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V17_PLATFORM_PREFLIGHT') ||
|
|
82
95
|
content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V16_SELF_BOOTSTRAP_PLATFORM_GUARD') ||
|
|
83
96
|
content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V15_RENDERER_STORAGE_GUARD') ||
|
|
84
97
|
content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V14_EXPLICIT_TAKEOVER_SWITCH') ||
|
|
@@ -112,7 +125,7 @@ ${CURSOR_POOL_WORKBENCH_AUTH_GATE_END_MARKER}`;
|
|
|
112
125
|
|
|
113
126
|
function buildPlatformModePreflightSnippet() {
|
|
114
127
|
return `/* ${CURSOR_POOL_WORKBENCH_PREFLIGHT_SIGNATURE}: begin */
|
|
115
|
-
try{const e="http://127.0.0.1:56393/platform/status",t=await Promise.race([fetch(e).then(e=>e.ok?e.json():null),new Promise(e=>setTimeout(()=>e(null),500))]),r=t?.mode?.state==="active";localStorage?.setItem("cursorPoolPlatformModeActive",r?"1":"0"),localStorage?.setItem("cursorPoolPlatformModeCheckedAt",String(Date.now()))}catch{}
|
|
128
|
+
try{const e="http://127.0.0.1:56393/platform/status",t=await Promise.race([fetch(e).then(e=>e.ok?e.json():null),new Promise(e=>setTimeout(()=>e(null),500))]),r=t?.mode?.state==="active"&&t?.mode?.route?.state==="ready";localStorage?.setItem("cursorPoolPlatformModeActive",r?"1":"0"),localStorage?.setItem("cursorPoolPlatformModeCheckedAt",String(Date.now()))}catch{}
|
|
116
129
|
/* ${CURSOR_POOL_WORKBENCH_PREFLIGHT_SIGNATURE}: end */
|
|
117
130
|
`;
|
|
118
131
|
}
|
|
@@ -144,6 +157,8 @@ function forceNativeLocalAgentMode(content: string) {
|
|
|
144
157
|
const runBranchAnchor = [
|
|
145
158
|
CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR,
|
|
146
159
|
CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_LINUX_3_6,
|
|
160
|
+
CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_MAC_3_7,
|
|
161
|
+
CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_MAC_3_4,
|
|
147
162
|
].find((anchor) => withProviderConfig.includes(anchor));
|
|
148
163
|
const runBranchIndex = runBranchAnchor
|
|
149
164
|
? withProviderConfig.indexOf(runBranchAnchor)
|
|
@@ -152,10 +167,20 @@ function forceNativeLocalAgentMode(content: string) {
|
|
|
152
167
|
throw new Error('Cursor Workbench agent client run localMode anchor was not found.');
|
|
153
168
|
}
|
|
154
169
|
const runBranchReplacement = runBranchAnchor!.replace(
|
|
155
|
-
runBranchAnchor!.startsWith('if(uv.localMode)')
|
|
170
|
+
runBranchAnchor!.startsWith('if(uv.localMode)')
|
|
171
|
+
? 'if(uv.localMode)'
|
|
172
|
+
: runBranchAnchor!.startsWith('if(wv.localMode)')
|
|
173
|
+
? 'if(wv.localMode)'
|
|
174
|
+
: runBranchAnchor!.startsWith('if(U0.localMode)')
|
|
175
|
+
? 'if(U0.localMode)'
|
|
176
|
+
: 'if(L0.localMode)',
|
|
156
177
|
runBranchAnchor!.startsWith('if(uv.localMode)')
|
|
157
178
|
? `if(${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}||uv.localMode)`
|
|
158
|
-
:
|
|
179
|
+
: runBranchAnchor!.startsWith('if(wv.localMode)')
|
|
180
|
+
? `if(${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}||wv.localMode)`
|
|
181
|
+
: runBranchAnchor!.startsWith('if(U0.localMode)')
|
|
182
|
+
? `if(${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}||U0.localMode)`
|
|
183
|
+
: `if(${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}||L0.localMode)`,
|
|
159
184
|
);
|
|
160
185
|
return `${withProviderConfig.slice(0, runBranchIndex)}${runBranchReplacement}${withProviderConfig.slice(
|
|
161
186
|
runBranchIndex + runBranchAnchor!.length,
|
|
@@ -171,7 +196,13 @@ export function injectCursorWorkbenchAuthGatePatch(content: string) {
|
|
|
171
196
|
const linux36GateIndex = content.indexOf(
|
|
172
197
|
CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_LINUX_3_6,
|
|
173
198
|
);
|
|
174
|
-
|
|
199
|
+
const mac37GateIndex = content.indexOf(
|
|
200
|
+
CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_7,
|
|
201
|
+
);
|
|
202
|
+
const mac34GateIndex = content.indexOf(
|
|
203
|
+
CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_4,
|
|
204
|
+
);
|
|
205
|
+
if (anchorIndex < 0 && linux36GateIndex < 0 && mac37GateIndex < 0 && mac34GateIndex < 0) {
|
|
175
206
|
throw new Error('Cursor Workbench composer auth gate anchor was not found.');
|
|
176
207
|
}
|
|
177
208
|
|
|
@@ -184,11 +215,25 @@ export function injectCursorWorkbenchAuthGatePatch(content: string) {
|
|
|
184
215
|
const linux36GateIndexWithPreflight = contentWithPreflight.indexOf(
|
|
185
216
|
CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_LINUX_3_6,
|
|
186
217
|
);
|
|
218
|
+
const mac37GateIndexWithPreflight = contentWithPreflight.indexOf(
|
|
219
|
+
CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_7,
|
|
220
|
+
);
|
|
221
|
+
const mac34GateIndexWithPreflight = contentWithPreflight.indexOf(
|
|
222
|
+
CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_4,
|
|
223
|
+
);
|
|
187
224
|
|
|
188
225
|
const withUiGate = anchorIndexWithPreflight >= 0
|
|
189
226
|
? `${contentWithPreflight.slice(0, anchorIndexWithPreflight)}get when(){return (p()||${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION})&&!fzC},${buildCursorWorkbenchAuthGatePatchSnippet()}get fallback(){return he(DGC,{})}${contentWithPreflight.slice(
|
|
190
227
|
anchorIndexWithPreflight + CURSOR_WORKBENCH_COMPOSER_AUTH_GATE_ANCHOR.length,
|
|
191
228
|
)}`
|
|
229
|
+
: mac37GateIndexWithPreflight >= 0
|
|
230
|
+
? `${contentWithPreflight.slice(0, mac37GateIndexWithPreflight)}get when(){return t()||${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}},${buildCursorWorkbenchAuthGatePatchSnippet()}get fallback(){return(()=>{var R=Swx();return ge(R,ie(go,{keybinding:" \\u23CE",onClick:E,hintText:"Log in to use Cloud Agents",variant:"secondary",children:"Log in"})),R})()},get children(){return${contentWithPreflight.slice(
|
|
231
|
+
mac37GateIndexWithPreflight + CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_7.length,
|
|
232
|
+
)}`
|
|
233
|
+
: mac34GateIndexWithPreflight >= 0
|
|
234
|
+
? `${contentWithPreflight.slice(0, mac34GateIndexWithPreflight)}get when(){return t()||${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}},${buildCursorWorkbenchAuthGatePatchSnippet()}get fallback(){return(()=>{var R=npC();return ke(R,re(ea,{keybinding:" \\u23CE",onClick:E,hintText:"Log in to use Cloud Agents",variant:"secondary",children:"Log in"})),R})()},get children(){return${contentWithPreflight.slice(
|
|
235
|
+
mac34GateIndexWithPreflight + CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_4.length,
|
|
236
|
+
)}`
|
|
192
237
|
: `${contentWithPreflight.slice(0, linux36GateIndexWithPreflight)}get when(){return h()||${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}},${buildCursorWorkbenchAuthGatePatchSnippet()}get fallback(){return(()=>{var R=x81();return fe(R,ie(lo,{keybinding:" \\u23CE",onClick:E,hintText:"Log in to use Cloud Agents",variant:"secondary",children:"Log in"})),R})()},get children(){return${contentWithPreflight.slice(
|
|
193
238
|
linux36GateIndexWithPreflight + CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_LINUX_3_6.length,
|
|
194
239
|
)}`;
|
|
@@ -204,7 +249,7 @@ export function injectCursorWorkbenchAuthGatePatch(content: string) {
|
|
|
204
249
|
|
|
205
250
|
const withAgentEditorSubmitGate = withAgentEditorSendButtonGate.includes(
|
|
206
251
|
CURSOR_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_LOGIN_ANCHOR,
|
|
207
|
-
)
|
|
252
|
+
) && mac34GateIndexWithPreflight < 0
|
|
208
253
|
? withAgentEditorSendButtonGate.replace(
|
|
209
254
|
CURSOR_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_LOGIN_ANCHOR,
|
|
210
255
|
`if(!t()&&!${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}){e.cursorAuthenticationService.login();return}`,
|
|
@@ -214,6 +259,8 @@ export function injectCursorWorkbenchAuthGatePatch(content: string) {
|
|
|
214
259
|
const submitGateAnchor = [
|
|
215
260
|
CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR,
|
|
216
261
|
CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_LINUX_3_6,
|
|
262
|
+
CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_7,
|
|
263
|
+
CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4,
|
|
217
264
|
].find((anchor) => withAgentEditorSubmitGate.includes(anchor));
|
|
218
265
|
const submitGateIndex = submitGateAnchor ? withAgentEditorSubmitGate.indexOf(submitGateAnchor) : -1;
|
|
219
266
|
if (submitGateIndex < 0) {
|
|
@@ -222,6 +269,10 @@ export function injectCursorWorkbenchAuthGatePatch(content: string) {
|
|
|
222
269
|
|
|
223
270
|
const submitGateReplacement = submitGateAnchor === CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_LINUX_3_6
|
|
224
271
|
? 'if(!h()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(P5,"general");return}'
|
|
272
|
+
: submitGateAnchor === CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_7
|
|
273
|
+
? 'if(!h()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(a6,"general");return}'
|
|
274
|
+
: submitGateAnchor === CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4
|
|
275
|
+
? 'if(!t()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login();return}'
|
|
225
276
|
: 'if(!p()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(wV,"general");return}';
|
|
226
277
|
const withSubmitGate = `${withAgentEditorSubmitGate.slice(0, submitGateIndex)}${submitGateReplacement}${withAgentEditorSubmitGate.slice(
|
|
227
278
|
submitGateIndex + submitGateAnchor!.length,
|
|
@@ -359,6 +359,26 @@ test('agent exec patch supports the Cursor 3.6 registerAgentExecProvider anchor'
|
|
|
359
359
|
assert.ok(patched.indexOf(CURSOR_POOL_PATCH_SIGNATURE) < patched.indexOf(anchor));
|
|
360
360
|
});
|
|
361
361
|
|
|
362
|
+
test('agent exec patch supports the Cursor 3.7 registerAgentExecProvider anchor', () => {
|
|
363
|
+
const anchor = 'const Et=c.cursor.registerAgentExecProvider(vt);';
|
|
364
|
+
assert.equal(CURSOR_POOL_AGENT_EXEC_PROVIDER_REGISTER_ANCHORS.includes(anchor), true);
|
|
365
|
+
|
|
366
|
+
const patched = injectCursorAgentExecPatchSnippet(`before();${anchor}after();`);
|
|
367
|
+
|
|
368
|
+
assert.equal(patched.includes(CURSOR_POOL_PATCH_SIGNATURE), true);
|
|
369
|
+
assert.ok(patched.indexOf(CURSOR_POOL_PATCH_SIGNATURE) < patched.indexOf(anchor));
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
test('agent exec patch supports the Cursor 3.4 registerAgentExecProvider anchor', () => {
|
|
373
|
+
const anchor = 'const dt=D.cursor.registerAgentExecProvider(ut);';
|
|
374
|
+
assert.equal(CURSOR_POOL_AGENT_EXEC_PROVIDER_REGISTER_ANCHORS.includes(anchor), true);
|
|
375
|
+
|
|
376
|
+
const patched = injectCursorAgentExecPatchSnippet(`before();${anchor}after();`);
|
|
377
|
+
|
|
378
|
+
assert.equal(patched.includes(CURSOR_POOL_PATCH_SIGNATURE), true);
|
|
379
|
+
assert.ok(patched.indexOf(CURSOR_POOL_PATCH_SIGNATURE) < patched.indexOf(anchor));
|
|
380
|
+
});
|
|
381
|
+
|
|
362
382
|
test('agent exec provider wrapper works when Cursor API object is minified as c', async () => {
|
|
363
383
|
const snippet = buildCursorAgentExecPatchSnippet();
|
|
364
384
|
const registered: unknown[] = [];
|
|
@@ -36,6 +36,22 @@ const localProviderConfigAnchor =
|
|
|
36
36
|
'async getLocalAgentProviderConfig(e){const t="[AgentClientService][getLocalAgentProviderConfig]",i=L0.localMode?await this.shellEnvironmentService.getShellEnv():{},r=e?.credentials,s=r?.case==="apiKeyCredentials"?r.value:void 0,o=this.reactiveStorageService.applicationUserPersistentStorage,a=o.useOpenAIKey===!0?this.cursorAuthenticationService.openAIKey()??void 0:void 0,u=xgS({apiKeyCandidates:[{value:s?.apiKey,source:"modelDetails.apiKeyCredentials.apiKey"},{value:a,source:"storage.openAIKey"}],baseUrlCandidates:[{value:s?.baseUrl,source:"modelDetails.apiKeyCredentials.baseUrl"},{value:o.openAIBaseUrl,source:"storage.openAIBaseUrl"}]});return{baseUrl:u.baseUrl,apiKey:u.apiKey}}createDefaultLocalModel(e){return "default"}';
|
|
37
37
|
const agentClientRunLocalModeAnchor =
|
|
38
38
|
'if(L0.localMode){try{g.onNetworkPhaseStart?.()}catch(b){this.logService.warn("[AgentClientService] onNetworkPhaseStart callback failed in local mode",b)}return this.runLocalAgentInExtensionHost(e,t,i,r,s,a,d,h,g)}return this.client.run(e,t,i,r,s,o,a,u,d,h,g)';
|
|
39
|
+
const composerSendButtonAuthGateAnchorMac37 =
|
|
40
|
+
'get when(){return t()},get fallback(){return(()=>{var R=Swx();return ge(R,ie(go,{keybinding:" \\u23CE",onClick:E,hintText:"Log in to use Cloud Agents",variant:"secondary",children:"Log in"})),R})()},get children(){return';
|
|
41
|
+
const composerSubmitAuthGateAnchorMac37 =
|
|
42
|
+
'if(!h()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(a6,"general");return}';
|
|
43
|
+
const localProviderConfigAnchorMac37 =
|
|
44
|
+
'async getLocalAgentProviderConfig(n){const e="[AgentClientService][getLocalAgentProviderConfig]",t=wv.localMode?await this.shellEnvironmentService.getShellEnv():{},i=n?.credentials,r=i?.case==="apiKeyCredentials"?i.value:void 0,s=this.reactiveStorageService.applicationUserPersistentStorage,o=s.useOpenAIKey===!0?this.cursorAuthenticationService.openAIKey()??void 0:void 0,c=xgS({apiKeyCandidates:[{value:r?.apiKey,source:"modelDetails.apiKeyCredentials.apiKey"},{value:o,source:"storage.openAIKey"}],baseUrlCandidates:[{value:r?.baseUrl,source:"modelDetails.apiKeyCredentials.baseUrl"},{value:s.openAIBaseUrl,source:"storage.openAIBaseUrl"}]});return{baseUrl:c.baseUrl,apiKey:c.apiKey}}createDefaultLocalModel(n){return "default"}';
|
|
45
|
+
const agentClientRunLocalModeAnchorMac37 =
|
|
46
|
+
'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)';
|
|
47
|
+
const composerSendButtonAuthGateAnchorMac34 =
|
|
48
|
+
'get when(){return t()},get fallback(){return(()=>{var R=npC();return ke(R,re(ea,{keybinding:" \\u23CE",onClick:E,hintText:"Log in to use Cloud Agents",variant:"secondary",children:"Log in"})),R})()},get children(){return';
|
|
49
|
+
const composerSubmitAuthGateAnchorMac34 =
|
|
50
|
+
'if(!t()){e.cursorAuthenticationService.login();return}';
|
|
51
|
+
const localProviderConfigAnchorMac34 =
|
|
52
|
+
'async getLocalAgentProviderConfig(e){const t="[AgentClientService][getLocalAgentProviderConfig]",i=U0.localMode?await this.shellEnvironmentService.getShellEnv():{},r=e?.credentials,s=r?.case==="apiKeyCredentials"?r.value:void 0,o=this.reactiveStorageService.applicationUserPersistentStorage,a=o.useOpenAIKey===!0?this.cursorAuthenticationService.openAIKey()??void 0:void 0;return{baseUrl:"https://api2.cursor.sh",apiKey:a}}createDefaultLocalModel(e){return "default"}';
|
|
53
|
+
const agentClientRunLocalModeAnchorMac34 =
|
|
54
|
+
'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)';
|
|
39
55
|
|
|
40
56
|
function workbenchFixture(extra = '') {
|
|
41
57
|
return [
|
|
@@ -50,6 +66,27 @@ function workbenchFixture(extra = '') {
|
|
|
50
66
|
].join(';');
|
|
51
67
|
}
|
|
52
68
|
|
|
69
|
+
function workbenchFixtureMac37() {
|
|
70
|
+
return [
|
|
71
|
+
`function composer(){return ge(Mt,{${composerSendButtonAuthGateAnchorMac37}"controls"}})}`,
|
|
72
|
+
`async function submit(){${composerSubmitAuthGateAnchorMac37};return "submitted";}`,
|
|
73
|
+
`function agentEditorControls(){const E=()=>{${agentEditorSendButtonLoginAnchor};return n.handleSubmit()};return "controls"}`,
|
|
74
|
+
`const flags={${buildFlagsLocalModeAnchor}}`,
|
|
75
|
+
localProviderConfigAnchorMac37,
|
|
76
|
+
`async function agentClientRun(){const h={...m,isRunningInTest:m.isRunningInTest??this.environmentService.enableSmokeTestDriver===!0,clientSupportsInlineImages:!0};${agentClientRunLocalModeAnchorMac37}}`,
|
|
77
|
+
].join(';');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function workbenchFixtureMac34() {
|
|
81
|
+
return [
|
|
82
|
+
`function composer(){const E=()=>{${composerSubmitAuthGateAnchorMac34};return n.handleSubmit()};return ke(Mt,{${composerSendButtonAuthGateAnchorMac34}"controls"}})}`,
|
|
83
|
+
`function agentEditorControls(){return "controls"}`,
|
|
84
|
+
`const flags={${buildFlagsLocalModeAnchor}}`,
|
|
85
|
+
localProviderConfigAnchorMac34,
|
|
86
|
+
`async function agentClientRun(){const f={...h,isRunningInTest:h.isRunningInTest??this.environmentService.enableSmokeTestDriver===!0,clientSupportsInlineImages:!0};${agentClientRunLocalModeAnchorMac34}}`,
|
|
87
|
+
].join(';');
|
|
88
|
+
}
|
|
89
|
+
|
|
53
90
|
async function createFixture(
|
|
54
91
|
content = workbenchFixture(),
|
|
55
92
|
) {
|
|
@@ -173,6 +210,48 @@ test('patchCursorWorkbenchAuthGate upgrades old V9 always-active guard from clea
|
|
|
173
210
|
}
|
|
174
211
|
});
|
|
175
212
|
|
|
213
|
+
test('patchCursorWorkbenchAuthGate upgrades old V17 active-only preflight from clean backup', async () => {
|
|
214
|
+
const backupDir = join(tmpdir(), `cursor-pool-workbench-v17-upgrade-${Date.now()}-${Math.random()}`);
|
|
215
|
+
const fixture = await createFixture();
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
const originalContent = await readFile(fixture.targetPath, 'utf8');
|
|
219
|
+
const backupPath = await backupPathForCursorWorkbenchAuthGate(
|
|
220
|
+
fixture.appPath,
|
|
221
|
+
fixture.targetPath,
|
|
222
|
+
backupDir,
|
|
223
|
+
);
|
|
224
|
+
await mkdir(dirname(backupPath), { recursive: true });
|
|
225
|
+
await writeFile(backupPath, originalContent, 'utf8');
|
|
226
|
+
const oldV17Patched = injectCursorWorkbenchAuthGatePatch(originalContent)
|
|
227
|
+
.replaceAll(
|
|
228
|
+
CURSOR_POOL_WORKBENCH_AUTH_GATE_MARKER,
|
|
229
|
+
'CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V17_PLATFORM_PREFLIGHT',
|
|
230
|
+
)
|
|
231
|
+
.replaceAll(
|
|
232
|
+
'e?.mode?.state==="active"&&e?.mode?.route?.state==="ready"',
|
|
233
|
+
'e?.mode?.state==="active"',
|
|
234
|
+
)
|
|
235
|
+
.replaceAll(
|
|
236
|
+
't?.mode?.state==="active"&&t?.mode?.route?.state==="ready"',
|
|
237
|
+
't?.mode?.state==="active"',
|
|
238
|
+
);
|
|
239
|
+
await writeFile(fixture.targetPath, oldV17Patched, 'utf8');
|
|
240
|
+
|
|
241
|
+
const result = await patchCursorWorkbenchAuthGate(fixture.appPath, { backupDir });
|
|
242
|
+
const upgraded = await readFile(fixture.targetPath, 'utf8');
|
|
243
|
+
|
|
244
|
+
assert.notEqual(result.afterHash, result.beforeHash);
|
|
245
|
+
assert.equal(containsCursorWorkbenchAuthGateMarker(upgraded), true);
|
|
246
|
+
assert.equal(upgraded.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V17_PLATFORM_PREFLIGHT'), false);
|
|
247
|
+
assert.equal(upgraded.includes('mode?.state==="active"&&e?.mode?.route?.state==="ready'), true);
|
|
248
|
+
assert.equal(upgraded.includes('t?.mode?.state==="active"&&t?.mode?.route?.state==="ready"'), true);
|
|
249
|
+
} finally {
|
|
250
|
+
await rm(fixture.appPath, { recursive: true, force: true });
|
|
251
|
+
await rm(backupDir, { recursive: true, force: true });
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
|
|
176
255
|
test('workbench auth gate patch keeps the native agent loop instead of appending fake AI bubbles', () => {
|
|
177
256
|
const patched = injectCursorWorkbenchAuthGatePatch(workbenchFixture());
|
|
178
257
|
|
|
@@ -207,6 +286,50 @@ test('workbench auth gate patch delegates agent turns to the local service only
|
|
|
207
286
|
assert.equal(patched.includes('return this.client.run(e,t,i,r,s,o,a,u,d,h,g)'), true);
|
|
208
287
|
});
|
|
209
288
|
|
|
289
|
+
test('workbench auth gate patch supports Cursor 3.7 macOS workbench anchors', () => {
|
|
290
|
+
const patched = injectCursorWorkbenchAuthGatePatch(workbenchFixtureMac37());
|
|
291
|
+
|
|
292
|
+
assert.equal(containsCursorWorkbenchAuthGateMarker(patched), true);
|
|
293
|
+
assert.equal(patched.includes(composerSendButtonAuthGateAnchorMac37), false);
|
|
294
|
+
assert.equal(patched.includes(composerSubmitAuthGateAnchorMac37), false);
|
|
295
|
+
assert.equal(patched.includes(agentClientRunLocalModeAnchorMac37), false);
|
|
296
|
+
assert.equal(
|
|
297
|
+
patched.includes(
|
|
298
|
+
'if(!h()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(a6,"general");return}',
|
|
299
|
+
),
|
|
300
|
+
true,
|
|
301
|
+
);
|
|
302
|
+
assert.equal(
|
|
303
|
+
patched.includes('if(((globalThis.__cursorPoolEnsurePlatformModeGuard||(globalThis.__cursorPoolEnsurePlatformModeGuard=()=>{'),
|
|
304
|
+
true,
|
|
305
|
+
);
|
|
306
|
+
assert.equal(patched.includes('||wv.localMode'), true);
|
|
307
|
+
assert.equal(patched.includes('return this.runLocalAgentInExtensionHost(n,e,t,i,r,o,c,d,h)'), true);
|
|
308
|
+
assert.equal(patched.includes('return this.client.run(n,e,t,i,r,s,o,a,c,d,h)'), true);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test('workbench auth gate patch supports Cursor 3.4 macOS workbench anchors', () => {
|
|
312
|
+
const patched = injectCursorWorkbenchAuthGatePatch(workbenchFixtureMac34());
|
|
313
|
+
|
|
314
|
+
assert.equal(containsCursorWorkbenchAuthGateMarker(patched), true);
|
|
315
|
+
assert.equal(patched.includes(composerSendButtonAuthGateAnchorMac34), false);
|
|
316
|
+
assert.equal(patched.includes(composerSubmitAuthGateAnchorMac34), false);
|
|
317
|
+
assert.equal(patched.includes(agentClientRunLocalModeAnchorMac34), false);
|
|
318
|
+
assert.equal(
|
|
319
|
+
patched.includes(
|
|
320
|
+
'if(!t()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login();return}',
|
|
321
|
+
),
|
|
322
|
+
true,
|
|
323
|
+
);
|
|
324
|
+
assert.equal(
|
|
325
|
+
patched.includes('if(((globalThis.__cursorPoolEnsurePlatformModeGuard||(globalThis.__cursorPoolEnsurePlatformModeGuard=()=>{'),
|
|
326
|
+
true,
|
|
327
|
+
);
|
|
328
|
+
assert.equal(patched.includes('||U0.localMode'), true);
|
|
329
|
+
assert.equal(patched.includes('return this.runLocalAgentInExtensionHost(e,t,i,r,s,a,u,d,f)'), true);
|
|
330
|
+
assert.equal(patched.includes('return this.client.run(e,t,i,r,s,o,a,l,u,d,f)'), true);
|
|
331
|
+
});
|
|
332
|
+
|
|
210
333
|
test('workbench auth gate patch reads the local service port from runtime json', () => {
|
|
211
334
|
const patched = injectCursorWorkbenchAuthGatePatch(workbenchFixture());
|
|
212
335
|
const markerStart = patched.indexOf(CURSOR_POOL_WORKBENCH_NATIVE_LOCAL_AGENT_SIGNATURE);
|
|
@@ -284,6 +407,10 @@ test('workbench platform-mode guard self-bootstraps from the real session file s
|
|
|
284
407
|
platformMode: 'active',
|
|
285
408
|
activeProductId: 'prod_basic',
|
|
286
409
|
platformModeStartedAt: '2026-06-04T03:10:06.880Z',
|
|
410
|
+
routeToken: {
|
|
411
|
+
token: 'rt_secret_value',
|
|
412
|
+
expiresAt: '2999-06-04T03:25:06.880Z',
|
|
413
|
+
},
|
|
287
414
|
};
|
|
288
415
|
const fakeRequire = (moduleName: string) => {
|
|
289
416
|
if (moduleName === 'node:fs') {
|
|
@@ -483,7 +610,15 @@ test('workbench platform-mode runtime guard stores fetched active state and relo
|
|
|
483
610
|
},
|
|
484
611
|
fetch: async (url: string) => {
|
|
485
612
|
fetchedUrl = url;
|
|
486
|
-
return {
|
|
613
|
+
return {
|
|
614
|
+
ok: true,
|
|
615
|
+
json: async () => ({
|
|
616
|
+
mode: {
|
|
617
|
+
state: 'active',
|
|
618
|
+
route: { state: 'ready', expiresAt: '2999-06-01T00:10:00.000Z' },
|
|
619
|
+
},
|
|
620
|
+
}),
|
|
621
|
+
};
|
|
487
622
|
},
|
|
488
623
|
setInterval(callback: () => unknown) {
|
|
489
624
|
timers.push(callback);
|
|
@@ -533,6 +668,54 @@ test('workbench platform-mode runtime guard stores fetched active state and relo
|
|
|
533
668
|
assert.equal(reloads, 1);
|
|
534
669
|
});
|
|
535
670
|
|
|
671
|
+
test('workbench platform-mode runtime guard does not accept active mode with expired route', async () => {
|
|
672
|
+
const patched = injectCursorWorkbenchAuthGatePatch(workbenchFixture());
|
|
673
|
+
const markerStart = patched.indexOf(CURSOR_POOL_WORKBENCH_NATIVE_LOCAL_AGENT_SIGNATURE);
|
|
674
|
+
const objectStart = patched.lastIndexOf('get when()', markerStart);
|
|
675
|
+
const objectEnd = patched.indexOf('get fallback()', markerStart) + 'get fallback(){return he(DGC,{})}'.length;
|
|
676
|
+
const objectLiteral = patched.slice(objectStart, objectEnd);
|
|
677
|
+
const values = new Map([['cursorPoolPlatformModeActive', '0']]);
|
|
678
|
+
const sandboxGlobal = {
|
|
679
|
+
localStorage: {
|
|
680
|
+
getItem(key: string) {
|
|
681
|
+
return values.get(key) ?? null;
|
|
682
|
+
},
|
|
683
|
+
setItem(key: string, value: string) {
|
|
684
|
+
values.set(key, value);
|
|
685
|
+
},
|
|
686
|
+
},
|
|
687
|
+
fetch: async () => ({
|
|
688
|
+
ok: true,
|
|
689
|
+
json: async () => ({
|
|
690
|
+
mode: {
|
|
691
|
+
state: 'active',
|
|
692
|
+
route: { state: 'expired', expiresAt: '2026-06-01T00:10:00.000Z' },
|
|
693
|
+
},
|
|
694
|
+
}),
|
|
695
|
+
}),
|
|
696
|
+
setInterval() {
|
|
697
|
+
return 1;
|
|
698
|
+
},
|
|
699
|
+
setTimeout(callback: () => unknown) {
|
|
700
|
+
callback();
|
|
701
|
+
return 1;
|
|
702
|
+
},
|
|
703
|
+
location: {
|
|
704
|
+
reload() {},
|
|
705
|
+
},
|
|
706
|
+
} as { __cursorPoolIsPlatformModeActive?: () => boolean };
|
|
707
|
+
|
|
708
|
+
new Script(`(({he,DGC,globalThis})=>({${objectLiteral}}))`).runInNewContext({
|
|
709
|
+
he: () => undefined,
|
|
710
|
+
DGC: {},
|
|
711
|
+
globalThis: sandboxGlobal,
|
|
712
|
+
})({ he: () => undefined, DGC: {}, globalThis: sandboxGlobal });
|
|
713
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
714
|
+
|
|
715
|
+
assert.equal(values.get('cursorPoolPlatformModeActive'), '0');
|
|
716
|
+
assert.equal(sandboxGlobal.__cursorPoolIsPlatformModeActive?.(), false);
|
|
717
|
+
});
|
|
718
|
+
|
|
536
719
|
test('workbench platform-mode runtime guard falls back to the default local port without node require', async () => {
|
|
537
720
|
const patched = injectCursorWorkbenchAuthGatePatch(workbenchFixture());
|
|
538
721
|
const markerStart = patched.indexOf(CURSOR_POOL_WORKBENCH_NATIVE_LOCAL_AGENT_SIGNATURE);
|
|
@@ -553,7 +736,15 @@ test('workbench platform-mode runtime guard falls back to the default local port
|
|
|
553
736
|
},
|
|
554
737
|
fetch: async (url: string) => {
|
|
555
738
|
fetchedUrl = url;
|
|
556
|
-
return {
|
|
739
|
+
return {
|
|
740
|
+
ok: true,
|
|
741
|
+
json: async () => ({
|
|
742
|
+
mode: {
|
|
743
|
+
state: 'active',
|
|
744
|
+
route: { state: 'ready', expiresAt: '2999-06-01T00:10:00.000Z' },
|
|
745
|
+
},
|
|
746
|
+
}),
|
|
747
|
+
};
|
|
557
748
|
},
|
|
558
749
|
setInterval() {
|
|
559
750
|
return 1;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cursor-pool/service",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.8",
|
|
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.
|
|
12
|
+
"@cursor-pool/shared": "0.5.8"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {
|
|
15
15
|
"test": "tsx --test test/*.test.ts"
|
|
@@ -61,7 +61,7 @@ export type PlatformModeReleaseReason =
|
|
|
61
61
|
|
|
62
62
|
export type PlatformModeSnapshot =
|
|
63
63
|
| { state: 'inactive'; releaseReason?: PlatformModeReleaseReason; releasedAt?: string }
|
|
64
|
-
| { state: 'active'; productId: string; startedAt: string };
|
|
64
|
+
| { state: 'active'; productId: string; startedAt: string; route?: SafeRouteState };
|
|
65
65
|
|
|
66
66
|
export type PlatformModeResult =
|
|
67
67
|
| PlatformModeSnapshot
|
|
@@ -346,7 +346,7 @@ function asStatus(session: PlatformSession): PlatformStatus {
|
|
|
346
346
|
state: 'logged-in',
|
|
347
347
|
user: session.user,
|
|
348
348
|
device: session.device,
|
|
349
|
-
mode:
|
|
349
|
+
mode: statusModeFromSession(session),
|
|
350
350
|
};
|
|
351
351
|
}
|
|
352
352
|
|
|
@@ -391,6 +391,29 @@ function platformModeFromSession(session: PlatformSession | null): PlatformModeS
|
|
|
391
391
|
return inactiveModeFromSession(session);
|
|
392
392
|
}
|
|
393
393
|
|
|
394
|
+
function routeStateFromSession(session: PlatformSession | null): SafeRouteState {
|
|
395
|
+
const routeToken = session?.routeToken;
|
|
396
|
+
if (!routeToken) {
|
|
397
|
+
return { state: 'missing' };
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
const expiresAt = Date.parse(routeToken.expiresAt);
|
|
401
|
+
if (Number.isNaN(expiresAt)) {
|
|
402
|
+
return { state: 'missing' };
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (expiresAt <= Date.now()) {
|
|
406
|
+
return { state: 'expired', expiresAt: routeToken.expiresAt };
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
return { state: 'ready', expiresAt: routeToken.expiresAt };
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
function statusModeFromSession(session: PlatformSession | null): PlatformModeSnapshot {
|
|
413
|
+
const mode = platformModeFromSession(session);
|
|
414
|
+
return mode.state === 'active' ? { ...mode, route: routeStateFromSession(session) } : mode;
|
|
415
|
+
}
|
|
416
|
+
|
|
394
417
|
function clearPlatformMode(session: PlatformSession): PlatformSession {
|
|
395
418
|
const {
|
|
396
419
|
platformMode: _platformMode,
|
|
@@ -814,11 +837,11 @@ async function statusFromRequestError(
|
|
|
814
837
|
const currentSession = await readPlatformSession(options) ?? session;
|
|
815
838
|
const { mode } = options.releaseActiveModeOnUnauthorized
|
|
816
839
|
? await releaseActivePlatformMode(currentSession, 'invalid-token', options)
|
|
817
|
-
: { mode:
|
|
840
|
+
: { mode: statusModeFromSession(currentSession) };
|
|
818
841
|
return { state: 'invalid-token', user: currentSession.user, device: currentSession.device, mode };
|
|
819
842
|
}
|
|
820
843
|
|
|
821
|
-
return { state: 'offline', user: session.user, device: session.device, mode:
|
|
844
|
+
return { state: 'offline', user: session.user, device: session.device, mode: statusModeFromSession(session) };
|
|
822
845
|
}
|
|
823
846
|
|
|
824
847
|
export async function loginWithCode(options: LoginWithCodeOptions): Promise<PlatformStatus> {
|
|
@@ -886,7 +909,7 @@ export async function platformStatus(options: PlatformSessionOptions = {}): Prom
|
|
|
886
909
|
state: 'logged-in',
|
|
887
910
|
user: released.session.user,
|
|
888
911
|
device: released.session.device,
|
|
889
|
-
mode: released.mode,
|
|
912
|
+
mode: released.mode.state === 'active' ? statusModeFromSession(released.session) : released.mode,
|
|
890
913
|
};
|
|
891
914
|
}
|
|
892
915
|
|
|
@@ -952,7 +975,7 @@ export async function platformCatalog(options: PlatformSessionOptions = {}): Pro
|
|
|
952
975
|
return {
|
|
953
976
|
state: 'logged-in',
|
|
954
977
|
account: { credits: account.value.credits },
|
|
955
|
-
mode,
|
|
978
|
+
mode: mode.state === 'active' ? statusModeFromSession(updatedSession) : mode,
|
|
956
979
|
...(selectedProductId ? { selectedProductId } : {}),
|
|
957
980
|
products: catalogProducts,
|
|
958
981
|
};
|
|
@@ -1159,7 +1182,7 @@ export async function sendHeartbeat(options: SendHeartbeatOptions = {}): Promise
|
|
|
1159
1182
|
state: 'logged-in',
|
|
1160
1183
|
user: released.session.user,
|
|
1161
1184
|
device: released.session.device,
|
|
1162
|
-
mode: released.mode,
|
|
1185
|
+
mode: released.mode.state === 'active' ? statusModeFromSession(released.session) : released.mode,
|
|
1163
1186
|
};
|
|
1164
1187
|
}
|
|
1165
1188
|
|
|
@@ -337,7 +337,7 @@ const poolSession = {
|
|
|
337
337
|
status: 'active' as const,
|
|
338
338
|
startedAt: '2026-05-31T00:00:00.000Z',
|
|
339
339
|
expiresAt: '2026-05-31T01:00:00.000Z',
|
|
340
|
-
routeTokenExpiresAt: '
|
|
340
|
+
routeTokenExpiresAt: '2999-05-31T00:10:00.000Z',
|
|
341
341
|
routeStrategy: 'platform-gateway' as const,
|
|
342
342
|
bannedModels: [],
|
|
343
343
|
capabilities: {
|
|
@@ -1654,6 +1654,7 @@ test('platform mode starts after selected available product and stops while pres
|
|
|
1654
1654
|
state: 'active',
|
|
1655
1655
|
productId: 'prod_basic',
|
|
1656
1656
|
startedAt: started.startedAt,
|
|
1657
|
+
route: { state: 'ready', expiresAt: '2999-05-31T00:10:00.000Z' },
|
|
1657
1658
|
});
|
|
1658
1659
|
|
|
1659
1660
|
const stopped = await stopPlatformMode({ sessionFile });
|
|
@@ -1721,7 +1722,7 @@ test('startPlatformMode creates a pool session and stores route token', async ()
|
|
|
1721
1722
|
assert.deepEqual(saved.poolSession, poolSession);
|
|
1722
1723
|
assert.deepEqual(saved.routeToken, {
|
|
1723
1724
|
token: 'rt_secret_value',
|
|
1724
|
-
expiresAt: '
|
|
1725
|
+
expiresAt: '2999-05-31T00:10:00.000Z',
|
|
1725
1726
|
});
|
|
1726
1727
|
} finally {
|
|
1727
1728
|
await api.close();
|
|
@@ -1776,7 +1777,7 @@ test('startPlatformMode calls default pool session endpoint without body device
|
|
|
1776
1777
|
assert.deepEqual(saved.poolSession, poolSession);
|
|
1777
1778
|
assert.deepEqual(saved.routeToken, {
|
|
1778
1779
|
token: 'rt_secret_value',
|
|
1779
|
-
expiresAt: '
|
|
1780
|
+
expiresAt: '2999-05-31T00:10:00.000Z',
|
|
1780
1781
|
});
|
|
1781
1782
|
} finally {
|
|
1782
1783
|
await api.close();
|
|
@@ -1891,7 +1892,7 @@ test('startPlatformMode sanitizes pool session response before saving', async ()
|
|
|
1891
1892
|
});
|
|
1892
1893
|
assert.deepEqual(saved.routeToken, {
|
|
1893
1894
|
token: 'rt_secret_value',
|
|
1894
|
-
expiresAt: '
|
|
1895
|
+
expiresAt: '2999-05-31T00:10:00.000Z',
|
|
1895
1896
|
});
|
|
1896
1897
|
assert.doesNotMatch(savedText, /discard-me|Bearer secret|rt_nested_secret|sk-secret-token|apiKey=secret/);
|
|
1897
1898
|
} finally {
|