pi-cursor-bridge 0.2.6 → 0.2.7
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 +229 -41
- 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.7 embeds Cursor Bridge 6.0.7, 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.7";
|
|
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
|
}
|
|
@@ -23540,12 +23563,90 @@ var EXPR_SELECTED_AGENT_MODEL_CONFIG = `(function(){
|
|
|
23540
23563
|
if(data&&data.modelConfig&&!configs.includes(data.modelConfig))configs.push(data.modelConfig);
|
|
23541
23564
|
}
|
|
23542
23565
|
}
|
|
23543
|
-
if(configs.length
|
|
23544
|
-
|
|
23545
|
-
|
|
23546
|
-
|
|
23547
|
-
|
|
23548
|
-
|
|
23566
|
+
if(configs.length>1)return JSON.stringify({found:false,state:'model_config_ambiguous',configCount:configs.length});
|
|
23567
|
+
if(configs.length===1){
|
|
23568
|
+
const config=configs[0];
|
|
23569
|
+
return JSON.stringify({found:true,modelName:String(config.modelName||''),selectedModels:(config.selectedModels||[]).map(model=>({
|
|
23570
|
+
modelId:String(model&&model.modelId||''),
|
|
23571
|
+
parameters:Object.fromEntries((model&&model.parameters||[]).map(parameter=>[String(parameter&¶meter.id||''),String(parameter&¶meter.value||'')]))
|
|
23572
|
+
}))});
|
|
23573
|
+
}
|
|
23574
|
+
// Cursor 3.23's IDE input is Solid; its model trigger is a mounted React
|
|
23575
|
+
// picker whose initialSelections/initialAutoMode come from this composer.
|
|
23576
|
+
const source='legacy_composer_model_trigger';
|
|
23577
|
+
const fail=(state)=>JSON.stringify({found:false,state,source});
|
|
23578
|
+
const input=inputs[0],composer=input.closest('.composer-bar[data-composer-id]');
|
|
23579
|
+
if(!composer||input.closest('.composer-bar')!==composer
|
|
23580
|
+
||composer.parentElement&&composer.parentElement.closest('.composer-bar')
|
|
23581
|
+
||composer.querySelectorAll('.composer-bar').length)return fail('legacy_composer_ambiguous');
|
|
23582
|
+
const composerId=composer.getAttribute('data-composer-id');
|
|
23583
|
+
const owners=[...document.querySelectorAll('.composer-bar[data-composer-id]')]
|
|
23584
|
+
.filter(node=>node.getAttribute('data-composer-id')===composerId);
|
|
23585
|
+
if(typeof composerId!=='string'||!composerId.trim()||owners.length!==1||owners[0]!==composer)return fail('legacy_composer_ambiguous');
|
|
23586
|
+
const triggers=[...composer.querySelectorAll('.vscode-model-picker__trigger')];
|
|
23587
|
+
if(triggers.length!==1||!triggers[0].classList.contains('vscode-model-picker__trigger')
|
|
23588
|
+
||triggers[0].closest('.composer-bar')!==composer)return fail('legacy_model_trigger_ambiguous');
|
|
23589
|
+
const trigger=triggers[0],keys=Object.keys(trigger).filter(key=>key.startsWith('__reactFiber$'));
|
|
23590
|
+
if(keys.length!==1)return fail('legacy_model_tree_unconfirmed');
|
|
23591
|
+
const levels=[],visited=new Set();
|
|
23592
|
+
let root=null,currentRoot=null;
|
|
23593
|
+
for(let fiber=trigger[keys[0]];fiber;fiber=fiber.return){
|
|
23594
|
+
if(levels.length>=256||visited.has(fiber))return fail('legacy_model_tree_unconfirmed');
|
|
23595
|
+
const alternate=fiber.alternate||null;
|
|
23596
|
+
if(alternate&&(alternate===fiber||alternate.alternate!==fiber||visited.has(alternate)))return fail('legacy_model_tree_unconfirmed');
|
|
23597
|
+
visited.add(fiber);if(alternate)visited.add(alternate);
|
|
23598
|
+
const pair=alternate?[fiber,alternate]:[fiber];
|
|
23599
|
+
levels.push(pair);
|
|
23600
|
+
const state=fiber.stateNode;
|
|
23601
|
+
if(state&&state.current){
|
|
23602
|
+
if(fiber.tag!==3||fiber.return||!pair.includes(state.current)||alternate&&(alternate.tag!==3||alternate.stateNode!==state))return fail('legacy_model_tree_unconfirmed');
|
|
23603
|
+
root=state;currentRoot=state.current;break;
|
|
23604
|
+
}
|
|
23605
|
+
}
|
|
23606
|
+
if(!root)return fail('legacy_model_tree_unconfirmed');
|
|
23607
|
+
// DOM expandos may retain an old fiber or a borrowed return chain. Each
|
|
23608
|
+
// edge must belong to the committed parent's actual child/sibling list.
|
|
23609
|
+
const currentPath=[currentRoot],currentVisited=new Set(currentPath);
|
|
23610
|
+
let parent=currentRoot,nodeBudget=2048;
|
|
23611
|
+
for(let depth=levels.length-2;depth>=0;depth--){
|
|
23612
|
+
const candidates=[],siblings=new Set();
|
|
23613
|
+
for(let child=parent.child;child;child=child.sibling){
|
|
23614
|
+
if(--nodeBudget<0||siblings.has(child))return fail('legacy_model_tree_unconfirmed');
|
|
23615
|
+
siblings.add(child);
|
|
23616
|
+
if(levels[depth].includes(child))candidates.push(child);
|
|
23617
|
+
}
|
|
23618
|
+
if(candidates.length!==1||currentVisited.has(candidates[0]))return fail('legacy_model_tree_unconfirmed');
|
|
23619
|
+
parent=candidates[0];currentVisited.add(parent);currentPath.push(parent);
|
|
23620
|
+
}
|
|
23621
|
+
if(parent.stateNode!==trigger)return fail('legacy_model_tree_unconfirmed');
|
|
23622
|
+
const snapshots=new Set();
|
|
23623
|
+
for(const fiber of currentPath){
|
|
23624
|
+
const props=fiber.memoizedProps;
|
|
23625
|
+
if(!props||!Object.prototype.hasOwnProperty.call(props,'initialSelections')
|
|
23626
|
+
&&!Object.prototype.hasOwnProperty.call(props,'initialAutoMode'))continue;
|
|
23627
|
+
if(!Object.prototype.hasOwnProperty.call(props,'initialSelections')||!Object.prototype.hasOwnProperty.call(props,'initialAutoMode')
|
|
23628
|
+
||!Array.isArray(props.initialSelections)||typeof props.initialAutoMode!=='boolean')return fail('legacy_model_schema_unconfirmed');
|
|
23629
|
+
// Auto is never evidence for a named model, even if stale selections remain.
|
|
23630
|
+
if(props.initialAutoMode)return fail('legacy_model_auto');
|
|
23631
|
+
if(props.initialSelections.length!==1)return fail('legacy_model_selection_ambiguous');
|
|
23632
|
+
const selected=props.initialSelections[0];
|
|
23633
|
+
if(!selected||typeof selected.modelId!=='string'||!selected.modelId.trim()
|
|
23634
|
+
||selected.modelId!==selected.modelId.trim()||selected.count!==1||!Array.isArray(selected.parameters))return fail('legacy_model_schema_unconfirmed');
|
|
23635
|
+
if(selected.modelId.toLowerCase()==='default')return fail('legacy_model_auto');
|
|
23636
|
+
const parameters=[];
|
|
23637
|
+
for(const parameter of selected.parameters){
|
|
23638
|
+
if(!parameter||typeof parameter.id!=='string'||!parameter.id.trim()||parameter.id!==parameter.id.trim()
|
|
23639
|
+
||typeof parameter.value!=='string'||!parameter.value.length||parameters.some(entry=>entry[0]===parameter.id))return fail('legacy_model_schema_unconfirmed');
|
|
23640
|
+
parameters.push([parameter.id,parameter.value]);
|
|
23641
|
+
}
|
|
23642
|
+
parameters.sort((a,b)=>a[0]<b[0]?-1:a[0]>b[0]?1:0);
|
|
23643
|
+
snapshots.add(JSON.stringify({modelName:selected.modelId,selectedModels:[{modelId:selected.modelId,parameters:Object.fromEntries(parameters)}]}));
|
|
23644
|
+
}
|
|
23645
|
+
if(!snapshots.size)return fail('legacy_model_schema_unconfirmed');
|
|
23646
|
+
if(snapshots.size!==1)return fail('legacy_model_config_ambiguous');
|
|
23647
|
+
const snapshot=JSON.parse([...snapshots][0]);
|
|
23648
|
+
if(root.current!==currentRoot)return fail('legacy_model_tree_unconfirmed');
|
|
23649
|
+
return JSON.stringify({found:true,...snapshot,source});
|
|
23549
23650
|
})()`;
|
|
23550
23651
|
function normalizeModelPickerText(value) {
|
|
23551
23652
|
return String(value || "").trim().toLowerCase().replace(/extra[\s_-]*high/g, "xhigh").replace(/[^a-z0-9]+/g, "");
|
|
@@ -23709,30 +23810,93 @@ function matchSelectedAgentModelConfig(snapshot, requestedModel, requestedEffort
|
|
|
23709
23810
|
return { modelId: match.modelId, effort: effort || null };
|
|
23710
23811
|
}
|
|
23711
23812
|
function exprSelectAgentWorkspace(projectPath) {
|
|
23712
|
-
return `(async function(){
|
|
23713
|
-
const
|
|
23714
|
-
const normalize
|
|
23813
|
+
return String.raw`(async function(){
|
|
23814
|
+
const normalize=value=>String(value||'').replace(/\\/g,'/').replace(/^\/([a-z]:\/)/i,'$1').replace(/\/+$/,'').toLowerCase();
|
|
23815
|
+
const wanted=normalize(${JSON.stringify(String(projectPath || ""))});
|
|
23715
23816
|
const visible=node=>!!(node&&(node.offsetParent!==null||(node.getClientRects&&node.getClientRects().length>0)));
|
|
23716
23817
|
const pathTriggers=()=>[...document.querySelectorAll('button.ui-select-trigger,button[aria-haspopup="menu"]')]
|
|
23717
|
-
.filter(visible).filter(node=>/^[a-z]
|
|
23818
|
+
.filter(visible).filter(node=>/^[a-z]:\//i.test(normalize(node.innerText||node.textContent)));
|
|
23718
23819
|
const triggers=pathTriggers();
|
|
23719
23820
|
const fail=(state,extra={})=>JSON.stringify({ok:false,state,wanted,...extra,
|
|
23720
23821
|
nextStep:'Select the exact local workspace '+${JSON.stringify(String(projectPath || ""))}+' in the new Agent project picker before retrying.'});
|
|
23721
23822
|
if(triggers.length!==1)return fail(triggers.length?'workspace_project_selector_ambiguous':'workspace_project_selector_unavailable',{triggerCount:triggers.length});
|
|
23722
23823
|
triggers[0].click();
|
|
23723
23824
|
await new Promise(resolve=>setTimeout(resolve,350));
|
|
23724
|
-
const menus=[...document.querySelectorAll('[data-component="menu-popup"],[role="menu"]')].filter(visible)
|
|
23725
|
-
.
|
|
23825
|
+
const menus=[...new Set([...document.querySelectorAll('[data-component="menu-popup"],[role="menu"]')].filter(visible)
|
|
23826
|
+
.map(menu=>menu.getAttribute('role')==='menu'&&menu.getAttribute('aria-label')==='Select a project'
|
|
23827
|
+
?menu:menu.querySelector('[role="menu"][aria-label="Select a project"]')).filter(visible))];
|
|
23828
|
+
if(menus.length!==1)return fail(menus.length?'workspace_project_option_ambiguous':'workspace_project_option_unavailable',{menuCount:menus.length});
|
|
23726
23829
|
const rows=[];const seen=new Set();
|
|
23727
23830
|
for(const menu of menus){
|
|
23728
23831
|
for(const row of menu.querySelectorAll('[data-component="menu-row"][role="menuitem"],[role="option"]')){
|
|
23729
23832
|
if(!visible(row)||seen.has(row))continue;seen.add(row);rows.push(row);
|
|
23730
23833
|
}
|
|
23731
23834
|
}
|
|
23732
|
-
const available=rows.map(row=>String(row.innerText||row.textContent||'').replace(
|
|
23733
|
-
const
|
|
23835
|
+
const available=rows.map(row=>String(row.innerText||row.textContent||'').replace(/\s+/g,' ').trim());
|
|
23836
|
+
const rowWorkspace=row=>{
|
|
23837
|
+
const key=Object.keys(row).find(key=>key.startsWith('__reactFiber$'));
|
|
23838
|
+
const levels=[];const visited=new Set();
|
|
23839
|
+
let root=null,currentRoot=null,hasProject=false,belowMenu=true;
|
|
23840
|
+
for(let fiber=key&&row[key];fiber;fiber=fiber.return){
|
|
23841
|
+
if(levels.length>=256||visited.has(fiber))return null;
|
|
23842
|
+
visited.add(fiber);
|
|
23843
|
+
const alternate=fiber.alternate||null;
|
|
23844
|
+
if(alternate&&(alternate===fiber||alternate.alternate!==fiber||visited.has(alternate)))return null;
|
|
23845
|
+
const pair=alternate?[fiber,alternate]:[fiber];
|
|
23846
|
+
levels.push(pair);
|
|
23847
|
+
if(pair.some(node=>node.stateNode===menus[0]))belowMenu=false;
|
|
23848
|
+
if(belowMenu&&pair.some(node=>node.memoizedProps&&Object.prototype.hasOwnProperty.call(node.memoizedProps,'project')))hasProject=true;
|
|
23849
|
+
const state=fiber.stateNode;
|
|
23850
|
+
if(state&&state.current){
|
|
23851
|
+
if(!pair.includes(state.current)||alternate&&alternate.stateNode!==state)return null;
|
|
23852
|
+
root=state;currentRoot=state.current;break;
|
|
23853
|
+
}
|
|
23854
|
+
}
|
|
23855
|
+
// Older pickers expose the complete path as row text without project metadata.
|
|
23856
|
+
if(!hasProject)return {path:normalize(row.innerText||row.textContent)};
|
|
23857
|
+
if(!root)return null;
|
|
23858
|
+
// A DOM expando can retain an old fiber, including a borrowed current return
|
|
23859
|
+
// chain. Prove every edge through the committed parent's child/sibling list.
|
|
23860
|
+
const currentPath=[currentRoot];const currentVisited=new Set(currentPath);
|
|
23861
|
+
let parent=currentRoot,nodeBudget=2048;
|
|
23862
|
+
for(let depth=levels.length-2;depth>=0;depth--){
|
|
23863
|
+
const candidates=[];const siblings=new Set();
|
|
23864
|
+
for(let child=parent.child;child;child=child.sibling){
|
|
23865
|
+
if(--nodeBudget<0||siblings.has(child))return null;
|
|
23866
|
+
siblings.add(child);
|
|
23867
|
+
if(levels[depth].includes(child))candidates.push(child);
|
|
23868
|
+
}
|
|
23869
|
+
if(candidates.length!==1||currentVisited.has(candidates[0]))return null;
|
|
23870
|
+
parent=candidates[0];currentVisited.add(parent);currentPath.push(parent);
|
|
23871
|
+
}
|
|
23872
|
+
if(parent.stateNode!==row)return null;
|
|
23873
|
+
const menuIndexes=currentPath.flatMap((node,index)=>node.stateNode===menus[0]?[index]:[]);
|
|
23874
|
+
if(menuIndexes.length!==1)return null;
|
|
23875
|
+
const projects=new Set();
|
|
23876
|
+
for(const fiber of currentPath.slice(menuIndexes[0]+1)){
|
|
23877
|
+
const props=fiber.memoizedProps;
|
|
23878
|
+
if(props&&Object.prototype.hasOwnProperty.call(props,'project'))projects.add(props.project);
|
|
23879
|
+
}
|
|
23880
|
+
if(!projects.size)return null;
|
|
23881
|
+
const identities=new Set();
|
|
23882
|
+
for(const project of projects){
|
|
23883
|
+
const identifier=project&&project.workspaceIdentifier;
|
|
23884
|
+
const uri=identifier&&(identifier.uri||identifier.configPath);
|
|
23885
|
+
if(!project||project.remoteAuthority||!identifier||identifier.remoteAuthority||typeof identifier.id!=='string'||!identifier.id.trim()
|
|
23886
|
+
||!uri||uri.scheme!=='file'||uri.authority||uri.remoteAuthority)return null;
|
|
23887
|
+
const paths=[uri.fsPath,uri._fsPath,uri.path].filter(value=>typeof value==='string'&&value.length).map(normalize);
|
|
23888
|
+
if(!paths.length||paths.some(path=>path!==paths[0]))return null;
|
|
23889
|
+
identities.add(JSON.stringify([identifier.id,paths[0]]));
|
|
23890
|
+
}
|
|
23891
|
+
if(identities.size!==1)return null;
|
|
23892
|
+
const [workspaceId,path]=JSON.parse([...identities][0]);
|
|
23893
|
+
return {path,workspaceId,root,currentRoot};
|
|
23894
|
+
};
|
|
23895
|
+
const matches=rows.map(row=>({row,identity:rowWorkspace(row)})).filter(match=>match.identity&&match.identity.path===wanted);
|
|
23734
23896
|
if(matches.length!==1)return fail(matches.length?'workspace_project_option_ambiguous':'workspace_project_option_unavailable',{available});
|
|
23735
|
-
matches[0]
|
|
23897
|
+
const selected=matches[0];
|
|
23898
|
+
if(selected.identity.root&&selected.identity.root.current!==selected.identity.currentRoot)return fail('workspace_project_option_unavailable',{available});
|
|
23899
|
+
selected.row.click();
|
|
23736
23900
|
await new Promise(resolve=>setTimeout(resolve,350));
|
|
23737
23901
|
return JSON.stringify({ok:true,state:'workspace_project_selection_requested',workspace:wanted,available});
|
|
23738
23902
|
})()`;
|
|
@@ -23902,7 +24066,11 @@ var REACT_ADAPTER_BODY = `
|
|
|
23902
24066
|
let globalSelectAgent=null;
|
|
23903
24067
|
let globalSelectedAgentId=null;
|
|
23904
24068
|
let sectionIdByAgentId=null;
|
|
23905
|
-
|
|
24069
|
+
const roots=new Set([
|
|
24070
|
+
...document.querySelectorAll('.glass-sidebar-agent-list-container'),
|
|
24071
|
+
...document.querySelectorAll('.ui-sidebar-section-head')
|
|
24072
|
+
]);
|
|
24073
|
+
for(const root of roots){
|
|
23906
24074
|
const nodes=[]; let n=root;
|
|
23907
24075
|
for(let i=0;n&&i<24;i++,n=n.parentElement)nodes.push(n);
|
|
23908
24076
|
for(const node of nodes){
|
|
@@ -24021,6 +24189,26 @@ var REACT_ADAPTER_BODY = `
|
|
|
24021
24189
|
};
|
|
24022
24190
|
};
|
|
24023
24191
|
const a=findAdapter();`;
|
|
24192
|
+
var EXPR_VISIBLE_COMPOSER = `(function(){
|
|
24193
|
+
${STOP_COMPOSER_BODY}
|
|
24194
|
+
const {modern,composers}=findStopComposers(null);
|
|
24195
|
+
if(composers.length!==1){
|
|
24196
|
+
return JSON.stringify({ok:false,state:composers.length?'ambiguous_composers':'composer_missing',count:composers.length});
|
|
24197
|
+
}
|
|
24198
|
+
const composer=composers[0];
|
|
24199
|
+
let status=composer.dataset.composerStatus||null;
|
|
24200
|
+
if(modern){
|
|
24201
|
+
${REACT_ADAPTER_BODY}
|
|
24202
|
+
status=modernComposerStatus(composer,a?a.entries():[]);
|
|
24203
|
+
}
|
|
24204
|
+
const composerId=modern?composer.dataset.glassAgentId:composer.dataset.composerId;
|
|
24205
|
+
return JSON.stringify({
|
|
24206
|
+
ok:true,
|
|
24207
|
+
id:'local:'+composerId,
|
|
24208
|
+
composerId,
|
|
24209
|
+
status
|
|
24210
|
+
});
|
|
24211
|
+
})()`;
|
|
24024
24212
|
var EXPR_AGENT_ADAPTER_READY = `(function(){${REACT_ADAPTER_BODY}return !!a;})()`;
|
|
24025
24213
|
var EXPR_PAGE_CAPABILITIES = `(function(){${INPUT_PICKER_BODY}
|
|
24026
24214
|
const visible=node=>!!(node&&(node.offsetParent!==null||(typeof node.getClientRects==='function'&&node.getClientRects().length>0)));
|
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.7",
|
|
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.7",
|
|
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.7"
|
|
51
51
|
}
|
|
52
52
|
}
|