pi-cursor-bridge 0.2.6 → 0.2.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/.codex-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/dist/cursor-bridge.mjs +373 -77
- package/extensions/index.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -12,6 +12,6 @@ pi install npm:pi-cursor-bridge
|
|
|
12
12
|
|
|
13
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.
|
|
14
14
|
|
|
15
|
-
Pi wrapper 0.2.
|
|
15
|
+
Pi wrapper 0.2.8 embeds Cursor Bridge 6.0.8, 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.
|
|
16
16
|
|
|
17
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
|
@@ -12907,6 +12907,11 @@ async function ensureCursorViaSupervisor(options = {}) {
|
|
|
12907
12907
|
ok: !!response.ok,
|
|
12908
12908
|
status: response.status,
|
|
12909
12909
|
message: response.message,
|
|
12910
|
+
needsAction: response.needsAction || null,
|
|
12911
|
+
nextStep: response.nextStep || null,
|
|
12912
|
+
retryable: response.retryable === true,
|
|
12913
|
+
cursorExecutable: response.cursorExecutable || null,
|
|
12914
|
+
cursorExecutableSource: response.cursorExecutableSource || null,
|
|
12910
12915
|
port: response.port,
|
|
12911
12916
|
exe: response.exe,
|
|
12912
12917
|
cursorPid: response.cursorPid || null,
|
|
@@ -22985,7 +22990,7 @@ function updateCursorSessionRegistry(filePath, mutator, options = {}) {
|
|
|
22985
22990
|
// server.mjs
|
|
22986
22991
|
init_cursor_ensure_core();
|
|
22987
22992
|
init_lifecycle_paths();
|
|
22988
|
-
var PLUGIN_VERSION = "6.0.
|
|
22993
|
+
var PLUGIN_VERSION = "6.0.8";
|
|
22989
22994
|
var CDP_PORT2 = Number(process.env.CURSOR_BRIDGE_CDP_PORT || 9223);
|
|
22990
22995
|
var ORIGIN = `http://localhost:${CDP_PORT2}`;
|
|
22991
22996
|
var QUERY_TIMEOUT = Number(process.env.CURSOR_BRIDGE_TIMEOUT || 3e5);
|
|
@@ -23373,6 +23378,24 @@ var EXPR_PROVIDER_ERROR = `(function(){
|
|
|
23373
23378
|
const signature=[title,message,requestId||''].join('|');
|
|
23374
23379
|
return JSON.stringify({found:true,title,message,requestId,retryAvailable,signature});
|
|
23375
23380
|
})()`;
|
|
23381
|
+
var STOP_COMPOSER_BODY = `
|
|
23382
|
+
const findStopComposers=(rawId)=>{
|
|
23383
|
+
const legacy=[...document.querySelectorAll('.composer-bar[data-composer-id]')]
|
|
23384
|
+
.filter(e=>e.offsetParent!==null&&e.dataset.composerId&&(!rawId||e.dataset.composerId===rawId));
|
|
23385
|
+
if(legacy.length)return {modern:false,composers:legacy};
|
|
23386
|
+
return {modern:true,composers:[...document.querySelectorAll('[data-agent-panel-conversation-shell][data-glass-agent-id]')]
|
|
23387
|
+
.filter(e=>e.offsetParent!==null&&e.dataset.glassAgentId&&(!rawId||e.dataset.glassAgentId===rawId))};
|
|
23388
|
+
};
|
|
23389
|
+
const modernComposerStatus=(composer,entries)=>{
|
|
23390
|
+
const ownStatus=composer.dataset.composerStatus;
|
|
23391
|
+
if(ownStatus)return ownStatus;
|
|
23392
|
+
const matches=entries.filter(e=>e&&e.id==='local:'+composer.dataset.glassAgentId);
|
|
23393
|
+
if(matches.length!==1)return null;
|
|
23394
|
+
const entry=matches[0];
|
|
23395
|
+
if(entry.showSpinner||entry.icon==='loading')return 'generating';
|
|
23396
|
+
return ({'check-circled':'completed','circle-slash':'cancelled',warning:'failed','needs-attention':'needs_attention'})[entry.icon]||null;
|
|
23397
|
+
};
|
|
23398
|
+
`;
|
|
23376
23399
|
function exprClickSelectedAgentStop(agentId) {
|
|
23377
23400
|
const expected = JSON.stringify(String(agentId));
|
|
23378
23401
|
return `(function(){
|
|
@@ -23385,52 +23408,52 @@ function exprClickSelectedAgentStop(agentId) {
|
|
|
23385
23408
|
if(!selected||selected.id!==${expected}){
|
|
23386
23409
|
return JSON.stringify({clicked:false,state:'selected_agent_mismatch',selectedId:selected&&selected.id||null,selectedCount:selectedEntries.length});
|
|
23387
23410
|
}
|
|
23411
|
+
${STOP_COMPOSER_BODY}
|
|
23388
23412
|
const expectedComposerId=String(${expected}).replace(/^local:/,'');
|
|
23389
|
-
const composers=
|
|
23390
|
-
.filter(e=>e.offsetParent!==null&&e.dataset.composerId===expectedComposerId);
|
|
23413
|
+
const {modern,composers}=findStopComposers(expectedComposerId);
|
|
23391
23414
|
if(composers.length!==1){
|
|
23392
23415
|
return JSON.stringify({clicked:false,state:'composer_identity_mismatch',selectedId:selected.id,count:composers.length});
|
|
23393
23416
|
}
|
|
23394
23417
|
const composer=composers[0];
|
|
23395
|
-
|
|
23396
|
-
|
|
23418
|
+
const status=modern?modernComposerStatus(composer,entries):composer.dataset.composerStatus||null;
|
|
23419
|
+
if(status!=='generating'){
|
|
23420
|
+
return JSON.stringify({clicked:false,state:'composer_not_generating',selectedId:selected.id,status});
|
|
23397
23421
|
}
|
|
23398
|
-
const
|
|
23399
|
-
|
|
23422
|
+
const belongs=button=>button.offsetParent!==null&&!button.disabled&&button.closest(modern?'[data-glass-agent-id]':'.composer-bar')===composer;
|
|
23423
|
+
const generationButtons=[...composer.querySelectorAll(modern?'button.ui-prompt-input-submit-button[aria-label="Stop generation"]':'button.ui-prompt-input-submit-button[data-state="stop"][aria-label="Stop generation"]')]
|
|
23424
|
+
.filter(belongs);
|
|
23400
23425
|
const commandButtons=[...composer.querySelectorAll('button.ui-shell-tool-call__glass-stop[aria-label="Stop command"]')]
|
|
23401
|
-
.filter(
|
|
23426
|
+
.filter(belongs);
|
|
23402
23427
|
const buttons=[...generationButtons,...commandButtons];
|
|
23403
23428
|
if(buttons.length!==1){
|
|
23404
23429
|
return JSON.stringify({clicked:false,state:buttons.length?'ambiguous_stop_controls':'stop_control_missing',selectedId:selected.id,count:buttons.length});
|
|
23405
23430
|
}
|
|
23406
23431
|
buttons[0].click();
|
|
23407
|
-
return JSON.stringify({clicked:true,state:'clicked',selectedId:selected.id,composerId:
|
|
23432
|
+
return JSON.stringify({clicked:true,state:'clicked',selectedId:selected.id,composerId:expectedComposerId,control:generationButtons.length?'stop_generation':'stop_command'});
|
|
23408
23433
|
})()`;
|
|
23409
23434
|
}
|
|
23410
|
-
var EXPR_VISIBLE_COMPOSER = `(function(){
|
|
23411
|
-
const composers=[...document.querySelectorAll('.composer-bar[data-composer-id]')]
|
|
23412
|
-
.filter(e=>e.offsetParent!==null&&e.dataset.composerId);
|
|
23413
|
-
if(composers.length!==1){
|
|
23414
|
-
return JSON.stringify({ok:false,state:composers.length?'ambiguous_composers':'composer_missing',count:composers.length});
|
|
23415
|
-
}
|
|
23416
|
-
const composer=composers[0];
|
|
23417
|
-
return JSON.stringify({
|
|
23418
|
-
ok:true,
|
|
23419
|
-
id:'local:'+composer.dataset.composerId,
|
|
23420
|
-
composerId:composer.dataset.composerId,
|
|
23421
|
-
status:composer.dataset.composerStatus||null
|
|
23422
|
-
});
|
|
23423
|
-
})()`;
|
|
23424
23435
|
function exprClickBoundComposerStop(agentId) {
|
|
23425
23436
|
const expected = JSON.stringify(String(agentId));
|
|
23426
23437
|
return `(function(){
|
|
23438
|
+
${STOP_COMPOSER_BODY}
|
|
23427
23439
|
const expectedComposerId=String(${expected}).replace(/^local:/,'');
|
|
23428
|
-
const composers=
|
|
23429
|
-
.filter(e=>e.offsetParent!==null&&e.dataset.composerId===expectedComposerId);
|
|
23440
|
+
const {modern,composers}=findStopComposers(expectedComposerId);
|
|
23430
23441
|
if(composers.length!==1){
|
|
23431
23442
|
return JSON.stringify({clicked:false,state:'composer_identity_mismatch',count:composers.length});
|
|
23432
23443
|
}
|
|
23433
23444
|
const composer=composers[0];
|
|
23445
|
+
if(modern){
|
|
23446
|
+
${REACT_ADAPTER_BODY}
|
|
23447
|
+
const status=modernComposerStatus(composer,a?a.entries():[]);
|
|
23448
|
+
if(status!=='generating')return JSON.stringify({clicked:false,state:'composer_not_generating',status,composerId:expectedComposerId});
|
|
23449
|
+
const belongs=button=>button.offsetParent!==null&&!button.disabled&&button.closest('[data-glass-agent-id]')===composer;
|
|
23450
|
+
const generationButtons=[...composer.querySelectorAll('button.ui-prompt-input-submit-button[aria-label="Stop generation"]')].filter(belongs);
|
|
23451
|
+
const commandButtons=[...composer.querySelectorAll('button.ui-shell-tool-call__glass-stop[aria-label="Stop command"]')].filter(belongs);
|
|
23452
|
+
const buttons=[...generationButtons,...commandButtons];
|
|
23453
|
+
if(buttons.length!==1)return JSON.stringify({clicked:false,state:buttons.length?'ambiguous_stop_controls':'stop_control_missing',count:buttons.length,composerId:expectedComposerId});
|
|
23454
|
+
buttons[0].click();
|
|
23455
|
+
return JSON.stringify({clicked:true,state:'clicked',composerId:expectedComposerId,control:generationButtons.length?'stop_generation':'stop_command'});
|
|
23456
|
+
}
|
|
23434
23457
|
if(composer.dataset.composerStatus!=='generating'){
|
|
23435
23458
|
return JSON.stringify({clicked:false,state:'composer_not_generating',status:composer.dataset.composerStatus||null,composerId:composer.dataset.composerId});
|
|
23436
23459
|
}
|
|
@@ -23458,21 +23481,45 @@ function exprClickBoundComposerStop(agentId) {
|
|
|
23458
23481
|
}
|
|
23459
23482
|
var EXPR_FIND_NEWAGENT = `(function(){const b=[...document.querySelectorAll('button,[role=button],a.action-label,.codicon')].find(e=>{if(e.offsetParent===null||e.closest('.glass-sidebar-agent-menu-btn'))return false;const s=(e.getAttribute('aria-label')||'')+' '+(e.getAttribute('title')||'')+' '+(e.innerText||'');return /(?:^|\\s)New (?:Agent|Chat)(?:\\s|$)/i.test(s);});if(!b)return '';const r=b.getBoundingClientRect();return JSON.stringify({x:Math.round(r.x+r.width/2),y:Math.round(r.y+r.height/2)});})()`;
|
|
23460
23483
|
var MODEL_PICKER_VISIBLE_BODY = `
|
|
23484
|
+
${INPUT_PICKER_BODY}
|
|
23461
23485
|
const visible=(node)=>!!(node&&(node.offsetParent!==null||(node.getClientRects&&node.getClientRects().length>0)));
|
|
23462
|
-
const
|
|
23463
|
-
const
|
|
23486
|
+
const inputs=inputCandidates();
|
|
23487
|
+
const ownerSelector='.composer-bar[data-composer-id],.composer-bar,.ui-prompt-input-root,.agent-prompt-input-root,.ui-prompt-input';
|
|
23488
|
+
const composer=inputs.length===1?inputs[0].closest(ownerSelector):null;
|
|
23489
|
+
const triggerSelector='.ui-model-picker__trigger,.vscode-model-picker__trigger';
|
|
23490
|
+
const candidates=composer?[...composer.querySelectorAll(triggerSelector)]
|
|
23491
|
+
.filter(node=>visible(node)&&node.closest(ownerSelector)===composer):[];
|
|
23492
|
+
const trigger=candidates.length===1?candidates[0]:null;
|
|
23493
|
+
const shell=inputs.length===1?inputs[0].closest('[data-agent-panel-conversation-shell][data-glass-agent-id]'):null;
|
|
23494
|
+
const owner=trigger?{triggerId:trigger.getAttribute('id'),composerId:composer.getAttribute('data-composer-id'),agentId:shell&&shell.getAttribute('data-glass-agent-id')}:null;
|
|
23464
23495
|
`;
|
|
23465
23496
|
var EXPR_MODEL_PICKER_TRIGGER = `(function(){
|
|
23466
23497
|
${MODEL_PICKER_VISIBLE_BODY}
|
|
23467
|
-
|
|
23468
|
-
const candidates=[...composer.querySelectorAll(triggerSelector)].filter(visible);
|
|
23469
|
-
const trigger=candidates[candidates.length-1]||[...document.querySelectorAll(triggerSelector)].filter(visible).pop();
|
|
23470
|
-
if(!trigger)return JSON.stringify({found:false,state:'trigger_missing'});
|
|
23498
|
+
if(!trigger)return JSON.stringify({found:false,state:inputs.length!==1?'input_ambiguous':!composer?'composer_missing':candidates.length>1?'trigger_ambiguous':'trigger_missing',inputCount:inputs.length,triggerCount:candidates.length});
|
|
23471
23499
|
const rect=trigger.getBoundingClientRect();
|
|
23472
23500
|
const text=String(trigger.querySelector('.ui-model-picker__trigger-text,.vscode-model-picker__trigger-text')?.innerText||trigger.innerText||'').replace(/\\s+/g,' ').trim();
|
|
23473
23501
|
const detail=String(trigger.querySelector('.ui-model-picker__trigger-variant-suffix,.vscode-model-picker__trigger-variant-suffix')?.innerText||'').replace(/\\s+/g,' ').trim();
|
|
23474
|
-
|
|
23502
|
+
const x=Math.round(rect.x+rect.width/2),y=Math.round(rect.y+rect.height/2);
|
|
23503
|
+
let state='ready';
|
|
23504
|
+
if(trigger.disabled||trigger.getAttribute('aria-disabled')==='true'||trigger.closest('[inert]')||getComputedStyle(trigger).pointerEvents==='none')state='trigger_disabled';
|
|
23505
|
+
else if(!Number.isFinite(x)||!Number.isFinite(y)||rect.width<=0||rect.height<=0||x<0||y<0||x>=innerWidth||y>=innerHeight)state='trigger_offscreen';
|
|
23506
|
+
else {const hit=document.elementFromPoint(x,y);if(!hit||hit!==trigger&&!trigger.contains(hit))state='trigger_occluded';}
|
|
23507
|
+
return JSON.stringify({found:true,state,interactive:state==='ready',expanded:trigger.getAttribute('aria-expanded'),text,detail,x,y,...owner});
|
|
23475
23508
|
})()`;
|
|
23509
|
+
function exprActivateClosedModelPicker(expected) {
|
|
23510
|
+
return `(function(){
|
|
23511
|
+
const expected=${JSON.stringify(expected)};
|
|
23512
|
+
const current=JSON.parse(${EXPR_MODEL_PICKER_TRIGGER});
|
|
23513
|
+
if(!current.found||current.interactive!==true||current.expanded!=='false')return JSON.stringify({clicked:false,state:'trigger_not_closed_and_interactive'});
|
|
23514
|
+
if(!current.triggerId||['triggerId','composerId','agentId','x','y'].some(key=>(current[key]??null)!==(expected[key]??null)))return JSON.stringify({clicked:false,state:'trigger_changed'});
|
|
23515
|
+
${MODEL_PICKER_VISIBLE_BODY}
|
|
23516
|
+
if(!trigger||trigger.getAttribute('id')!==current.triggerId)return JSON.stringify({clicked:false,state:'trigger_changed'});
|
|
23517
|
+
// Use the same button's normal click handler after a native click failed
|
|
23518
|
+
// to expand it. The closed-state and hit checks occur in this same turn.
|
|
23519
|
+
trigger.click();
|
|
23520
|
+
return JSON.stringify({clicked:true,state:'closed_trigger_activated',owner});
|
|
23521
|
+
})()`;
|
|
23522
|
+
}
|
|
23476
23523
|
function classifyModelPickerRowKind(text, hasItemName, menuTestId, submenuTestId, ariaHaspopup, hasParamCheck, inSubmenu) {
|
|
23477
23524
|
const menu = String(menuTestId || "").toLowerCase();
|
|
23478
23525
|
const submenu = String(submenuTestId || "").toLowerCase();
|
|
@@ -23489,7 +23536,32 @@ function classifyModelPickerRowKind(text, hasItemName, menuTestId, submenuTestId
|
|
|
23489
23536
|
var EXPR_MODEL_PICKER_ROWS = `(function(){
|
|
23490
23537
|
${MODEL_PICKER_VISIBLE_BODY}
|
|
23491
23538
|
${classifyModelPickerRowKind.toString()}
|
|
23492
|
-
const
|
|
23539
|
+
const visibleMenus=[...document.querySelectorAll('[data-testid="model-picker-menu"],[data-testid="selected-auto-menu"],[data-testid*="model-parameters"],[data-testid*="parameter-submenu"],[data-component="menu-popup"][data-submenu]')].filter(visible);
|
|
23540
|
+
const menus=[];
|
|
23541
|
+
if(trigger){
|
|
23542
|
+
// Modern menus are portalled. Follow the exact trigger's accessibility
|
|
23543
|
+
// links, including submenu triggers, instead of adopting another picker.
|
|
23544
|
+
const ids=new Set(),controls=new Set();
|
|
23545
|
+
const link=node=>{
|
|
23546
|
+
const id=node.getAttribute('id');if(id)ids.add(id);
|
|
23547
|
+
for(const id of String(node.getAttribute('aria-controls')||'').split(/\\s+/).filter(Boolean))controls.add(id);
|
|
23548
|
+
};
|
|
23549
|
+
link(trigger);
|
|
23550
|
+
for(let pass=0;pass<visibleMenus.length;pass++){
|
|
23551
|
+
let changed=false;
|
|
23552
|
+
for(const menu of visibleMenus){
|
|
23553
|
+
if(menus.includes(menu))continue;
|
|
23554
|
+
const id=menu.getAttribute('id'),labelledBy=String(menu.getAttribute('aria-labelledby')||'').split(/\\s+/).filter(Boolean);
|
|
23555
|
+
if(!(id&&controls.has(id))&&!labelledBy.some(id=>ids.has(id)))continue;
|
|
23556
|
+
menus.push(menu);link(menu);
|
|
23557
|
+
for(const node of menu.querySelectorAll('[id],[aria-controls]'))link(node);
|
|
23558
|
+
changed=true;
|
|
23559
|
+
}
|
|
23560
|
+
if(!changed)break;
|
|
23561
|
+
}
|
|
23562
|
+
if(!ids.size&&!controls.size&&visibleMenus.length===1
|
|
23563
|
+
&&[...document.querySelectorAll(triggerSelector)].filter(visible).length===1)menus.push(visibleMenus[0]);
|
|
23564
|
+
}
|
|
23493
23565
|
const rows=[];
|
|
23494
23566
|
const seen=new Set();
|
|
23495
23567
|
for(const menu of menus){
|
|
@@ -23524,8 +23596,11 @@ var EXPR_MODEL_PICKER_ROWS = `(function(){
|
|
|
23524
23596
|
});
|
|
23525
23597
|
}
|
|
23526
23598
|
}
|
|
23527
|
-
return JSON.stringify({open:menus.length>0,rows});
|
|
23599
|
+
return JSON.stringify({open:menus.length>0,rows,owner});
|
|
23528
23600
|
})()`;
|
|
23601
|
+
function modelPickerOwnerKey(owner) {
|
|
23602
|
+
return owner && JSON.stringify([owner.triggerId || null, owner.composerId || null, owner.agentId || null]);
|
|
23603
|
+
}
|
|
23529
23604
|
var EXPR_SELECTED_AGENT_MODEL_CONFIG = `(function(){
|
|
23530
23605
|
${INPUT_PICKER_BODY}
|
|
23531
23606
|
const inputs=inputCandidates();
|
|
@@ -23540,12 +23615,90 @@ var EXPR_SELECTED_AGENT_MODEL_CONFIG = `(function(){
|
|
|
23540
23615
|
if(data&&data.modelConfig&&!configs.includes(data.modelConfig))configs.push(data.modelConfig);
|
|
23541
23616
|
}
|
|
23542
23617
|
}
|
|
23543
|
-
if(configs.length
|
|
23544
|
-
|
|
23545
|
-
|
|
23546
|
-
|
|
23547
|
-
|
|
23548
|
-
|
|
23618
|
+
if(configs.length>1)return JSON.stringify({found:false,state:'model_config_ambiguous',configCount:configs.length});
|
|
23619
|
+
if(configs.length===1){
|
|
23620
|
+
const config=configs[0];
|
|
23621
|
+
return JSON.stringify({found:true,modelName:String(config.modelName||''),selectedModels:(config.selectedModels||[]).map(model=>({
|
|
23622
|
+
modelId:String(model&&model.modelId||''),
|
|
23623
|
+
parameters:Object.fromEntries((model&&model.parameters||[]).map(parameter=>[String(parameter&¶meter.id||''),String(parameter&¶meter.value||'')]))
|
|
23624
|
+
}))});
|
|
23625
|
+
}
|
|
23626
|
+
// Cursor 3.23's IDE input is Solid; its model trigger is a mounted React
|
|
23627
|
+
// picker whose initialSelections/initialAutoMode come from this composer.
|
|
23628
|
+
const source='legacy_composer_model_trigger';
|
|
23629
|
+
const fail=(state)=>JSON.stringify({found:false,state,source});
|
|
23630
|
+
const input=inputs[0],composer=input.closest('.composer-bar[data-composer-id]');
|
|
23631
|
+
if(!composer||input.closest('.composer-bar')!==composer
|
|
23632
|
+
||composer.parentElement&&composer.parentElement.closest('.composer-bar')
|
|
23633
|
+
||composer.querySelectorAll('.composer-bar').length)return fail('legacy_composer_ambiguous');
|
|
23634
|
+
const composerId=composer.getAttribute('data-composer-id');
|
|
23635
|
+
const owners=[...document.querySelectorAll('.composer-bar[data-composer-id]')]
|
|
23636
|
+
.filter(node=>node.getAttribute('data-composer-id')===composerId);
|
|
23637
|
+
if(typeof composerId!=='string'||!composerId.trim()||owners.length!==1||owners[0]!==composer)return fail('legacy_composer_ambiguous');
|
|
23638
|
+
const triggers=[...composer.querySelectorAll('.vscode-model-picker__trigger')];
|
|
23639
|
+
if(triggers.length!==1||!triggers[0].classList.contains('vscode-model-picker__trigger')
|
|
23640
|
+
||triggers[0].closest('.composer-bar')!==composer)return fail('legacy_model_trigger_ambiguous');
|
|
23641
|
+
const trigger=triggers[0],keys=Object.keys(trigger).filter(key=>key.startsWith('__reactFiber$'));
|
|
23642
|
+
if(keys.length!==1)return fail('legacy_model_tree_unconfirmed');
|
|
23643
|
+
const levels=[],visited=new Set();
|
|
23644
|
+
let root=null,currentRoot=null;
|
|
23645
|
+
for(let fiber=trigger[keys[0]];fiber;fiber=fiber.return){
|
|
23646
|
+
if(levels.length>=256||visited.has(fiber))return fail('legacy_model_tree_unconfirmed');
|
|
23647
|
+
const alternate=fiber.alternate||null;
|
|
23648
|
+
if(alternate&&(alternate===fiber||alternate.alternate!==fiber||visited.has(alternate)))return fail('legacy_model_tree_unconfirmed');
|
|
23649
|
+
visited.add(fiber);if(alternate)visited.add(alternate);
|
|
23650
|
+
const pair=alternate?[fiber,alternate]:[fiber];
|
|
23651
|
+
levels.push(pair);
|
|
23652
|
+
const state=fiber.stateNode;
|
|
23653
|
+
if(state&&state.current){
|
|
23654
|
+
if(fiber.tag!==3||fiber.return||!pair.includes(state.current)||alternate&&(alternate.tag!==3||alternate.stateNode!==state))return fail('legacy_model_tree_unconfirmed');
|
|
23655
|
+
root=state;currentRoot=state.current;break;
|
|
23656
|
+
}
|
|
23657
|
+
}
|
|
23658
|
+
if(!root)return fail('legacy_model_tree_unconfirmed');
|
|
23659
|
+
// DOM expandos may retain an old fiber or a borrowed return chain. Each
|
|
23660
|
+
// edge must belong to the committed parent's actual child/sibling list.
|
|
23661
|
+
const currentPath=[currentRoot],currentVisited=new Set(currentPath);
|
|
23662
|
+
let parent=currentRoot,nodeBudget=2048;
|
|
23663
|
+
for(let depth=levels.length-2;depth>=0;depth--){
|
|
23664
|
+
const candidates=[],siblings=new Set();
|
|
23665
|
+
for(let child=parent.child;child;child=child.sibling){
|
|
23666
|
+
if(--nodeBudget<0||siblings.has(child))return fail('legacy_model_tree_unconfirmed');
|
|
23667
|
+
siblings.add(child);
|
|
23668
|
+
if(levels[depth].includes(child))candidates.push(child);
|
|
23669
|
+
}
|
|
23670
|
+
if(candidates.length!==1||currentVisited.has(candidates[0]))return fail('legacy_model_tree_unconfirmed');
|
|
23671
|
+
parent=candidates[0];currentVisited.add(parent);currentPath.push(parent);
|
|
23672
|
+
}
|
|
23673
|
+
if(parent.stateNode!==trigger)return fail('legacy_model_tree_unconfirmed');
|
|
23674
|
+
const snapshots=new Set();
|
|
23675
|
+
for(const fiber of currentPath){
|
|
23676
|
+
const props=fiber.memoizedProps;
|
|
23677
|
+
if(!props||!Object.prototype.hasOwnProperty.call(props,'initialSelections')
|
|
23678
|
+
&&!Object.prototype.hasOwnProperty.call(props,'initialAutoMode'))continue;
|
|
23679
|
+
if(!Object.prototype.hasOwnProperty.call(props,'initialSelections')||!Object.prototype.hasOwnProperty.call(props,'initialAutoMode')
|
|
23680
|
+
||!Array.isArray(props.initialSelections)||typeof props.initialAutoMode!=='boolean')return fail('legacy_model_schema_unconfirmed');
|
|
23681
|
+
// Auto is never evidence for a named model, even if stale selections remain.
|
|
23682
|
+
if(props.initialAutoMode)return fail('legacy_model_auto');
|
|
23683
|
+
if(props.initialSelections.length!==1)return fail('legacy_model_selection_ambiguous');
|
|
23684
|
+
const selected=props.initialSelections[0];
|
|
23685
|
+
if(!selected||typeof selected.modelId!=='string'||!selected.modelId.trim()
|
|
23686
|
+
||selected.modelId!==selected.modelId.trim()||selected.count!==1||!Array.isArray(selected.parameters))return fail('legacy_model_schema_unconfirmed');
|
|
23687
|
+
if(selected.modelId.toLowerCase()==='default')return fail('legacy_model_auto');
|
|
23688
|
+
const parameters=[];
|
|
23689
|
+
for(const parameter of selected.parameters){
|
|
23690
|
+
if(!parameter||typeof parameter.id!=='string'||!parameter.id.trim()||parameter.id!==parameter.id.trim()
|
|
23691
|
+
||typeof parameter.value!=='string'||!parameter.value.length||parameters.some(entry=>entry[0]===parameter.id))return fail('legacy_model_schema_unconfirmed');
|
|
23692
|
+
parameters.push([parameter.id,parameter.value]);
|
|
23693
|
+
}
|
|
23694
|
+
parameters.sort((a,b)=>a[0]<b[0]?-1:a[0]>b[0]?1:0);
|
|
23695
|
+
snapshots.add(JSON.stringify({modelName:selected.modelId,selectedModels:[{modelId:selected.modelId,parameters:Object.fromEntries(parameters)}]}));
|
|
23696
|
+
}
|
|
23697
|
+
if(!snapshots.size)return fail('legacy_model_schema_unconfirmed');
|
|
23698
|
+
if(snapshots.size!==1)return fail('legacy_model_config_ambiguous');
|
|
23699
|
+
const snapshot=JSON.parse([...snapshots][0]);
|
|
23700
|
+
if(root.current!==currentRoot)return fail('legacy_model_tree_unconfirmed');
|
|
23701
|
+
return JSON.stringify({found:true,...snapshot,source});
|
|
23549
23702
|
})()`;
|
|
23550
23703
|
function normalizeModelPickerText(value) {
|
|
23551
23704
|
return String(value || "").trim().toLowerCase().replace(/extra[\s_-]*high/g, "xhigh").replace(/[^a-z0-9]+/g, "");
|
|
@@ -23709,30 +23862,93 @@ function matchSelectedAgentModelConfig(snapshot, requestedModel, requestedEffort
|
|
|
23709
23862
|
return { modelId: match.modelId, effort: effort || null };
|
|
23710
23863
|
}
|
|
23711
23864
|
function exprSelectAgentWorkspace(projectPath) {
|
|
23712
|
-
return `(async function(){
|
|
23713
|
-
const
|
|
23714
|
-
const normalize
|
|
23865
|
+
return String.raw`(async function(){
|
|
23866
|
+
const normalize=value=>String(value||'').replace(/\\/g,'/').replace(/^\/([a-z]:\/)/i,'$1').replace(/\/+$/,'').toLowerCase();
|
|
23867
|
+
const wanted=normalize(${JSON.stringify(String(projectPath || ""))});
|
|
23715
23868
|
const visible=node=>!!(node&&(node.offsetParent!==null||(node.getClientRects&&node.getClientRects().length>0)));
|
|
23716
23869
|
const pathTriggers=()=>[...document.querySelectorAll('button.ui-select-trigger,button[aria-haspopup="menu"]')]
|
|
23717
|
-
.filter(visible).filter(node=>/^[a-z]
|
|
23870
|
+
.filter(visible).filter(node=>/^[a-z]:\//i.test(normalize(node.innerText||node.textContent)));
|
|
23718
23871
|
const triggers=pathTriggers();
|
|
23719
23872
|
const fail=(state,extra={})=>JSON.stringify({ok:false,state,wanted,...extra,
|
|
23720
23873
|
nextStep:'Select the exact local workspace '+${JSON.stringify(String(projectPath || ""))}+' in the new Agent project picker before retrying.'});
|
|
23721
23874
|
if(triggers.length!==1)return fail(triggers.length?'workspace_project_selector_ambiguous':'workspace_project_selector_unavailable',{triggerCount:triggers.length});
|
|
23722
23875
|
triggers[0].click();
|
|
23723
23876
|
await new Promise(resolve=>setTimeout(resolve,350));
|
|
23724
|
-
const menus=[...document.querySelectorAll('[data-component="menu-popup"],[role="menu"]')].filter(visible)
|
|
23725
|
-
.
|
|
23877
|
+
const menus=[...new Set([...document.querySelectorAll('[data-component="menu-popup"],[role="menu"]')].filter(visible)
|
|
23878
|
+
.map(menu=>menu.getAttribute('role')==='menu'&&menu.getAttribute('aria-label')==='Select a project'
|
|
23879
|
+
?menu:menu.querySelector('[role="menu"][aria-label="Select a project"]')).filter(visible))];
|
|
23880
|
+
if(menus.length!==1)return fail(menus.length?'workspace_project_option_ambiguous':'workspace_project_option_unavailable',{menuCount:menus.length});
|
|
23726
23881
|
const rows=[];const seen=new Set();
|
|
23727
23882
|
for(const menu of menus){
|
|
23728
23883
|
for(const row of menu.querySelectorAll('[data-component="menu-row"][role="menuitem"],[role="option"]')){
|
|
23729
23884
|
if(!visible(row)||seen.has(row))continue;seen.add(row);rows.push(row);
|
|
23730
23885
|
}
|
|
23731
23886
|
}
|
|
23732
|
-
const available=rows.map(row=>String(row.innerText||row.textContent||'').replace(
|
|
23733
|
-
const
|
|
23887
|
+
const available=rows.map(row=>String(row.innerText||row.textContent||'').replace(/\s+/g,' ').trim());
|
|
23888
|
+
const rowWorkspace=row=>{
|
|
23889
|
+
const key=Object.keys(row).find(key=>key.startsWith('__reactFiber$'));
|
|
23890
|
+
const levels=[];const visited=new Set();
|
|
23891
|
+
let root=null,currentRoot=null,hasProject=false,belowMenu=true;
|
|
23892
|
+
for(let fiber=key&&row[key];fiber;fiber=fiber.return){
|
|
23893
|
+
if(levels.length>=256||visited.has(fiber))return null;
|
|
23894
|
+
visited.add(fiber);
|
|
23895
|
+
const alternate=fiber.alternate||null;
|
|
23896
|
+
if(alternate&&(alternate===fiber||alternate.alternate!==fiber||visited.has(alternate)))return null;
|
|
23897
|
+
const pair=alternate?[fiber,alternate]:[fiber];
|
|
23898
|
+
levels.push(pair);
|
|
23899
|
+
if(pair.some(node=>node.stateNode===menus[0]))belowMenu=false;
|
|
23900
|
+
if(belowMenu&&pair.some(node=>node.memoizedProps&&Object.prototype.hasOwnProperty.call(node.memoizedProps,'project')))hasProject=true;
|
|
23901
|
+
const state=fiber.stateNode;
|
|
23902
|
+
if(state&&state.current){
|
|
23903
|
+
if(!pair.includes(state.current)||alternate&&alternate.stateNode!==state)return null;
|
|
23904
|
+
root=state;currentRoot=state.current;break;
|
|
23905
|
+
}
|
|
23906
|
+
}
|
|
23907
|
+
// Older pickers expose the complete path as row text without project metadata.
|
|
23908
|
+
if(!hasProject)return {path:normalize(row.innerText||row.textContent)};
|
|
23909
|
+
if(!root)return null;
|
|
23910
|
+
// A DOM expando can retain an old fiber, including a borrowed current return
|
|
23911
|
+
// chain. Prove every edge through the committed parent's child/sibling list.
|
|
23912
|
+
const currentPath=[currentRoot];const currentVisited=new Set(currentPath);
|
|
23913
|
+
let parent=currentRoot,nodeBudget=2048;
|
|
23914
|
+
for(let depth=levels.length-2;depth>=0;depth--){
|
|
23915
|
+
const candidates=[];const siblings=new Set();
|
|
23916
|
+
for(let child=parent.child;child;child=child.sibling){
|
|
23917
|
+
if(--nodeBudget<0||siblings.has(child))return null;
|
|
23918
|
+
siblings.add(child);
|
|
23919
|
+
if(levels[depth].includes(child))candidates.push(child);
|
|
23920
|
+
}
|
|
23921
|
+
if(candidates.length!==1||currentVisited.has(candidates[0]))return null;
|
|
23922
|
+
parent=candidates[0];currentVisited.add(parent);currentPath.push(parent);
|
|
23923
|
+
}
|
|
23924
|
+
if(parent.stateNode!==row)return null;
|
|
23925
|
+
const menuIndexes=currentPath.flatMap((node,index)=>node.stateNode===menus[0]?[index]:[]);
|
|
23926
|
+
if(menuIndexes.length!==1)return null;
|
|
23927
|
+
const projects=new Set();
|
|
23928
|
+
for(const fiber of currentPath.slice(menuIndexes[0]+1)){
|
|
23929
|
+
const props=fiber.memoizedProps;
|
|
23930
|
+
if(props&&Object.prototype.hasOwnProperty.call(props,'project'))projects.add(props.project);
|
|
23931
|
+
}
|
|
23932
|
+
if(!projects.size)return null;
|
|
23933
|
+
const identities=new Set();
|
|
23934
|
+
for(const project of projects){
|
|
23935
|
+
const identifier=project&&project.workspaceIdentifier;
|
|
23936
|
+
const uri=identifier&&(identifier.uri||identifier.configPath);
|
|
23937
|
+
if(!project||project.remoteAuthority||!identifier||identifier.remoteAuthority||typeof identifier.id!=='string'||!identifier.id.trim()
|
|
23938
|
+
||!uri||uri.scheme!=='file'||uri.authority||uri.remoteAuthority)return null;
|
|
23939
|
+
const paths=[uri.fsPath,uri._fsPath,uri.path].filter(value=>typeof value==='string'&&value.length).map(normalize);
|
|
23940
|
+
if(!paths.length||paths.some(path=>path!==paths[0]))return null;
|
|
23941
|
+
identities.add(JSON.stringify([identifier.id,paths[0]]));
|
|
23942
|
+
}
|
|
23943
|
+
if(identities.size!==1)return null;
|
|
23944
|
+
const [workspaceId,path]=JSON.parse([...identities][0]);
|
|
23945
|
+
return {path,workspaceId,root,currentRoot};
|
|
23946
|
+
};
|
|
23947
|
+
const matches=rows.map(row=>({row,identity:rowWorkspace(row)})).filter(match=>match.identity&&match.identity.path===wanted);
|
|
23734
23948
|
if(matches.length!==1)return fail(matches.length?'workspace_project_option_ambiguous':'workspace_project_option_unavailable',{available});
|
|
23735
|
-
matches[0]
|
|
23949
|
+
const selected=matches[0];
|
|
23950
|
+
if(selected.identity.root&&selected.identity.root.current!==selected.identity.currentRoot)return fail('workspace_project_option_unavailable',{available});
|
|
23951
|
+
selected.row.click();
|
|
23736
23952
|
await new Promise(resolve=>setTimeout(resolve,350));
|
|
23737
23953
|
return JSON.stringify({ok:true,state:'workspace_project_selection_requested',workspace:wanted,available});
|
|
23738
23954
|
})()`;
|
|
@@ -23902,7 +24118,11 @@ var REACT_ADAPTER_BODY = `
|
|
|
23902
24118
|
let globalSelectAgent=null;
|
|
23903
24119
|
let globalSelectedAgentId=null;
|
|
23904
24120
|
let sectionIdByAgentId=null;
|
|
23905
|
-
|
|
24121
|
+
const roots=new Set([
|
|
24122
|
+
...document.querySelectorAll('.glass-sidebar-agent-list-container'),
|
|
24123
|
+
...document.querySelectorAll('.ui-sidebar-section-head')
|
|
24124
|
+
]);
|
|
24125
|
+
for(const root of roots){
|
|
23906
24126
|
const nodes=[]; let n=root;
|
|
23907
24127
|
for(let i=0;n&&i<24;i++,n=n.parentElement)nodes.push(n);
|
|
23908
24128
|
for(const node of nodes){
|
|
@@ -24021,6 +24241,26 @@ var REACT_ADAPTER_BODY = `
|
|
|
24021
24241
|
};
|
|
24022
24242
|
};
|
|
24023
24243
|
const a=findAdapter();`;
|
|
24244
|
+
var EXPR_VISIBLE_COMPOSER = `(function(){
|
|
24245
|
+
${STOP_COMPOSER_BODY}
|
|
24246
|
+
const {modern,composers}=findStopComposers(null);
|
|
24247
|
+
if(composers.length!==1){
|
|
24248
|
+
return JSON.stringify({ok:false,state:composers.length?'ambiguous_composers':'composer_missing',count:composers.length});
|
|
24249
|
+
}
|
|
24250
|
+
const composer=composers[0];
|
|
24251
|
+
let status=composer.dataset.composerStatus||null;
|
|
24252
|
+
if(modern){
|
|
24253
|
+
${REACT_ADAPTER_BODY}
|
|
24254
|
+
status=modernComposerStatus(composer,a?a.entries():[]);
|
|
24255
|
+
}
|
|
24256
|
+
const composerId=modern?composer.dataset.glassAgentId:composer.dataset.composerId;
|
|
24257
|
+
return JSON.stringify({
|
|
24258
|
+
ok:true,
|
|
24259
|
+
id:'local:'+composerId,
|
|
24260
|
+
composerId,
|
|
24261
|
+
status
|
|
24262
|
+
});
|
|
24263
|
+
})()`;
|
|
24024
24264
|
var EXPR_AGENT_ADAPTER_READY = `(function(){${REACT_ADAPTER_BODY}return !!a;})()`;
|
|
24025
24265
|
var EXPR_PAGE_CAPABILITIES = `(function(){${INPUT_PICKER_BODY}
|
|
24026
24266
|
const visible=node=>!!(node&&(node.offsetParent!==null||(typeof node.getClientRects==='function'&&node.getClientRects().length>0)));
|
|
@@ -25655,7 +25895,7 @@ var CursorBridge = class {
|
|
|
25655
25895
|
}
|
|
25656
25896
|
async _readModelPickerRows(c, options) {
|
|
25657
25897
|
const snapshot = await this._readModelPickerValue(c, EXPR_MODEL_PICKER_ROWS, "rows", options);
|
|
25658
|
-
return { open: snapshot.open === true, rows: Array.isArray(snapshot.rows) ? snapshot.rows : [] };
|
|
25898
|
+
return { open: snapshot.open === true, rows: Array.isArray(snapshot.rows) ? snapshot.rows : [], owner: snapshot.owner || null };
|
|
25659
25899
|
}
|
|
25660
25900
|
async _readSelectedAgentModelConfig(c, options) {
|
|
25661
25901
|
return this._readModelPickerValue(c, EXPR_SELECTED_AGENT_MODEL_CONFIG, "selected_agent_model_config", options);
|
|
@@ -25673,19 +25913,67 @@ var CursorBridge = class {
|
|
|
25673
25913
|
if (!point || !Number.isFinite(Number(point.x)) || !Number.isFinite(Number(point.y))) return;
|
|
25674
25914
|
await c.send("Input.dispatchMouseEvent", { type: "mouseMoved", x: Number(point.x), y: Number(point.y) });
|
|
25675
25915
|
}
|
|
25676
|
-
async
|
|
25677
|
-
|
|
25678
|
-
|
|
25679
|
-
|
|
25680
|
-
|
|
25681
|
-
|
|
25682
|
-
|
|
25683
|
-
|
|
25684
|
-
|
|
25685
|
-
|
|
25686
|
-
|
|
25687
|
-
|
|
25688
|
-
|
|
25916
|
+
async _activateClosedModelPicker(c, trigger, options) {
|
|
25917
|
+
return this._readModelPickerValue(c, exprActivateClosedModelPicker(trigger), "closed_trigger_activation", options);
|
|
25918
|
+
}
|
|
25919
|
+
async _openModelPicker(c, job = null, options = {}) {
|
|
25920
|
+
const timeoutMs = Math.max(0, Number(options.timeoutMs ?? 2e3));
|
|
25921
|
+
const pollMs = Math.max(10, Number(options.pollMs ?? 50));
|
|
25922
|
+
const stableMs = Math.max(0, Number(options.stableMs ?? 100));
|
|
25923
|
+
const recoveryDelayMs = Math.max(0, Number(options.recoveryDelayMs ?? 750));
|
|
25924
|
+
const deadline = Date.now() + timeoutMs;
|
|
25925
|
+
let trigger = null, snapshot = { open: false, rows: [] };
|
|
25926
|
+
let stableSignature = null, stableSince = 0, clicked = false, clickedOwner = null;
|
|
25927
|
+
let clickedAt = 0, recoveryAttempted = false, lastPollError = null;
|
|
25928
|
+
const attempts = [];
|
|
25929
|
+
do {
|
|
25930
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25931
|
+
if (deadline - Date.now() < 10) break;
|
|
25932
|
+
try {
|
|
25933
|
+
snapshot = await this._readModelPickerRows(c, { timeoutMs: deadline - Date.now() });
|
|
25934
|
+
if (deadline - Date.now() < 10) break;
|
|
25935
|
+
trigger = await this._readModelPickerTrigger(c, { timeoutMs: deadline - Date.now() });
|
|
25936
|
+
} catch (error2) {
|
|
25937
|
+
if (error2.code !== "CDP_COMMAND_TIMEOUT" || Date.now() < deadline) throw error2;
|
|
25938
|
+
lastPollError = error2.pickerRead || { code: error2.code, message: error2.message };
|
|
25939
|
+
break;
|
|
25940
|
+
}
|
|
25941
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25942
|
+
const sameOwner = modelPickerOwnerKey(snapshot.owner) === modelPickerOwnerKey(trigger);
|
|
25943
|
+
if (snapshot.open && trigger.found && sameOwner && (!clicked || clickedOwner === modelPickerOwnerKey(trigger))) return { trigger, ...snapshot };
|
|
25944
|
+
if (snapshot.open && !sameOwner && !attempts.includes("owner_changed")) attempts.push("owner_changed");
|
|
25945
|
+
if (!clicked) {
|
|
25946
|
+
const interactive = trigger.found && trigger.interactive !== false;
|
|
25947
|
+
const signature = interactive ? JSON.stringify([trigger.triggerId, trigger.composerId, trigger.agentId, trigger.x, trigger.y]) : null;
|
|
25948
|
+
if (!interactive || signature !== stableSignature) {
|
|
25949
|
+
stableSignature = signature;
|
|
25950
|
+
stableSince = Date.now();
|
|
25951
|
+
const state = trigger.state || (interactive ? "ready" : "trigger_missing");
|
|
25952
|
+
if (!attempts.includes(state)) attempts.push(state);
|
|
25953
|
+
}
|
|
25954
|
+
if (interactive && Date.now() - stableSince >= stableMs) {
|
|
25955
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25956
|
+
await this._clickModelPickerPoint(c, trigger);
|
|
25957
|
+
clicked = true;
|
|
25958
|
+
clickedAt = Date.now();
|
|
25959
|
+
clickedOwner = modelPickerOwnerKey(trigger);
|
|
25960
|
+
attempts.push("click_once", "wait_menu");
|
|
25961
|
+
}
|
|
25962
|
+
} else if (!recoveryAttempted && !snapshot.open && sameOwner && clickedOwner === modelPickerOwnerKey(trigger) && trigger.interactive === true && trigger.expanded === "false" && Date.now() - clickedAt >= recoveryDelayMs && deadline - Date.now() >= 10) {
|
|
25963
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25964
|
+
recoveryAttempted = true;
|
|
25965
|
+
const recovered = await this._activateClosedModelPicker(c, trigger, { timeoutMs: deadline - Date.now() });
|
|
25966
|
+
attempts.push(recovered.clicked ? "activate_confirmed_closed_trigger" : recovered.state || "activation_rejected");
|
|
25967
|
+
}
|
|
25968
|
+
if (Date.now() >= deadline) break;
|
|
25969
|
+
await sleep2(Math.min(pollMs, Math.max(0, deadline - Date.now())));
|
|
25970
|
+
} while (Date.now() < deadline);
|
|
25971
|
+
throw createModelSelectionError("Cursor model picker did not open", "picker_did_not_open", true, {
|
|
25972
|
+
attempts,
|
|
25973
|
+
trigger,
|
|
25974
|
+
lastPollError,
|
|
25975
|
+
menu: { open: snapshot.open, rows: (snapshot.rows || []).slice(0, 20) }
|
|
25976
|
+
});
|
|
25689
25977
|
}
|
|
25690
25978
|
async _closeModelPicker(c) {
|
|
25691
25979
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
@@ -25697,24 +25985,29 @@ var CursorBridge = class {
|
|
|
25697
25985
|
}
|
|
25698
25986
|
if ((await this._readModelPickerRows(c)).open) throw new Error("Cursor model picker did not close after selection");
|
|
25699
25987
|
}
|
|
25700
|
-
async _openModelPickerControl(c, snapshot, controlKind) {
|
|
25988
|
+
async _openModelPickerControl(c, snapshot, controlKind, job = null) {
|
|
25989
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25701
25990
|
const control = (snapshot && snapshot.rows || []).find((row) => row.kind === controlKind && row.disabled !== true);
|
|
25702
25991
|
if (!control) return snapshot;
|
|
25992
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25703
25993
|
await this._clickModelPickerPoint(c, control);
|
|
25704
25994
|
await sleep2(400);
|
|
25705
25995
|
let next = await this._readModelPickerRows(c);
|
|
25706
25996
|
const expectedKind = controlKind === "model_control" ? "model" : "parameter";
|
|
25707
25997
|
if (!next.rows.some((row) => row.kind === expectedKind)) {
|
|
25998
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25708
25999
|
await this._hoverModelPickerPoint(c, control);
|
|
25709
26000
|
await sleep2(350);
|
|
25710
26001
|
next = await this._readModelPickerRows(c);
|
|
25711
26002
|
}
|
|
25712
26003
|
return next;
|
|
25713
26004
|
}
|
|
25714
|
-
async _findModelPickerModel(c, snapshot, requestedModel) {
|
|
26005
|
+
async _findModelPickerModel(c, snapshot, requestedModel, job = null) {
|
|
26006
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25715
26007
|
let modelRow = selectModelPickerRow(snapshot && snapshot.rows, requestedModel, "model");
|
|
25716
26008
|
if (modelRow) return { snapshot, modelRow };
|
|
25717
|
-
const expanded = await this._openModelPickerControl(c, snapshot, "model_control");
|
|
26009
|
+
const expanded = await this._openModelPickerControl(c, snapshot, "model_control", job);
|
|
26010
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25718
26011
|
modelRow = selectModelPickerRow(expanded && expanded.rows, requestedModel, "model");
|
|
25719
26012
|
return { snapshot: expanded, modelRow };
|
|
25720
26013
|
}
|
|
@@ -25859,9 +26152,9 @@ var CursorBridge = class {
|
|
|
25859
26152
|
if (job) job.modelSelection = result2;
|
|
25860
26153
|
return result2;
|
|
25861
26154
|
}
|
|
25862
|
-
const opened = await this._openModelPicker(c);
|
|
26155
|
+
const opened = await this._openModelPicker(c, job);
|
|
25863
26156
|
stage = "locate_model";
|
|
25864
|
-
let located = await this._findModelPickerModel(c, opened, requestedModel);
|
|
26157
|
+
let located = await this._findModelPickerModel(c, opened, requestedModel, job);
|
|
25865
26158
|
modelRow = located.modelRow;
|
|
25866
26159
|
if (!modelRow) {
|
|
25867
26160
|
throw createModelSelectionError(
|
|
@@ -25877,8 +26170,8 @@ var CursorBridge = class {
|
|
|
25877
26170
|
if (!outcome.row && outcome.state === "not_rendered" && !effortPickerReopened) {
|
|
25878
26171
|
effortPickerReopened = true;
|
|
25879
26172
|
await this._closeModelPicker(c);
|
|
25880
|
-
const reopened = await this._openModelPicker(c);
|
|
25881
|
-
located = await this._findModelPickerModel(c, reopened, requestedModel);
|
|
26173
|
+
const reopened = await this._openModelPicker(c, job);
|
|
26174
|
+
located = await this._findModelPickerModel(c, reopened, requestedModel, job);
|
|
25882
26175
|
modelRow = located.modelRow;
|
|
25883
26176
|
if (!modelRow) {
|
|
25884
26177
|
throw createModelSelectionError(
|
|
@@ -25921,8 +26214,8 @@ var CursorBridge = class {
|
|
|
25921
26214
|
this._throwIfCancelledBeforeSend(job);
|
|
25922
26215
|
await this._clickModelPickerPoint(c, modelRow);
|
|
25923
26216
|
await sleep2(550);
|
|
25924
|
-
const reopened = await this._openModelPicker(c);
|
|
25925
|
-
located = await this._findModelPickerModel(c, reopened, requestedModel);
|
|
26217
|
+
const reopened = await this._openModelPicker(c, job);
|
|
26218
|
+
located = await this._findModelPickerModel(c, reopened, requestedModel, job);
|
|
25926
26219
|
modelRow = located.modelRow;
|
|
25927
26220
|
if (!modelRow) {
|
|
25928
26221
|
throw createModelSelectionError(
|
|
@@ -25949,8 +26242,8 @@ var CursorBridge = class {
|
|
|
25949
26242
|
stage = "verify_model";
|
|
25950
26243
|
let trigger2 = await this._readModelPickerTrigger(c);
|
|
25951
26244
|
if (!trigger2.found || !normalizeModelPickerModelText(trigger2.text).includes(normalizeModelPickerModelText(requestedModel))) {
|
|
25952
|
-
const reopened = await this._openModelPicker(c);
|
|
25953
|
-
located = await this._findModelPickerModel(c, reopened, requestedModel);
|
|
26245
|
+
const reopened = await this._openModelPicker(c, job);
|
|
26246
|
+
located = await this._findModelPickerModel(c, reopened, requestedModel, job);
|
|
25954
26247
|
const selected = selectModelPickerRow(located.snapshot.rows.filter((row) => row.selected), requestedModel, "model");
|
|
25955
26248
|
if (!selected) {
|
|
25956
26249
|
throw createModelSelectionError(
|
|
@@ -25963,8 +26256,8 @@ var CursorBridge = class {
|
|
|
25963
26256
|
}
|
|
25964
26257
|
if (requestedEffort) {
|
|
25965
26258
|
stage = "verify_effort";
|
|
25966
|
-
const reopened = await this._openModelPicker(c);
|
|
25967
|
-
located = await this._findModelPickerModel(c, reopened, requestedModel);
|
|
26259
|
+
const reopened = await this._openModelPicker(c, job);
|
|
26260
|
+
located = await this._findModelPickerModel(c, reopened, requestedModel, job);
|
|
25968
26261
|
modelRow = located.modelRow;
|
|
25969
26262
|
if (!modelRow) {
|
|
25970
26263
|
throw createModelSelectionError(
|
|
@@ -26019,6 +26312,8 @@ var CursorBridge = class {
|
|
|
26019
26312
|
errorCode: primaryError.code || `CURSOR_MODEL_${String(failure.failureClass).toUpperCase()}`,
|
|
26020
26313
|
available: failure.available || [],
|
|
26021
26314
|
attempts: failure.attempts || [],
|
|
26315
|
+
trigger: failure.trigger || null,
|
|
26316
|
+
lastPollError: failure.lastPollError || null,
|
|
26022
26317
|
menu: failure.menu || null,
|
|
26023
26318
|
runtimeMode: this.runtimeMode,
|
|
26024
26319
|
lastError: primaryError.message,
|
|
@@ -28106,6 +28401,7 @@ export {
|
|
|
28106
28401
|
createChatPanelUnavailableError,
|
|
28107
28402
|
createProviderError,
|
|
28108
28403
|
cursorStartupBehavior,
|
|
28404
|
+
exprActivateClosedModelPicker,
|
|
28109
28405
|
exprClickBoundComposerStop,
|
|
28110
28406
|
exprClickSelectedAgentStop,
|
|
28111
28407
|
exprCreateAgentForWorkspace,
|
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.8",
|
|
14
14
|
serverName: "cursor-bridge",
|
|
15
15
|
serverScript: join(packageRoot, "dist", "cursor-bridge.mjs"),
|
|
16
16
|
cwd: hostCwd,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-cursor-bridge",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
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",
|
|
@@ -47,6 +47,6 @@
|
|
|
47
47
|
},
|
|
48
48
|
"piPackage": {
|
|
49
49
|
"embeddedProduct": "Cursor Bridge",
|
|
50
|
-
"embeddedProductVersion": "6.0.
|
|
50
|
+
"embeddedProductVersion": "6.0.8"
|
|
51
51
|
}
|
|
52
52
|
}
|