@cursorpool-dev/cli 0.5.8 → 0.5.10

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 (49) hide show
  1. package/node_modules/@cursor-pool/extension/dist/extension.js +46 -116
  2. package/node_modules/@cursor-pool/extension/package.json +3 -3
  3. package/node_modules/@cursor-pool/extension/src/api.ts +2 -17
  4. package/node_modules/@cursor-pool/extension/src/panel.ts +3 -26
  5. package/node_modules/@cursor-pool/extension/test/panel.test.ts +1 -34
  6. package/node_modules/@cursor-pool/patcher/package.json +2 -2
  7. package/node_modules/@cursor-pool/patcher/src/marker.ts +72 -7
  8. package/node_modules/@cursor-pool/patcher/src/workbenchAuthGateMarker.ts +102 -19
  9. package/node_modules/@cursor-pool/patcher/test/patchCursorAgentExec.test.ts +88 -13
  10. package/node_modules/@cursor-pool/patcher/test/patchCursorWorkbench.test.ts +162 -149
  11. package/node_modules/@cursor-pool/service/package.json +2 -2
  12. package/node_modules/@cursor-pool/service/src/platformSession.ts +7 -30
  13. package/node_modules/@cursor-pool/service/src/server.ts +1 -1
  14. package/node_modules/@cursor-pool/service/test/platformSession.test.ts +4 -5
  15. package/node_modules/@cursor-pool/service/test/server.test.ts +1 -130
  16. package/node_modules/@cursor-pool/shared/package.json +1 -1
  17. package/node_modules/@cursor-pool/shared/src/manifest.ts +0 -35
  18. package/node_modules/@cursor-pool/shared/test/manifest.test.ts +9 -43
  19. package/package.json +5 -7
  20. package/src/compat.ts +201 -194
  21. package/src/cursor.ts +45 -4
  22. package/src/extensionBundle.ts +1 -1
  23. package/src/extensionLink.ts +8 -29
  24. package/src/install.ts +10 -62
  25. package/src/installRecord.ts +0 -2
  26. package/src/patchSet.ts +49 -13
  27. package/src/platform.ts +3 -3
  28. package/src/repair.ts +9 -13
  29. package/src/restore.ts +11 -12
  30. package/src/status.ts +5 -9
  31. package/src/target.ts +12 -0
  32. package/src/trial.ts +2 -3
  33. package/src/uninstall.ts +6 -2
  34. package/test/compat.test.ts +146 -192
  35. package/test/cursor.test.ts +54 -0
  36. package/test/e2e-install.test.ts +29 -46
  37. package/test/extensionLink.test.ts +26 -49
  38. package/test/install.test.ts +4 -64
  39. package/test/patchSet.test.ts +71 -0
  40. package/test/repair.test.ts +131 -1
  41. package/test/restore.test.ts +59 -3
  42. package/test/status.test.ts +0 -1
  43. package/test/target.test.ts +28 -0
  44. package/test/trial.test.ts +15 -1
  45. package/node_modules/@cursor-pool/takeover-plans/package.json +0 -12
  46. package/node_modules/@cursor-pool/takeover-plans/src/index.ts +0 -22
  47. package/node_modules/@cursor-pool/takeover-plans/src/plans.ts +0 -37
  48. package/node_modules/@cursor-pool/takeover-plans/src/types.ts +0 -9
  49. package/node_modules/@cursor-pool/takeover-plans/test/registry.test.ts +0 -23
@@ -8,10 +8,16 @@ export const CURSOR_POOL_AGENT_EXEC_PROVIDER_REGISTER_ANCHOR =
8
8
  'const ht=F.cursor.registerAgentExecProvider(mt);';
9
9
  export const CURSOR_POOL_AGENT_EXEC_PROVIDER_REGISTER_ANCHORS = [
10
10
  CURSOR_POOL_AGENT_EXEC_PROVIDER_REGISTER_ANCHOR,
11
+ 'const dt=D.cursor.registerAgentExecProvider(ut);',
11
12
  'const ht=c.cursor.registerAgentExecProvider(mt);',
12
13
  'const Et=c.cursor.registerAgentExecProvider(vt);',
13
- 'const dt=D.cursor.registerAgentExecProvider(ut);',
14
14
  ];
