pi-cursor-bridge 0.2.4-macos.0 → 0.2.5

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursor-bridge",
3
- "version": "6.0.3+codex.20260916040500",
3
+ "version": "6.0.5+codex.20260922110122",
4
4
  "description": "Evidence-backed Cursor Context Engine search and bounded Cursor Agent execution, including a UI-suppressed minimal runtime.",
5
5
  "author": {
6
6
  "name": "Vanyangyang"
package/README.md CHANGED
@@ -1,15 +1,17 @@
1
1
  # Cursor Bridge for Pi
2
2
 
3
+ > **Windows only:** Cursor Bridge currently supports Windows only. macOS and Linux are not supported or covered by end-to-end acceptance.
4
+
3
5
  Use Cursor's project index and Agent search from Pi, with compact `path:line` evidence and optional bounded Cursor task execution.
4
6
 
5
7
  ⭐ If Cursor Bridge helps you, please consider giving it a Star on GitHub—it helps others discover the project.
6
8
 
7
9
  ```powershell
8
- pi install npm:pi-cursor-bridge@0.2.4-macos.0
10
+ pi install npm:pi-cursor-bridge
9
11
  ```
10
12
 
11
- This is a macOS CDP identity trial. It does not replace the stable `pi-cursor-bridge@0.2.3` release. Restart Pi after installation. Initialize the current project by asking Pi to initialize Cursor Bridge for the absolute project path, then use it normally. The package includes the `cce-routing` and `cursor-delegate` Skills and registers the native Cursor Bridge MCP tools directly in Pi.
13
+ Restart Pi after installation. Initialize the current project by asking Pi to initialize Cursor Bridge for the absolute project path, then use it normally. The package includes the `cce-routing` and `cursor-delegate` Skills and registers the native Cursor Bridge MCP tools directly in Pi.
12
14
 
13
- Pi wrapper 0.2.4-macos.0 embeds Cursor Bridge 6.0.3 plus the macOS `Cursor.app` CDP identity matcher. `cursor_status.pluginVersion` may still report `6.0.3`. Confirm the installed wrapper is `0.2.4-macos.0`. Its result contract returns a compact receipt for background `cursor_do` work: poll `cursor_status(task_id)` normally, retrieve the terminal raw reply with `cursor_status(task_id, detail="result")`, check `isError` before using its content, and use `detail="full"` only when diagnostics are needed. Cursor must be installed and signed in. Current end-to-end compatibility claims remain scoped to the environments documented in the main repository.
15
+ Pi wrapper 0.2.5 embeds Cursor Bridge 6.0.5, including Cursor 3.21 model-provider alias matching and `reasoning_effort` verification for Grok 4.7/high. Its result contract returns a compact receipt for background `cursor_do` work: poll `cursor_status(task_id)` normally, retrieve the terminal raw reply with `cursor_status(task_id, detail="result")`, check `isError` before using its content, and use `detail="full"` only when diagnostics are needed. Cursor must be installed and signed in. Current end-to-end compatibility claims remain scoped to the environments documented in the main repository.
14
16
 
15
17
  Full documentation: [English](https://github.com/Vanyangyang/cursor-bridge#readme) · [简体中文](https://github.com/Vanyangyang/cursor-bridge/blob/main/README.zh-CN.md)
@@ -3115,6 +3115,7 @@ var require_utils = __commonJS({
3115
3115
  "use strict";
3116
3116
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3117
3117
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
3118
+ var isPort = RegExp.prototype.test.bind(/^\d*$/u);
3118
3119
  var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
3119
3120
  var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
3120
3121
  var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
@@ -3580,8 +3581,12 @@ var require_utils = __commonJS({
3580
3581
  uriTokens.push(host);
3581
3582
  }
3582
3583
  if (typeof component.port === "number" || typeof component.port === "string") {
3584
+ const port = String(component.port);
3585
+ if (!isPort(port)) {
3586
+ throw new TypeError("URI port is malformed.");
3587
+ }
3583
3588
  uriTokens.push(":");
3584
- uriTokens.push(String(component.port));
3589
+ uriTokens.push(port);
3585
3590
  }
3586
3591
  return uriTokens.length ? uriTokens.join("") : void 0;
3587
3592
  }
@@ -4024,12 +4029,15 @@ var require_fast_uri = __commonJS({
4024
4029
  }
4025
4030
  return false;
4026
4031
  }
4032
+ function isIPLiteral(host) {
4033
+ return host[0] === "[" && host[host.length - 1] === "]";
4034
+ }
4027
4035
  function hasMalformedComponentPercentEncoding(matches) {
4028
4036
  const host = matches[4];
4029
- return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !(host[0] === "[" && host[host.length - 1] === "]") && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4037
+ return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4030
4038
  }
4031
4039
  function canonicalizeHost(parsed, options, schemeHandler, isIP) {
4032
- if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && parsed.host[0] !== "[" && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4040
+ if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4033
4041
  try {
4034
4042
  parsed.host = new URL("http://" + parsed.host).hostname;
4035
4043
  } catch (e) {
@@ -4116,10 +4124,11 @@ var require_fast_uri = __commonJS({
4116
4124
  if (parsed.host) {
4117
4125
  const ipv4result = isIPv4(parsed.host);
4118
4126
  if (ipv4result === false) {
4119
- const bracketedIPLiteral = parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
4127
+ const bracketedIPLiteral = isIPLiteral(parsed.host);
4128
+ const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
4120
4129
  const ipv6result = normalizeIPv6(parsed.host);
4121
4130
  isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
4122
- malformedIPLiteral = bracketedIPLiteral && ipv6result.error === true;
4131
+ malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
4123
4132
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
4124
4133
  if (malformedIPLiteral) {
4125
4134
  parsed.error = parsed.error || "URI host is malformed.";
@@ -4142,14 +4151,17 @@ var require_fast_uri = __commonJS({
4142
4151
  parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
4143
4152
  }
4144
4153
  const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
4145
- malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
4146
- if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4147
- if (uri.indexOf("%") !== -1) {
4148
- if (parsed.host !== void 0 && !malformedIPLiteral) {
4149
- const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
4150
- parsed.host = reescapeHostDelimiters(host, isIP);
4151
- }
4154
+ if (!malformedIPLiteral) {
4155
+ malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
4156
+ }
4157
+ if (uri.indexOf("%") !== -1 && parsed.host !== void 0 && !malformedIPLiteral) {
4158
+ let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
4159
+ if (!isIP) {
4160
+ host = normalizePercentEncoding(host.toLowerCase());
4152
4161
  }
4162
+ parsed.host = reescapeHostDelimiters(host, isIP);
4163
+ }
4164
+ if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4153
4165
  if (parsed.path) {
4154
4166
  parsed.path = normalizePathEncoding(parsed.path);
4155
4167
  }
@@ -22973,7 +22985,7 @@ function updateCursorSessionRegistry(filePath, mutator, options = {}) {
22973
22985
  // server.mjs
22974
22986
  init_cursor_ensure_core();
22975
22987
  init_lifecycle_paths();
22976
- var PLUGIN_VERSION = "6.0.3";
22988
+ var PLUGIN_VERSION = "6.0.5";
22977
22989
  var CDP_PORT2 = Number(process.env.CURSOR_BRIDGE_CDP_PORT || 9223);
22978
22990
  var ORIGIN = `http://localhost:${CDP_PORT2}`;
22979
22991
  var QUERY_TIMEOUT = Number(process.env.CURSOR_BRIDGE_TIMEOUT || 3e5);
@@ -23514,9 +23526,34 @@ var EXPR_MODEL_PICKER_ROWS = `(function(){
23514
23526
  }
23515
23527
  return JSON.stringify({open:menus.length>0,rows});
23516
23528
  })()`;
23529
+ var EXPR_SELECTED_AGENT_MODEL_CONFIG = `(function(){
23530
+ ${INPUT_PICKER_BODY}
23531
+ const inputs=inputCandidates();
23532
+ if(inputs.length!==1)return JSON.stringify({found:false,state:'input_ambiguous',inputCount:inputs.length});
23533
+ const configs=[];
23534
+ for(let node=inputs[0],n=0;node&&n<12;n++,node=node.parentElement){
23535
+ const key=Object.keys(node).find(key=>key.startsWith('__reactFiber$'));
23536
+ for(let f=key&&node[key],i=0;f&&i<48;i++,f=f.return){
23537
+ const reference=f.memoizedProps&&f.memoizedProps.selectedAgent&&f.memoizedProps.selectedAgent.reference;
23538
+ const handle=reference&&(reference._composerDataHandle||reference.composerDataHandle);
23539
+ const data=handle&&(handle._cachedData||handle.data);
23540
+ if(data&&data.modelConfig&&!configs.includes(data.modelConfig))configs.push(data.modelConfig);
23541
+ }
23542
+ }
23543
+ if(configs.length!==1)return JSON.stringify({found:false,state:'model_config_ambiguous',configCount:configs.length});
23544
+ const config=configs[0];
23545
+ return JSON.stringify({found:true,modelName:String(config.modelName||''),selectedModels:(config.selectedModels||[]).map(model=>({
23546
+ modelId:String(model&&model.modelId||''),
23547
+ parameters:Object.fromEntries((model&&model.parameters||[]).map(parameter=>[String(parameter&&parameter.id||''),String(parameter&&parameter.value||'')]))
23548
+ }))});
23549
+ })()`;
23517
23550
  function normalizeModelPickerText(value) {
23518
23551
  return String(value || "").trim().toLowerCase().replace(/extra[\s_-]*high/g, "xhigh").replace(/[^a-z0-9]+/g, "");
23519
23552
  }
23553
+ function normalizeModelPickerModelText(value) {
23554
+ const normalized = normalizeModelPickerText(value);
23555
+ return normalized.startsWith("cursor") && normalized.length > "cursor".length ? normalized.slice("cursor".length) : normalized;
23556
+ }
23520
23557
  function isCursorEffortOptionText(text) {
23521
23558
  return CURSOR_MODEL_EFFORTS.includes(normalizeModelPickerText(text));
23522
23559
  }
@@ -23526,10 +23563,11 @@ function modelPickerAvailableIsDecisive(kind, available) {
23526
23563
  return available.some((text) => isCursorEffortOptionText(text));
23527
23564
  }
23528
23565
  function selectModelPickerRow(rows, requested, kind = "model") {
23529
- const wanted = normalizeModelPickerText(requested);
23566
+ const normalize = kind === "parameter" ? normalizeModelPickerText : normalizeModelPickerModelText;
23567
+ const wanted = normalize(requested);
23530
23568
  if (!wanted) return null;
23531
23569
  const candidates = (Array.isArray(rows) ? rows : []).filter((row) => row && row.disabled !== true && (kind === "any" || row.kind === kind)).map((row) => {
23532
- const normalized = normalizeModelPickerText(row.text);
23570
+ const normalized = normalize(row.text);
23533
23571
  let score = normalized === wanted ? 1e3 : 0;
23534
23572
  if (kind !== "parameter") {
23535
23573
  if (!score && normalized.startsWith(wanted)) score = 800;
@@ -23635,13 +23673,12 @@ var WORKSPACE_SECTION_BODY = String.raw`
23635
23673
  if(matches.length!==1)return {diagnostic:fail('workspace_ambiguous')};
23636
23674
  const {section,project}=matches[0];
23637
23675
  if(project.remoteAuthority||!project.workspaceIdentifier.id)return {diagnostic:fail('workspace_environment_unverified')};
23638
- // Cursor's section-level New Agent action chooses among registered targets.
23639
- // Do not click it when a second workspace could win that choice.
23640
- if(section.source.projects.length!==1)return {diagnostic:fail('workspace_creation_target_ambiguous')};
23641
23676
  if(!section.button)return {diagnostic:fail('workspace_new_agent_unavailable')};
23642
23677
  return {section,diagnostic:{ok:true,state:'workspace_ready',workspace:wanted,
23643
23678
  workspaceId:project.workspaceIdentifier.id,sectionId:section.metadata.id,
23644
- environment:'local',identitySource:'registered_workspace_file_uri',repoUrls:Array.isArray(project.repoUrls)?project.repoUrls:[]}};
23679
+ environment:'local',identitySource:'registered_workspace_file_uri',
23680
+ workspaceSelectionRequired:section.source.projects.length!==1,
23681
+ repoUrls:Array.isArray(project.repoUrls)?project.repoUrls:[]}};
23645
23682
  };
23646
23683
  `;
23647
23684
  function exprCreateAgentForWorkspace(projectPath) {
@@ -23656,6 +23693,50 @@ function exprCreateAgentForWorkspace(projectPath) {
23656
23693
  return JSON.stringify({...result.diagnostic,state:'workspace_agent_creation_requested',previousAgentIds});
23657
23694
  })()`;
23658
23695
  }
23696
+ function matchSelectedAgentModelConfig(snapshot, requestedModel, requestedEffort) {
23697
+ if (!snapshot || snapshot.found !== true) return null;
23698
+ const requested = normalizeModelPickerModelText(requestedModel);
23699
+ const entries = Array.isArray(snapshot.selectedModels) && snapshot.selectedModels.length ? snapshot.selectedModels : [{ modelId: snapshot.modelName, parameters: {} }];
23700
+ const matches = entries.filter((entry) => {
23701
+ const candidate = normalizeModelPickerModelText(entry && entry.modelId);
23702
+ return candidate && candidate === requested;
23703
+ });
23704
+ if (matches.length !== 1) return null;
23705
+ const match = matches[0];
23706
+ const parameters = match.parameters || {};
23707
+ const effort = normalizeCursorModelEffort(parameters.reasoning_effort ?? parameters.effort, "");
23708
+ if (requestedEffort && effort !== requestedEffort) return null;
23709
+ return { modelId: match.modelId, effort: effort || null };
23710
+ }
23711
+ function exprSelectAgentWorkspace(projectPath) {
23712
+ return `(async function(){
23713
+ const wanted=String(${JSON.stringify(String(projectPath || ""))}).replace(/\\\\/g,'/').replace(/^\\/([a-z]:\\/)/i,'$1').replace(/\\/+$/,'').toLowerCase();
23714
+ const normalize=value=>String(value||'').replace(/\\\\/g,'/').replace(/^\\/([a-z]:\\/)/i,'$1').replace(/\\/+$/,'').toLowerCase();
23715
+ const visible=node=>!!(node&&(node.offsetParent!==null||(node.getClientRects&&node.getClientRects().length>0)));
23716
+ const pathTriggers=()=>[...document.querySelectorAll('button.ui-select-trigger,button[aria-haspopup="menu"]')]
23717
+ .filter(visible).filter(node=>/^[a-z]:\\//i.test(normalize(node.innerText||node.textContent)));
23718
+ const triggers=pathTriggers();
23719
+ const fail=(state,extra={})=>JSON.stringify({ok:false,state,wanted,...extra,
23720
+ nextStep:'Select the exact local workspace '+${JSON.stringify(String(projectPath || ""))}+' in the new Agent project picker before retrying.'});
23721
+ if(triggers.length!==1)return fail(triggers.length?'workspace_project_selector_ambiguous':'workspace_project_selector_unavailable',{triggerCount:triggers.length});
23722
+ triggers[0].click();
23723
+ await new Promise(resolve=>setTimeout(resolve,350));
23724
+ const menus=[...document.querySelectorAll('[data-component="menu-popup"],[role="menu"]')].filter(visible)
23725
+ .filter(menu=>String(menu.getAttribute('aria-label')||'')==='Select a project'||menu.querySelector('[aria-label="Select a project"]'));
23726
+ const rows=[];const seen=new Set();
23727
+ for(const menu of menus){
23728
+ for(const row of menu.querySelectorAll('[data-component="menu-row"][role="menuitem"],[role="option"]')){
23729
+ if(!visible(row)||seen.has(row))continue;seen.add(row);rows.push(row);
23730
+ }
23731
+ }
23732
+ const available=rows.map(row=>String(row.innerText||row.textContent||'').replace(/\\s+/g,' ').trim());
23733
+ const matches=rows.filter(row=>normalize(row.innerText||row.textContent)===wanted);
23734
+ if(matches.length!==1)return fail(matches.length?'workspace_project_option_ambiguous':'workspace_project_option_unavailable',{available});
23735
+ matches[0].click();
23736
+ await new Promise(resolve=>setTimeout(resolve,350));
23737
+ return JSON.stringify({ok:true,state:'workspace_project_selection_requested',workspace:wanted,available});
23738
+ })()`;
23739
+ }
23659
23740
  function exprInspectWorkspaceRepository(projectPath) {
23660
23741
  return `(function(){
23661
23742
  ${WORKSPACE_SECTION_BODY}
@@ -23951,7 +24032,8 @@ var EXPR_PAGE_CAPABILITIES = `(function(){${INPUT_PICKER_BODY}
23951
24032
  const hasLegacyInput=!!document.querySelector('.aislash-editor-input');
23952
24033
  const hasLegacyHistory=!!document.querySelector('.compact-agent-history-react-menu-label')||
23953
24034
  [...document.querySelectorAll('button,[role=button],a.action-label,.codicon')].some(e=>/Show Chat History|Chat History|Agent History/i.test((e.getAttribute('aria-label')||'')+' '+(e.getAttribute('title')||'')));
23954
- const dialogs=[...document.querySelectorAll('[role="dialog"],dialog[open],.monaco-dialog-box,.quick-input-widget')].filter(visible);
24035
+ const dialogs=[...document.querySelectorAll('[role="dialog"],dialog[open],.monaco-dialog-box,.quick-input-widget')]
24036
+ .filter(visible).filter(node=>node.getAttribute('data-component')!=='preview-card-layer-popup');
23955
24037
  const dialog=dialogs[dialogs.length-1]||null;
23956
24038
  const dialogHeading=dialog&&dialog.querySelector('h1,h2,h3,[role="heading"]');
23957
24039
  const dialogLabel=dialog?String(dialog.getAttribute('aria-label')||dialog.getAttribute('title')||label(dialogHeading)||'').slice(0,120):null;
@@ -25538,6 +25620,9 @@ var CursorBridge = class {
25538
25620
  const snapshot = await this._readModelPickerValue(c, EXPR_MODEL_PICKER_ROWS, "rows", options);
25539
25621
  return { open: snapshot.open === true, rows: Array.isArray(snapshot.rows) ? snapshot.rows : [] };
25540
25622
  }
25623
+ async _readSelectedAgentModelConfig(c, options) {
25624
+ return this._readModelPickerValue(c, EXPR_SELECTED_AGENT_MODEL_CONFIG, "selected_agent_model_config", options);
25625
+ }
25541
25626
  async _clickModelPickerPoint(c, point) {
25542
25627
  if (!point || !Number.isFinite(Number(point.x)) || !Number.isFinite(Number(point.y))) {
25543
25628
  throw new Error("Cursor model picker returned an invalid target");
@@ -25711,6 +25796,32 @@ var CursorBridge = class {
25711
25796
  const selectionStartedAt = Date.now();
25712
25797
  let stage = "open_picker";
25713
25798
  try {
25799
+ if (this.runtimeMode === "minimal") {
25800
+ stage = "verify_hidden_model_config";
25801
+ const snapshot = await this._readSelectedAgentModelConfig(c);
25802
+ const verified = matchSelectedAgentModelConfig(snapshot, requestedModel, requestedEffort);
25803
+ if (!verified) {
25804
+ throw createModelSelectionError(
25805
+ `Cursor minimal runtime could not confirm ${requestedModel}${requestedEffort ? ` / ${requestedEffort}` : ""}; switch Cursor runtime to normal and retry`,
25806
+ "hidden_model_not_confirmed",
25807
+ true,
25808
+ { available: (snapshot.selectedModels || []).map((entry) => entry.modelId).filter(Boolean) }
25809
+ );
25810
+ }
25811
+ const result2 = {
25812
+ configured: true,
25813
+ applied: true,
25814
+ requestedModel,
25815
+ requestedEffort,
25816
+ effectiveModel: verified.modelId,
25817
+ effectiveEffort: verified.effort,
25818
+ pickerDetail: null,
25819
+ verificationSource: "selected_agent_model_config",
25820
+ verifiedAt: (/* @__PURE__ */ new Date()).toISOString()
25821
+ };
25822
+ if (job) job.modelSelection = result2;
25823
+ return result2;
25824
+ }
25714
25825
  const opened = await this._openModelPicker(c);
25715
25826
  stage = "locate_model";
25716
25827
  let located = await this._findModelPickerModel(c, opened, requestedModel);
@@ -25767,6 +25878,31 @@ var CursorBridge = class {
25767
25878
  await this._clickModelPickerPoint(c, selectedEffort.row);
25768
25879
  await sleep2(550);
25769
25880
  }
25881
+ } else if (requestedEffort) {
25882
+ if (!modelRow.selected) {
25883
+ stage = "select_model";
25884
+ this._throwIfCancelledBeforeSend(job);
25885
+ await this._clickModelPickerPoint(c, modelRow);
25886
+ await sleep2(550);
25887
+ const reopened = await this._openModelPicker(c);
25888
+ located = await this._findModelPickerModel(c, reopened, requestedModel);
25889
+ modelRow = located.modelRow;
25890
+ if (!modelRow) {
25891
+ throw createModelSelectionError(
25892
+ `Cursor model row disappeared while applying effort: ${requestedModel}`,
25893
+ "model_unavailable",
25894
+ true
25895
+ );
25896
+ }
25897
+ }
25898
+ stage = "select_effort";
25899
+ const selectedEffort = await resolveEffort();
25900
+ if (!selectedEffort.row) throwEffortFailure(selectedEffort);
25901
+ if (!selectedEffort.row.selected) {
25902
+ this._throwIfCancelledBeforeSend(job);
25903
+ await this._clickModelPickerPoint(c, selectedEffort.row);
25904
+ await sleep2(550);
25905
+ }
25770
25906
  } else if (!modelRow.selected) {
25771
25907
  stage = "select_model";
25772
25908
  this._throwIfCancelledBeforeSend(job);
@@ -25775,7 +25911,7 @@ var CursorBridge = class {
25775
25911
  }
25776
25912
  stage = "verify_model";
25777
25913
  let trigger2 = await this._readModelPickerTrigger(c);
25778
- if (!trigger2.found || !normalizeModelPickerText(trigger2.text).includes(normalizeModelPickerText(requestedModel))) {
25914
+ if (!trigger2.found || !normalizeModelPickerModelText(trigger2.text).includes(normalizeModelPickerModelText(requestedModel))) {
25779
25915
  const reopened = await this._openModelPicker(c);
25780
25916
  located = await this._findModelPickerModel(c, reopened, requestedModel);
25781
25917
  const selected = selectModelPickerRow(located.snapshot.rows.filter((row) => row.selected), requestedModel, "model");
@@ -25950,7 +26086,13 @@ var CursorBridge = class {
25950
26086
  if (!created.ok) {
25951
26087
  throw createWorkspaceBindingError(created);
25952
26088
  }
25953
- await sleep2(1100);
26089
+ if (created.workspaceSelectionRequired) {
26090
+ await sleep2(250);
26091
+ const selected = JSON.parse(await evalJS(c, exprSelectAgentWorkspace(options.projectPath)) || "{}");
26092
+ if (options.job) options.job.workspaceBindingChecks.project_selection = { ...selected, checkedAt: (/* @__PURE__ */ new Date()).toISOString() };
26093
+ if (!selected.ok) throw createWorkspaceBindingError(selected);
26094
+ }
26095
+ await sleep2(created.workspaceSelectionRequired ? 750 : 1100);
25954
26096
  const actual = JSON.parse(await evalJS(c, exprInspectAgentWorkspace(options.projectPath, { excludedAgentIds: created.previousAgentIds })) || "{}");
25955
26097
  if (options.job) options.job.workspaceBindingChecks.after_create = { ...actual, checkedAt: (/* @__PURE__ */ new Date()).toISOString() };
25956
26098
  if (!actual.ok) throw createWorkspaceBindingError(actual);
@@ -27862,6 +28004,7 @@ export {
27862
28004
  EXPR_PAGE_CAPABILITIES,
27863
28005
  EXPR_PREPARE_INPUT,
27864
28006
  EXPR_PROVIDER_ERROR,
28007
+ EXPR_SELECTED_AGENT_MODEL_CONFIG,
27865
28008
  EXPR_SNAP,
27866
28009
  EXPR_VISIBLE,
27867
28010
  EXPR_VISIBLE_COMPOSER,
@@ -27882,18 +28025,21 @@ export {
27882
28025
  exprInspectWorkspaceRepository,
27883
28026
  exprOpenAgent,
27884
28027
  exprRegisterAgentsWorkspace,
28028
+ exprSelectAgentWorkspace,
27885
28029
  isConfirmedCompletedReply,
27886
28030
  isCursorEffortOptionText,
27887
28031
  isDurablyRegisteredParallelEntry,
27888
28032
  isSessionTurnReplyReady,
27889
28033
  isTargetedStopConfirmed,
27890
28034
  lifecycleFailureSummary,
28035
+ matchSelectedAgentModelConfig,
27891
28036
  modelPickerAvailableIsDecisive,
27892
28037
  normalizeAllowedPath,
27893
28038
  normalizeCceSearchResult,
27894
28039
  normalizeCursorModelEffort,
27895
28040
  normalizeCursorRuntimeMode,
27896
28041
  normalizeDelegationMode,
28042
+ normalizeModelPickerModelText,
27897
28043
  normalizeModelPickerText,
27898
28044
  normalizeRequestContext,
27899
28045
  pathsOverlap,
@@ -10,7 +10,7 @@ const hostWorkspaceId = hostCwd.replace(/\\/g, "/").toLowerCase();
10
10
  export default createStdioMcpExtension({
11
11
  label: "Cursor Bridge",
12
12
  clientName: "pi-cursor-bridge",
13
- packageVersion: "0.2.4-macos.0",
13
+ packageVersion: "0.2.5",
14
14
  serverName: "cursor-bridge",
15
15
  serverScript: join(packageRoot, "dist", "cursor-bridge.mjs"),
16
16
  cwd: hostCwd,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pi-cursor-bridge",
3
- "version": "0.2.4-macos.0",
4
- "description": "Use Cursor Context Engine and bounded, explicitly continuous Cursor Agent execution from the Pi coding agent.",
3
+ "version": "0.2.5",
4
+ "description": "Windows only. Use Cursor Context Engine and bounded, explicitly continuous Cursor Agent execution from the Pi coding agent.",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
7
  "author": "Vanyangyang",
@@ -47,6 +47,6 @@
47
47
  },
48
48
  "piPackage": {
49
49
  "embeddedProduct": "Cursor Bridge",
50
- "embeddedProductVersion": "6.0.3"
50
+ "embeddedProductVersion": "6.0.5"
51
51
  }
52
52
  }