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.
- package/.codex-plugin/plugin.json +1 -1
- package/README.md +5 -3
- package/dist/cursor-bridge.mjs +168 -22
- package/extensions/index.ts +1 -1
- package/package.json +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursor-bridge",
|
|
3
|
-
"version": "6.0.
|
|
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
|
|
10
|
+
pi install npm:pi-cursor-bridge
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
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.
|
|
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)
|
package/dist/cursor-bridge.mjs
CHANGED
|
@@ -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(
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
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.
|
|
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&¶meter.id||''),String(parameter&¶meter.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
|
|
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 =
|
|
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',
|
|
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')]
|
|
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 || !
|
|
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
|
-
|
|
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,
|
package/extensions/index.ts
CHANGED
|
@@ -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.
|
|
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
|
-
"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.
|
|
50
|
+
"embeddedProductVersion": "6.0.5"
|
|
51
51
|
}
|
|
52
52
|
}
|