15
+ const CURSOR_AGENT_EXEC_LOCAL_PROVIDER_KIND_ANCHOR =
16
+ 'this.options.localProvider).kind';
17
+ const CURSOR_AGENT_EXEC_LEGACY_LOCAL_CLIENT_OPTIONS =
18
+ 'new t({baseUrl:e.baseUrl,apiKey:e.apiKey,userAgent:e.userAgent,defaultModel:p,privacyMode:e.privacyMode})';
19
+ const CURSOR_AGENT_EXEC_LOCAL_PROVIDER_CLIENT_OPTIONS =
20
+ 'new t({localProvider:{kind:"http",baseUrl:e.baseUrl,apiKey:e.apiKey},userAgent:e.userAgent,defaultModel:p,privacyMode:e.privacyMode})';
15
21
 
16
22
  export function buildCursorAgentExecPatchSnippet() {
17
23
  return `
@@ -88,6 +94,47 @@ ${CURSOR_POOL_PATCH_BEGIN_MARKER}
88
94
  });
89
95
  request.end(body);
90
96
  });
97
+ const rememberTakeover = (takeover) => {
98
+ try {
99
+ if (globalThis.__cursorPoolAgentExecTakeover) {
100
+ globalThis.__cursorPoolAgentExecTakeover.lastTakeover = takeover;
101
+ }
102
+ } catch {}
103
+ };
104
+ const normalizeTakeoverContext = (context) => ({
105
+ requestId:
106
+ context?.requestId ||
107
+ context?.runOptions?.generationUUID ||
108
+ context?.generationUUID,
109
+ modelName:
110
+ context?.modelName ||
111
+ context?.modelDetails?.modelName ||
112
+ context?.modelDetails?.model ||
113
+ context?.defaultModel?.name ||
114
+ context?.defaultModel ||
115
+ 'unknown',
116
+ });
117
+ const wrapCursorPoolSession = (session) => {
118
+ if (!session || session.__cursorPoolWrappedAgentExecSession) {
119
+ return session;
120
+ }
121
+ const wrappedSession = Object.create(Object.getPrototypeOf(session));
122
+ Object.assign(wrappedSession, session);
123
+ if (typeof session.createStream === 'function') {
124
+ wrappedSession.createStream = function(context, requestBytes, abortSignal) {
125
+ const originalStreamFactory = session.createStream.call(session, context, requestBytes, abortSignal);
126
+ if (typeof originalStreamFactory !== 'function') {
127
+ return originalStreamFactory;
128
+ }
129
+ return async function* cursorPoolTakeoverStream(...args) {
130
+ rememberTakeover(await requestCursorPoolTakeover(normalizeTakeoverContext(context)));
131
+ yield* originalStreamFactory.apply(this, args);
132
+ };
133
+ };
134
+ }
135
+ wrappedSession.__cursorPoolWrappedAgentExecSession = true;
136
+ return wrappedSession;
137
+ };
91
138
  const wrapCursorPoolProvider = (provider) => {
92
139
  if (!provider || provider.__cursorPoolWrappedAgentExecProvider) {
93
140
  return provider;
@@ -95,10 +142,15 @@ ${CURSOR_POOL_PATCH_BEGIN_MARKER}
95
142
  const wrapped = Object.create(Object.getPrototypeOf(provider));
96
143
  Object.assign(wrapped, provider);
97
144
  if (typeof provider.runLocalAgent === 'function') {
98
- wrapped.runLocalAgent = provider.runLocalAgent.bind(provider);
145
+ wrapped.runLocalAgent = async function(...args) {
146
+ rememberTakeover(await requestCursorPoolTakeover(normalizeTakeoverContext(args[0])));
147
+ return provider.runLocalAgent.apply(provider, args);
148
+ };
99
149
  }
100
150
  if (typeof provider.createSession === 'function') {
101
- wrapped.createSession = provider.createSession.bind(provider);
151
+ wrapped.createSession = function(...args) {
152
+ return wrapCursorPoolSession(provider.createSession.apply(provider, args));
153
+ };
102
154
  }
103
155
  if (typeof provider.fetchLocalProviderModels === 'function') {
104
156
  wrapped.fetchLocalProviderModels = provider.fetchLocalProviderModels.bind(provider);
@@ -111,9 +163,7 @@ ${CURSOR_POOL_PATCH_BEGIN_MARKER}
111
163
  ? F
112
164
  : typeof c !== 'undefined' && c.cursor?.registerAgentExecProvider
113
165
  ? c
114
- : typeof D !== 'undefined' && D.cursor?.registerAgentExecProvider
115
- ? D
116
- : undefined;
166
+ : undefined;
117
167
  if (cursorApi?.cursor?.registerAgentExecProvider) {
118
168
  const originalRegisterAgentExecProvider = cursorApi.cursor.registerAgentExecProvider.bind(cursorApi.cursor);
119
169
  cursorApi.cursor.registerAgentExecProvider = (provider) =>
@@ -137,7 +187,22 @@ export function injectCursorAgentExecPatchSnippet(content: string) {
137
187
  if (anchorIndex < 0) {
138
188
  throw new Error('Cursor Agent Exec provider registration anchor was not found.');
139
189
  }
140
- return `${content.slice(0, anchorIndex)}${snippet}${content.slice(anchorIndex)}`;
190
+ const contentWithLocalProviderOptions = content.includes(CURSOR_AGENT_EXEC_LOCAL_PROVIDER_KIND_ANCHOR)
191
+ ? content.replace(
192
+ CURSOR_AGENT_EXEC_LEGACY_LOCAL_CLIENT_OPTIONS,
193
+ CURSOR_AGENT_EXEC_LOCAL_PROVIDER_CLIENT_OPTIONS,
194
+ )
195
+ : content;
196
+ const adjustedAnchorIndex = anchor
197
+ ? contentWithLocalProviderOptions.indexOf(anchor)
198
+ : -1;
199
+ if (
200
+ content.includes(CURSOR_AGENT_EXEC_LOCAL_PROVIDER_KIND_ANCHOR) &&
201
+ contentWithLocalProviderOptions === content
202
+ ) {
203
+ throw new Error('Cursor Agent Exec local provider client options anchor was not found.');
204
+ }
205
+ return `${contentWithLocalProviderOptions.slice(0, adjustedAnchorIndex)}${snippet}${contentWithLocalProviderOptions.slice(adjustedAnchorIndex)}`;
141
206
  }
142
207
 
143
208
  export function containsCursorPoolMarker(content: string) {
@@ -1,5 +1,5 @@
1
1
  export const CURSOR_POOL_WORKBENCH_AUTH_GATE_MARKER =
2
- 'CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V18_ROUTE_READY_GUARD';
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 =
@@ -16,10 +16,14 @@ export const CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_SIGNATURE =
16
16
  '__cursorPoolWorkbenchAgentEditorSendButton';
17
17
  export const CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SUBMIT_SIGNATURE =
18
18
  '__cursorPoolWorkbenchAgentEditorSubmit';
19
+ export const CURSOR_POOL_WORKBENCH_AGENT_EDITOR_CURSOR_AI_LOGIN_SIGNATURE =
20
+ '__cursorPoolWorkbenchAgentEditorCursorAiLogin';
19
21
  export const CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE =
20
22
  '__cursorPoolWorkbenchRuntimeBaseUrl';
21
23
  export const CURSOR_POOL_WORKBENCH_PREFLIGHT_SIGNATURE =
22
24
  '__cursorPoolWorkbenchPlatformModePreflight';
25
+ export const CURSOR_POOL_WORKBENCH_LOGGED_OUT_GLASS_SIGNATURE =
26
+ '__cursorPoolWorkbenchLoggedOutGlassBypass';
23
27
 
24
28
  export const CURSOR_WORKBENCH_COMPOSER_AUTH_GATE_ANCHOR =
25
29
  'get when(){return p()&&!fzC},get fallback(){return he(DGC,{})}';
@@ -31,6 +35,8 @@ export const CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_7 =
31
35
  'if(!h()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(a6,"general");return}';
32
36
  export const CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4 =
33
37
  'if(!t()){e.cursorAuthenticationService.login();return}';
38
+ export const CURSOR_WORKBENCH_MAIN_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4 =
39
+ 'if(!v()){e.cursorAuthenticationService.login(),e.commandService.executeCommand($6,"general");return}';
34
40
  export const CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_LINUX_3_6 =
35
41
  '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
42
  export const CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_7 =
@@ -41,6 +47,14 @@ export const CURSOR_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_AUTH_GATE_ANCHOR =
41
47
  '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';
42
48
  export const CURSOR_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_LOGIN_ANCHOR =
43
49
  'if(!t()){e.cursorAuthenticationService.login();return}';
50
+ export const CURSOR_WORKBENCH_AGENT_EDITOR_CURSOR_AI_LOGIN_BUTTON_ANCHOR_LINUX_3_6 =
51
+ 'return ie(lo,{get keybinding(){return e()},onClick:()=>{n.cursorAuthenticationService.login()},hintText:"Log in to use Cursor AI features",variant:"secondary",style:{"margin-left":"auto"},children:"Log in"})';
52
+ export const CURSOR_WORKBENCH_AGENT_EDITOR_BOTTOM_BAR_AUTH_GATE_ANCHOR_LINUX_3_6 =
53
+ 'get when(){return h()&&!Xk1},get fallback(){return ie(X_1,{})},get children(){return ie(i01,';
54
+ export const CURSOR_WORKBENCH_AGENT_EDITOR_BOTTOM_BAR_AUTH_GATE_ANCHOR_MAC_3_7 =
55
+ 'get when(){return h()&&!rYT},get fallback(){return ie(CzT,{})},get children(){return ie(AVT,';
56
+ export const CURSOR_WORKBENCH_AGENT_EDITOR_BOTTOM_BAR_AUTH_GATE_ANCHOR_MAC_3_4 =
57
+ 'get when(){return v()&&!HG1},get fallback(){return re(s71,{})},get children(){return re(u$1,';
44
58
  export const CURSOR_WORKBENCH_AGENT_LOOP_RUN_ANCHOR =
45
59
  'await this.agentClientService.run(te,H,$e,Ne,Ce,T,ze,me,we,[],ct)';
46
60
  export const CURSOR_WORKBENCH_BUILD_FLAGS_LOCAL_MODE_ANCHOR = 'localMode:!1';
@@ -56,9 +70,11 @@ export const CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_MAC_3_7 =
56
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)';
57
71
  export const CURSOR_WORKBENCH_AGENT_CLIENT_RUN_LOCAL_MODE_ANCHOR_MAC_3_4 =
58
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})';
59
75
 
60
76
  function buildPlatformModeGuardBootstrapExpression() {
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)';
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)';
62
78
  }
63
79
 
64
80
  const CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION =
@@ -84,7 +100,13 @@ export function containsCursorWorkbenchAuthGateMarker(content: string) {
84
100
  .includes(CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SUBMIT_SIGNATURE) &&
85
101
  content
86
102
  .slice(beginIndex, endIndex)
87
- .includes(CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE)
103
+ .includes(CURSOR_POOL_WORKBENCH_AGENT_EDITOR_CURSOR_AI_LOGIN_SIGNATURE) &&
104
+ content
105
+ .slice(beginIndex, endIndex)
106
+ .includes(CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE) &&
107
+ content
108
+ .slice(beginIndex, endIndex)
109
+ .includes(CURSOR_POOL_WORKBENCH_LOGGED_OUT_GLASS_SIGNATURE)
88
110
  );
89
111
  }
90
112
 
@@ -92,6 +114,7 @@ export function containsAnyCursorWorkbenchAuthGateMarkerText(content: string) {
92
114
  return (
93
115
  content.includes(CURSOR_POOL_WORKBENCH_AUTH_GATE_MARKER) ||
94
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') ||
95
118
  content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V16_SELF_BOOTSTRAP_PLATFORM_GUARD') ||
96
119
  content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V15_RENDERER_STORAGE_GUARD') ||
97
120
  content.includes('CURSOR_POOL_MVP1_WORKBENCH_AUTH_GATE_PATCH_V14_EXPLICIT_TAKEOVER_SWITCH') ||
@@ -107,7 +130,9 @@ export function containsAnyCursorWorkbenchAuthGateMarkerText(content: string) {
107
130
  content.includes(CURSOR_POOL_WORKBENCH_NATIVE_LOCAL_AGENT_SIGNATURE) ||
108
131
  content.includes(CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_SIGNATURE) ||
109
132
  content.includes(CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SUBMIT_SIGNATURE) ||
110
- content.includes(CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE)
133
+ content.includes(CURSOR_POOL_WORKBENCH_AGENT_EDITOR_CURSOR_AI_LOGIN_SIGNATURE) ||
134
+ content.includes(CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE) ||
135
+ content.includes(CURSOR_POOL_WORKBENCH_LOGGED_OUT_GLASS_SIGNATURE)
111
136
  );
112
137
  }
113
138
 
@@ -118,14 +143,16 @@ export function buildCursorWorkbenchAuthGatePatchSnippet() {
118
143
  ["${CURSOR_POOL_WORKBENCH_AGENT_LOOP_SIGNATURE}"]:true,
119
144
  ["${CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_SIGNATURE}"]:true,
120
145
  ["${CURSOR_POOL_WORKBENCH_AGENT_EDITOR_SUBMIT_SIGNATURE}"]:true,
146
+ ["${CURSOR_POOL_WORKBENCH_AGENT_EDITOR_CURSOR_AI_LOGIN_SIGNATURE}"]:true,
121
147
  ["${CURSOR_POOL_WORKBENCH_RUNTIME_BASE_URL_SIGNATURE}"]:true,
148
+ ["${CURSOR_POOL_WORKBENCH_LOGGED_OUT_GLASS_SIGNATURE}"]:true,
122
149
  ["${CURSOR_POOL_WORKBENCH_NATIVE_LOCAL_AGENT_SIGNATURE}"]:(${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION},void 0),
123
150
  ${CURSOR_POOL_WORKBENCH_AUTH_GATE_END_MARKER}`;
124
151
  }
125
152
 
126
153
  function buildPlatformModePreflightSnippet() {
127
154
  return `/* ${CURSOR_POOL_WORKBENCH_PREFLIGHT_SIGNATURE}: begin */
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{}
155
+ 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{}
129
156
  /* ${CURSOR_POOL_WORKBENCH_PREFLIGHT_SIGNATURE}: end */
130
157
  `;
131
158
  }
@@ -138,6 +165,22 @@ function buildLocalProviderConfigReplacement() {
138
165
  return 'async getLocalAgentProviderConfig(e){const t="[AgentClientService][getLocalAgentProviderConfig]",r=globalThis.__cursorPoolRuntimeBaseUrl?.()||"http://127.0.0.1:56393",i={baseUrl:r,apiKey:"cursor-pool-local"};try{this.logService.info(`${t} resolved`,{apiKeySource:"cursor-pool-local",hasApiKey:!0,baseUrlSource:"cursor-pool-runtime",normalizedBaseUrl:i.baseUrl,normalizationChangedUrl:!1})}catch{}return i}';
139
166
  }
140
167
 
168
+ function buildComposerSubmitAuthGateReplacement(anchor: string) {
169
+ if (anchor === CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_LINUX_3_6) {
170
+ return 'if(!h()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(P5,"general");return}';
171
+ }
172
+ if (anchor === CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_7) {
173
+ return 'if(!h()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(a6,"general");return}';
174
+ }
175
+ if (anchor === CURSOR_WORKBENCH_MAIN_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4) {
176
+ return 'if(!v()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login(),e.commandService.executeCommand($6,"general");return}';
177
+ }
178
+ if (anchor === CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4) {
179
+ return `if(!t()&&!${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}){e.cursorAuthenticationService.login();return}`;
180
+ }
181
+ return 'if(!p()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(wV,"general");return}';
182
+ }
183
+
141
184
  function forceNativeLocalAgentMode(content: string) {
142
185
  if (!content.includes(CURSOR_WORKBENCH_BUILD_FLAGS_LOCAL_MODE_ANCHOR)) {
143
186
  throw new Error('Cursor Workbench localMode build flag anchor was not found.');
@@ -249,34 +292,74 @@ export function injectCursorWorkbenchAuthGatePatch(content: string) {
249
292
 
250
293
  const withAgentEditorSubmitGate = withAgentEditorSendButtonGate.includes(
251
294
  CURSOR_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_LOGIN_ANCHOR,
252
- ) && mac34GateIndexWithPreflight < 0
295
+ )
253
296
  ? withAgentEditorSendButtonGate.replace(
254
297
  CURSOR_WORKBENCH_AGENT_EDITOR_SEND_BUTTON_LOGIN_ANCHOR,
255
298
  `if(!t()&&!${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION}){e.cursorAuthenticationService.login();return}`,
256
299
  )
257
300
  : withAgentEditorSendButtonGate;
258
301
 
302
+ const withAgentEditorCursorAiLoginGate = withAgentEditorSubmitGate.includes(
303
+ CURSOR_WORKBENCH_AGENT_EDITOR_BOTTOM_BAR_AUTH_GATE_ANCHOR_LINUX_3_6,
304
+ )
305
+ ? withAgentEditorSubmitGate.replace(
306
+ CURSOR_WORKBENCH_AGENT_EDITOR_BOTTOM_BAR_AUTH_GATE_ANCHOR_LINUX_3_6,
307
+ `get when(){return (h()||${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION})&&!Xk1},get fallback(){return ie(X_1,{})},get children(){return ie(i01,`,
308
+ )
309
+ : withAgentEditorSubmitGate.includes(
310
+ CURSOR_WORKBENCH_AGENT_EDITOR_BOTTOM_BAR_AUTH_GATE_ANCHOR_MAC_3_7,
311
+ )
312
+ ? withAgentEditorSubmitGate.replace(
313
+ CURSOR_WORKBENCH_AGENT_EDITOR_BOTTOM_BAR_AUTH_GATE_ANCHOR_MAC_3_7,
314
+ `get when(){return (h()||${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION})&&!rYT},get fallback(){return ie(CzT,{})},get children(){return ie(AVT,`,
315
+ )
316
+ : withAgentEditorSubmitGate.includes(
317
+ CURSOR_WORKBENCH_AGENT_EDITOR_BOTTOM_BAR_AUTH_GATE_ANCHOR_MAC_3_4,
318
+ )
319
+ ? withAgentEditorSubmitGate.replace(
320
+ CURSOR_WORKBENCH_AGENT_EDITOR_BOTTOM_BAR_AUTH_GATE_ANCHOR_MAC_3_4,
321
+ `get when(){return (v()||${CURSOR_POOL_PLATFORM_MODE_GUARD_EXPRESSION})&&!HG1},get fallback(){return re(s71,{})},get children(){return re(u$1,`,
322
+ )
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
+
259
334
  const submitGateAnchor = [
260
335
  CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR,
261
336
  CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_LINUX_3_6,
262
337
  CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_7,
263
338
  CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4,
264
- ].find((anchor) => withAgentEditorSubmitGate.includes(anchor));
265
- const submitGateIndex = submitGateAnchor ? withAgentEditorSubmitGate.indexOf(submitGateAnchor) : -1;
266
- if (submitGateIndex < 0) {
339
+ CURSOR_WORKBENCH_MAIN_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4,
340
+ ].find((anchor) => withLoggedOutGlassGate.includes(anchor));
341
+ const submitGateIndex = submitGateAnchor ? withLoggedOutGlassGate.indexOf(submitGateAnchor) : -1;
342
+ const mac34SubmitReplacement = buildComposerSubmitAuthGateReplacement(
343
+ CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_MAC_3_4,
344
+ );
345
+ const isMac34ComposerPatch = contentWithPreflight.includes(
346
+ CURSOR_WORKBENCH_COMPOSER_SEND_BUTTON_AUTH_GATE_ANCHOR_MAC_3_4,
347
+ );
348
+ if (
349
+ submitGateIndex < 0 &&
350
+ !(isMac34ComposerPatch && withLoggedOutGlassGate.includes(mac34SubmitReplacement))
351
+ ) {
267
352
  throw new Error('Cursor Workbench composer submit auth gate anchor was not found.');
268
353
  }
269
354
 
270
- const submitGateReplacement = submitGateAnchor === CURSOR_WORKBENCH_COMPOSER_SUBMIT_AUTH_GATE_ANCHOR_LINUX_3_6
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}'
276
- : 'if(!p()&&!globalThis.__cursorPoolIsPlatformModeActive?.()){e.cursorAuthenticationService.login(),e.commandService.executeCommand(wV,"general");return}';
277
- const withSubmitGate = `${withAgentEditorSubmitGate.slice(0, submitGateIndex)}${submitGateReplacement}${withAgentEditorSubmitGate.slice(
278
- submitGateIndex + submitGateAnchor!.length,
279
- )}`;
355
+ const submitGateReplacement = submitGateAnchor
356
+ ? buildComposerSubmitAuthGateReplacement(submitGateAnchor)
357
+ : '';
358
+ const withSubmitGate = submitGateIndex >= 0
359
+ ? `${withLoggedOutGlassGate.slice(0, submitGateIndex)}${submitGateReplacement}${withLoggedOutGlassGate.slice(
360
+ submitGateIndex + submitGateAnchor!.length,
361
+ )}`
362
+ : withLoggedOutGlassGate;
280
363
 
281
364
  const agentLoopIndex = withSubmitGate.indexOf(CURSOR_WORKBENCH_AGENT_LOOP_RUN_ANCHOR);
282
365
  if (
@@ -349,8 +349,8 @@ test('agent exec patch injects the wrapper before Cursor registers the provider'
349
349
  );
350
350
  });
351
351
 
352
- test('agent exec patch supports the Cursor 3.6 registerAgentExecProvider anchor', () => {
353
- const anchor = 'const ht=c.cursor.registerAgentExecProvider(mt);';
352
+ test('agent exec patch supports the Cursor 3.4 registerAgentExecProvider anchor', () => {
353
+ const anchor = 'const dt=D.cursor.registerAgentExecProvider(ut);';
354
354
  assert.equal(CURSOR_POOL_AGENT_EXEC_PROVIDER_REGISTER_ANCHORS.includes(anchor), true);
355
355
 
356
356
  const patched = injectCursorAgentExecPatchSnippet(`before();${anchor}after();`);
@@ -359,8 +359,8 @@ 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);';
362
+ test('agent exec patch supports the Cursor 3.6 registerAgentExecProvider anchor', () => {
363
+ const anchor = 'const ht=c.cursor.registerAgentExecProvider(mt);';
364
364
  assert.equal(CURSOR_POOL_AGENT_EXEC_PROVIDER_REGISTER_ANCHORS.includes(anchor), true);
365
365
 
366
366
  const patched = injectCursorAgentExecPatchSnippet(`before();${anchor}after();`);
@@ -369,8 +369,8 @@ test('agent exec patch supports the Cursor 3.7 registerAgentExecProvider anchor'
369
369
  assert.ok(patched.indexOf(CURSOR_POOL_PATCH_SIGNATURE) < patched.indexOf(anchor));
370
370
  });
371
371
 
372
- test('agent exec patch supports the Cursor 3.4 registerAgentExecProvider anchor', () => {
373
- const anchor = 'const dt=D.cursor.registerAgentExecProvider(ut);';
372
+ test('agent exec patch supports the Cursor 3.7 registerAgentExecProvider anchor', () => {
373
+ const anchor = 'const Et=c.cursor.registerAgentExecProvider(vt);';
374
374
  assert.equal(CURSOR_POOL_AGENT_EXEC_PROVIDER_REGISTER_ANCHORS.includes(anchor), true);
375
375
 
376
376
  const patched = injectCursorAgentExecPatchSnippet(`before();${anchor}after();`);
@@ -379,6 +379,31 @@ test('agent exec patch supports the Cursor 3.4 registerAgentExecProvider anchor'
379
379
  assert.ok(patched.indexOf(CURSOR_POOL_PATCH_SIGNATURE) < patched.indexOf(anchor));
380
380
  });
381
381
 
382
+ test('agent exec patch normalizes Cursor 3.7 LocalAgentClient options to include a localProvider', () => {
383
+ const content = [
384
+ 'class E9{async run(e,t,n,r,s,o,i,a,l,c,u){',
385
+ 'const A="bedrock"===(y=this.options.localProvider).kind?`bedrock:${y.region}`:y.baseUrl;',
386
+ 'const{LocalAgentClient:t}=await Be(),r=new t({baseUrl:e.baseUrl,apiKey:e.apiKey,userAgent:e.userAgent,defaultModel:p,privacyMode:e.privacyMode});',
387
+ '}}',
388
+ 'const Et=c.cursor.registerAgentExecProvider(vt);',
389
+ ].join('');
390
+
391
+ const patched = injectCursorAgentExecPatchSnippet(content);
392
+
393
+ assert.equal(
394
+ patched.includes(
395
+ 'new t({localProvider:{kind:"http",baseUrl:e.baseUrl,apiKey:e.apiKey},userAgent:e.userAgent,defaultModel:p,privacyMode:e.privacyMode})',
396
+ ),
397
+ true,
398
+ );
399
+ assert.equal(
400
+ patched.includes(
401
+ 'new t({baseUrl:e.baseUrl,apiKey:e.apiKey,userAgent:e.userAgent,defaultModel:p,privacyMode:e.privacyMode})',
402
+ ),
403
+ false,
404
+ );
405
+ });
406
+
382
407
  test('agent exec provider wrapper works when Cursor API object is minified as c', async () => {
383
408
  const snippet = buildCursorAgentExecPatchSnippet();
384
409
  const registered: unknown[] = [];
@@ -408,7 +433,27 @@ const require = (specifier) => {
408
433
  return { join: (...parts) => parts.join('/') };
409
434
  }
410
435
  if (specifier === 'node:http') {
411
- return { request() { return { on() { return this; }, end() {}, destroy() {} }; } };
436
+ return {
437
+ request(_options, callback) {
438
+ return {
439
+ on() { return this; },
440
+ end() {
441
+ callback({
442
+ setEncoding() {},
443
+ on(event, handler) {
444
+ if (event === 'data') {
445
+ handler(JSON.stringify({ state: 'rejected', requestId: 'takeover-1', reason: 'invalid-session' }));
446
+ }
447
+ if (event === 'end') {
448
+ handler();
449
+ }
450
+ },
451
+ });
452
+ },
453
+ destroy() {},
454
+ };
455
+ },
456
+ };
412
457
  }
413
458
  throw new Error('unexpected require ' + specifier);
414
459
  };
@@ -433,7 +478,7 @@ return registered[0];`,
433
478
  assert.equal(await wrappedProvider.runLocalAgent(), 'ok');
434
479
  });
435
480
 
436
- test('agent exec provider wrapper preserves original runLocalAgent so Cursor local client can consume OpenAI endpoint', async () => {
481
+ test('agent exec provider wrapper records takeover before preserving original runLocalAgent', async () => {
437
482
  const snippet = buildCursorAgentExecPatchSnippet();
438
483
  const runtime = { host: '127.0.0.1', port: 32123, runtimeId: 'runtime-test' };
439
484
  const calls: string[] = [];
@@ -528,6 +573,8 @@ return registered[0];`,
528
573
  const wrappedProvider = registered[0] as typeof originalProvider;
529
574
  await wrappedProvider.runLocalAgent(
530
575
  {
576
+ requestId: 'agent-req-1',
577
+ modelName: 'gpt-test',
531
578
  runOptions: { generationUUID: 'req-1' },
532
579
  modelDetails: undefined,
533
580
  defaultModel: undefined,
@@ -535,11 +582,25 @@ return registered[0];`,
535
582
  {},
536
583
  );
537
584
 
538
- assert.deepEqual(calls, ['original-runLocalAgent']);
539
- assert.equal((sandbox.globalThis.__cursorPoolAgentExecTakeover as { lastAnswer?: unknown }).lastAnswer, undefined);
585
+ assert.equal(calls.length, 2);
586
+ assert.deepEqual(JSON.parse(calls[0]!), {
587
+ requestId: 'agent-req-1',
588
+ source: 'cursor-agent-exec',
589
+ model: 'gpt-test',
590
+ stream: true,
591
+ bodyShape: 'redacted',
592
+ });
593
+ assert.equal(calls[1], 'original-runLocalAgent');
594
+ assert.deepEqual((sandbox.globalThis.__cursorPoolAgentExecTakeover as { lastTakeover?: unknown }).lastTakeover, {
595
+ state: 'answered',
596
+ requestId: 'takeover-1',
597
+ source: 'cursor-agent-exec',
598
+ model: 'gpt-test',
599
+ content: '来自 Cursor Pool 本地测试 provider',
600
+ });
540
601
  });
541
602
 
542
- test('agent exec provider wrapper preserves original createStream so Cursor stream frames are not swallowed', async () => {
603
+ test('agent exec provider wrapper records takeover before preserving original createStream', async () => {
543
604
  const snippet = buildCursorAgentExecPatchSnippet();
544
605
  const runtime = { host: '127.0.0.1', port: 32123, runtimeId: 'runtime-test' };
545
606
  const calls: string[] = [];
@@ -644,7 +705,21 @@ return registered[0];`,
644
705
  frames.push(frame);
645
706
  }
646
707
 
647
- assert.deepEqual(calls, ['original-createStream']);
708
+ assert.equal(calls.length, 2);
709
+ assert.deepEqual(JSON.parse(calls[0]!), {
710
+ requestId: 'stream-1',
711
+ source: 'cursor-agent-exec',
712
+ model: 'gpt-test',
713
+ stream: true,
714
+ bodyShape: 'redacted',
715
+ });
716
+ assert.equal(calls[1], 'original-createStream');
648
717
  assert.deepEqual(frames, [originalFrame]);
649
- assert.equal((sandbox.globalThis.__cursorPoolAgentExecTakeover as { lastAnswer?: unknown }).lastAnswer, undefined);
718
+ assert.deepEqual((sandbox.globalThis.__cursorPoolAgentExecTakeover as { lastTakeover?: unknown }).lastTakeover, {
719
+ state: 'answered',
720
+ requestId: 'takeover-1',
721
+ source: 'cursor-agent-exec',
722
+ model: 'gpt-test',
723
+ content: '来自 Cursor Pool 本地测试 provider',
724
+ });
650
725
  });