pi-cursor-bridge 0.1.10 → 0.1.11
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 +4 -2
- package/dist/cursor-bridge.mjs +138 -60
- package/extensions/index.ts +1 -1
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cursor-bridge",
|
|
3
|
-
"version": "5.8.
|
|
3
|
+
"version": "5.8.1+codex.20260903121439",
|
|
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
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Use Cursor's project index and Agent search from Pi, with compact `path:line` evidence and optional bounded Cursor task execution.
|
|
4
4
|
|
|
5
|
+
⭐ If Cursor Bridge helps you, please consider giving it a [Star on GitHub](https://github.com/Vanyangyang/cursor-bridge)—it helps others discover the project.
|
|
6
|
+
|
|
5
7
|
```powershell
|
|
6
8
|
pi install npm:pi-cursor-bridge
|
|
7
9
|
```
|
|
8
10
|
|
|
9
11
|
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.
|
|
10
12
|
|
|
11
|
-
This Pi package embeds Cursor Bridge 5.8.
|
|
13
|
+
This Pi package embeds Cursor Bridge 5.8.1. Cursor must be installed and signed in. Current end-to-end compatibility claims remain scoped to the environments documented in the main repository.
|
|
12
14
|
|
|
13
|
-
Full documentation: [English](https://github.com/Vanyangyang/cursor-bridge#readme) · [简体中文](https://github.com/Vanyangyang/cursor-bridge/blob/
|
|
15
|
+
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
|
@@ -22604,7 +22604,7 @@ function updateCursorSessionRegistry(filePath, mutator, options = {}) {
|
|
|
22604
22604
|
// server.mjs
|
|
22605
22605
|
init_cursor_ensure_core();
|
|
22606
22606
|
init_lifecycle_paths();
|
|
22607
|
-
var PLUGIN_VERSION = "5.8.
|
|
22607
|
+
var PLUGIN_VERSION = "5.8.1";
|
|
22608
22608
|
var CDP_PORT2 = Number(process.env.CURSOR_BRIDGE_CDP_PORT || 9223);
|
|
22609
22609
|
var ORIGIN = `http://localhost:${CDP_PORT2}`;
|
|
22610
22610
|
var QUERY_TIMEOUT = Number(process.env.CURSOR_BRIDGE_TIMEOUT || 3e5);
|
|
@@ -22744,11 +22744,6 @@ function summarizeCdpPages(list) {
|
|
|
22744
22744
|
page: first && first.url ? String(first.url).slice(0, 60) : ""
|
|
22745
22745
|
};
|
|
22746
22746
|
}
|
|
22747
|
-
function isBlankAgentsWindow(page) {
|
|
22748
|
-
if (!page || !isAgentsWindowTitle(page.title)) return false;
|
|
22749
|
-
if (page.probeError || !page.capabilities) return true;
|
|
22750
|
-
return page.capabilities.uiFlavor !== "agents_v2" && !page.capabilities.hasWritableInput;
|
|
22751
|
-
}
|
|
22752
22747
|
var NORMAL_AGENTS_PRESENTATION_REFRESH_MS = 5 * 60 * 1e3;
|
|
22753
22748
|
function shouldRecoverNormalAgentsPresentation({
|
|
22754
22749
|
runtimeMode,
|
|
@@ -22769,25 +22764,6 @@ function shouldRecoverNormalAgentsPresentation({
|
|
|
22769
22764
|
if (!Number.isFinite(previousAt)) return true;
|
|
22770
22765
|
return Number(now) - previousAt >= Math.max(0, Number(refreshMs) || 0);
|
|
22771
22766
|
}
|
|
22772
|
-
async function reloadPageTarget(page, timeoutMs = 5e3) {
|
|
22773
|
-
if (!page || !page.webSocketDebuggerUrl) return false;
|
|
22774
|
-
const c = makeClient(page.webSocketDebuggerUrl);
|
|
22775
|
-
try {
|
|
22776
|
-
await Promise.race([
|
|
22777
|
-
c.ready,
|
|
22778
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("Timed out connecting to the CDP target")), timeoutMs))
|
|
22779
|
-
]);
|
|
22780
|
-
await Promise.race([
|
|
22781
|
-
c.send("Page.reload", { ignoreCache: true }),
|
|
22782
|
-
new Promise((_, reject) => setTimeout(() => reject(new Error("Timed out reloading the CDP target")), timeoutMs))
|
|
22783
|
-
]);
|
|
22784
|
-
return true;
|
|
22785
|
-
} catch {
|
|
22786
|
-
return false;
|
|
22787
|
-
} finally {
|
|
22788
|
-
c.close();
|
|
22789
|
-
}
|
|
22790
|
-
}
|
|
22791
22767
|
async function inspectPageTarget(page) {
|
|
22792
22768
|
const c = makeClient(page.webSocketDebuggerUrl);
|
|
22793
22769
|
const probeMs = Number(process.env.CURSOR_BRIDGE_PAGE_PROBE_TIMEOUT || 5e3);
|
|
@@ -22807,24 +22783,6 @@ async function inspectPageTarget(page) {
|
|
|
22807
22783
|
c.close();
|
|
22808
22784
|
}
|
|
22809
22785
|
}
|
|
22810
|
-
async function recoverBlankAgentsWindows(inspected) {
|
|
22811
|
-
const pages = Array.isArray(inspected) ? inspected : [];
|
|
22812
|
-
const recovered = [];
|
|
22813
|
-
for (const page of pages) {
|
|
22814
|
-
if (!isBlankAgentsWindow(page)) {
|
|
22815
|
-
recovered.push(page);
|
|
22816
|
-
continue;
|
|
22817
|
-
}
|
|
22818
|
-
const reloaded = await reloadPageTarget(page);
|
|
22819
|
-
if (!reloaded) {
|
|
22820
|
-
recovered.push(page);
|
|
22821
|
-
continue;
|
|
22822
|
-
}
|
|
22823
|
-
await sleep2(800);
|
|
22824
|
-
recovered.push(await inspectPageTarget(page));
|
|
22825
|
-
}
|
|
22826
|
-
return recovered;
|
|
22827
|
-
}
|
|
22828
22786
|
function pagesWithFlavor(pages, flavor) {
|
|
22829
22787
|
return (Array.isArray(pages) ? pages : []).filter((page) => page && page.capabilities && page.capabilities.uiFlavor === flavor);
|
|
22830
22788
|
}
|
|
@@ -22855,7 +22813,7 @@ async function findPage(options = {}) {
|
|
|
22855
22813
|
if (options.targetId && options.preferAgentsV2 !== true && options.preferLegacy !== true) {
|
|
22856
22814
|
return selectCursorPageCandidate(pages, options);
|
|
22857
22815
|
}
|
|
22858
|
-
const inspected = await
|
|
22816
|
+
const inspected = await Promise.all(pages.map(inspectPageTarget));
|
|
22859
22817
|
return selectPageForUiPreference(inspected, options) || pages[0];
|
|
22860
22818
|
}
|
|
22861
22819
|
function makeClient(wsUrl) {
|
|
@@ -22941,6 +22899,70 @@ var INPUT_PICKER_BODY = `
|
|
|
22941
22899
|
.filter(e=>e.offsetParent!==null&&!e.disabled&&e.getAttribute('aria-disabled')!=='true'&&e.getAttribute('contenteditable')!=='false')
|
|
22942
22900
|
.sort((a,b)=>(b.classList&&b.classList.contains('ui-prompt-input-editor__input')?1:0)-(a.classList&&a.classList.contains('ui-prompt-input-editor__input')?1:0))[0]||null;`;
|
|
22943
22901
|
var EXPR_VISIBLE = `(function(){${INPUT_PICKER_BODY}return !!pickInput();})()`;
|
|
22902
|
+
var CHAT_PANEL_NEXT_STEP = "Complete or close the current Customize/Settings dialog, open Cursor's main Agent/Chat panel or New Chat, then retry the same request.";
|
|
22903
|
+
function classifyChatPanelDiagnostic(snapshot = {}) {
|
|
22904
|
+
const evidence = {
|
|
22905
|
+
writableInputVisible: snapshot.writableInputVisible === true || snapshot.hasWritableInput === true,
|
|
22906
|
+
inputCandidateCount: Number.isFinite(Number(snapshot.inputCandidateCount)) ? Number(snapshot.inputCandidateCount) : 0,
|
|
22907
|
+
settingsOrCustomizeVisible: snapshot.settingsOrCustomizeVisible === true,
|
|
22908
|
+
modalVisible: snapshot.modalVisible === true,
|
|
22909
|
+
modalLabel: snapshot.modalLabel ? String(snapshot.modalLabel) : null,
|
|
22910
|
+
signInControlVisible: snapshot.signInControlVisible === true,
|
|
22911
|
+
signInVisible: snapshot.signInVisible === true,
|
|
22912
|
+
agentSurfaceVisible: snapshot.agentSurfaceVisible === true,
|
|
22913
|
+
composerCount: Number.isFinite(Number(snapshot.composerCount)) ? Number(snapshot.composerCount) : 0,
|
|
22914
|
+
visibilityState: String(snapshot.visibilityState || "unknown"),
|
|
22915
|
+
focused: typeof snapshot.focused === "boolean" ? snapshot.focused : null,
|
|
22916
|
+
pageTitle: snapshot.pageTitle ? String(snapshot.pageTitle) : null,
|
|
22917
|
+
probeError: snapshot.probeError ? String(snapshot.probeError) : null,
|
|
22918
|
+
inputStateChanged: snapshot.inputStateChanged === true
|
|
22919
|
+
};
|
|
22920
|
+
let state = "composer_input_unavailable";
|
|
22921
|
+
let needsAction = "open_new_chat";
|
|
22922
|
+
let message = "Cursor shows an Agent/Chat surface, but no writable input was detected.";
|
|
22923
|
+
if (evidence.signInVisible) {
|
|
22924
|
+
state = "sign_in_required";
|
|
22925
|
+
needsAction = "sign_in_to_cursor";
|
|
22926
|
+
message = "Cursor is showing a sign-in surface instead of a writable Agent/Chat input.";
|
|
22927
|
+
} else if (evidence.settingsOrCustomizeVisible) {
|
|
22928
|
+
state = "settings_or_customize_open";
|
|
22929
|
+
needsAction = "complete_or_close_configuration";
|
|
22930
|
+
message = "Cursor is showing Customize/Settings instead of a writable Agent/Chat input.";
|
|
22931
|
+
} else if (evidence.modalVisible) {
|
|
22932
|
+
state = "modal_dialog_open";
|
|
22933
|
+
needsAction = "complete_or_close_dialog";
|
|
22934
|
+
message = "A visible Cursor dialog is blocking access to the Agent/Chat input.";
|
|
22935
|
+
} else if (evidence.probeError || ["hidden", "prerender", "unloaded"].includes(evidence.visibilityState)) {
|
|
22936
|
+
state = "cursor_window_unavailable";
|
|
22937
|
+
needsAction = "make_cursor_window_available";
|
|
22938
|
+
message = "The selected Cursor page is unavailable or not visible.";
|
|
22939
|
+
} else if (evidence.inputStateChanged) {
|
|
22940
|
+
state = "input_state_changed";
|
|
22941
|
+
needsAction = "open_new_chat";
|
|
22942
|
+
message = "Cursor's Agent/Chat input changed while the request was being prepared.";
|
|
22943
|
+
} else if (!evidence.agentSurfaceVisible && evidence.composerCount === 0) {
|
|
22944
|
+
state = "agent_chat_panel_not_open";
|
|
22945
|
+
needsAction = "open_agent_chat_panel";
|
|
22946
|
+
message = "Cursor's main Agent/Chat panel is not open.";
|
|
22947
|
+
}
|
|
22948
|
+
return {
|
|
22949
|
+
schemaVersion: 1,
|
|
22950
|
+
code: "CURSOR_CHAT_PANEL_UNAVAILABLE",
|
|
22951
|
+
state,
|
|
22952
|
+
message,
|
|
22953
|
+
needsAction,
|
|
22954
|
+
nextStep: CHAT_PANEL_NEXT_STEP,
|
|
22955
|
+
retryable: true,
|
|
22956
|
+
evidence
|
|
22957
|
+
};
|
|
22958
|
+
}
|
|
22959
|
+
function createChatPanelUnavailableError(snapshot) {
|
|
22960
|
+
const uiDiagnostic = classifyChatPanelDiagnostic(snapshot);
|
|
22961
|
+
const error2 = new Error(`${uiDiagnostic.code}: ${uiDiagnostic.message} ${uiDiagnostic.nextStep}`);
|
|
22962
|
+
error2.code = uiDiagnostic.code;
|
|
22963
|
+
error2.uiDiagnostic = uiDiagnostic;
|
|
22964
|
+
return error2;
|
|
22965
|
+
}
|
|
22944
22966
|
function exprFill(text) {
|
|
22945
22967
|
const js = JSON.stringify(text);
|
|
22946
22968
|
return `(function(){${INPUT_PICKER_BODY}const inp=pickInput();if(!inp)return 'NO_INPUT';inp.focus();try{const s=getSelection();const r=document.createRange();r.selectNodeContents(inp);s.removeAllRanges();s.addRange(r);}catch(e){}const ok=document.execCommand('insertText',false,${js});try{inp.dispatchEvent(new InputEvent('input',{bubbles:true,inputType:'insertText',data:${js}}));}catch(e){inp.dispatchEvent(new Event('input',{bubbles:true}));}return ok?(inp.innerText||'').slice(0,30):'EXEC_FAIL';})()`;
|
|
@@ -23398,17 +23420,44 @@ var REACT_ADAPTER_BODY = `
|
|
|
23398
23420
|
const a=findAdapter();`;
|
|
23399
23421
|
var EXPR_AGENT_ADAPTER_READY = `(function(){${REACT_ADAPTER_BODY}return !!a;})()`;
|
|
23400
23422
|
var EXPR_PAGE_CAPABILITIES = `(function(){${INPUT_PICKER_BODY}
|
|
23423
|
+
const visible=node=>!!(node&&(node.offsetParent!==null||(typeof node.getClientRects==='function'&&node.getClientRects().length>0)));
|
|
23424
|
+
const label=node=>String(node&&(node.getAttribute&&(
|
|
23425
|
+
node.getAttribute('aria-label')||node.getAttribute('title'))||node.innerText||node.textContent)||'').replace(/\\s+/g,' ').trim();
|
|
23401
23426
|
const input=pickInput();
|
|
23427
|
+
const inputCandidateCount=[...document.querySelectorAll(${JSON.stringify(CURSOR_INPUT_SELECTOR)})].filter(visible).length;
|
|
23402
23428
|
const hasV2Sidebar=!!document.querySelector('.glass-sidebar-agent-list-container');
|
|
23403
23429
|
const hasLegacyInput=!!document.querySelector('.aislash-editor-input');
|
|
23404
23430
|
const hasLegacyHistory=!!document.querySelector('.compact-agent-history-react-menu-label')||
|
|
23405
23431
|
[...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')||'')));
|
|
23432
|
+
const dialogs=[...document.querySelectorAll('[role="dialog"],dialog[open],.monaco-dialog-box,.quick-input-widget')].filter(visible);
|
|
23433
|
+
const dialog=dialogs[dialogs.length-1]||null;
|
|
23434
|
+
const dialogHeading=dialog&&dialog.querySelector('h1,h2,h3,[role="heading"]');
|
|
23435
|
+
const dialogLabel=dialog?String(dialog.getAttribute('aria-label')||dialog.getAttribute('title')||label(dialogHeading)||'').slice(0,120):null;
|
|
23436
|
+
const pageTitle=String(document.title||'').replace(/\\s+/g,' ').trim();
|
|
23437
|
+
const pagePath=String(globalThis.location&&globalThis.location.pathname||'');
|
|
23438
|
+
const headings=[...document.querySelectorAll('h1,h2,h3,[role="heading"]')]
|
|
23439
|
+
.filter(node=>visible(node)&&!node.closest('.markdown-root,.composer-messages-container,.composer-react-transcript-root,.aichat-container'))
|
|
23440
|
+
.map(label).filter(Boolean).slice(0,40);
|
|
23441
|
+
const configurationText=[pageTitle,pagePath,...headings,label(dialogHeading)].join(' ');
|
|
23442
|
+
const configurationSelector='.ui-customize-view,.settings-editor,.settings-body,.preferences-editor,[class*="settings-editor"],[class*="preferences-editor"],[data-testid*="customize"]';
|
|
23443
|
+
const settingsOrCustomizeVisible=[...document.querySelectorAll(configurationSelector)].some(visible)||/(?:settings?|customize|preferences|\u8BBE\u7F6E|\u8A2D\u5B9A|\u81EA\u5B9A\u4E49|\u81EA\u8A02)/i.test(configurationText);
|
|
23444
|
+
const authControls=[...document.querySelectorAll('button,a,[role="button"],[role="link"]')]
|
|
23445
|
+
.filter(node=>visible(node)&&!node.closest('.markdown-root,.composer-messages-container,.composer-react-transcript-root'));
|
|
23446
|
+
const signInPattern=/(?:sign|log)\\s*in(?:\\s+to\\s+cursor)?|authenticate(?:\\s+cursor)?|continue with (?:google|github|email|sso)|\u767B\u5F55|\u767B\u5165/i;
|
|
23447
|
+
const signInControlVisible=authControls.some(node=>signInPattern.test(label(node)));
|
|
23448
|
+
const signInVisible=authControls.some(node=>signInPattern.test(label(node))&&!node.closest(configurationSelector));
|
|
23449
|
+
const composerCount=[...document.querySelectorAll('.composer-bar[data-composer-id],.composer-bar,.ui-prompt-input-root')].filter(visible).length;
|
|
23450
|
+
const agentSurfaceVisible=composerCount>0||[...document.querySelectorAll('.glass-sidebar-agent-list-container,.compact-agent-history-react-menu-label,.aichat-container')].some(visible)||authControls.some(node=>/(?:New (?:Agent|Chat)|(?:Chat|Agent) History)/i.test(label(node)));
|
|
23406
23451
|
const uiFlavor=hasV2Sidebar||(input&&input.classList&&input.classList.contains('ui-prompt-input-editor__input'))?'agents_v2':hasLegacyInput?'legacy':'unknown';
|
|
23407
23452
|
return JSON.stringify({
|
|
23408
|
-
hasWritableInput:!!input,uiFlavor,
|
|
23453
|
+
hasWritableInput:!!input,inputCandidateCount,uiFlavor,
|
|
23409
23454
|
agentAdapterKind:hasV2Sidebar?'agents_v2':hasLegacyHistory?'legacy':'none',
|
|
23410
23455
|
hasComposer:!!document.querySelector('.composer-bar[data-composer-id]'),
|
|
23411
|
-
|
|
23456
|
+
modalVisible:!!dialog,modalLabel:dialogLabel,
|
|
23457
|
+
settingsOrCustomizeVisible,signInControlVisible,signInVisible,agentSurfaceVisible,composerCount,
|
|
23458
|
+
visibilityState:String(document.visibilityState||'unknown'),
|
|
23459
|
+
visible:document.visibilityState==='visible',focused:typeof document.hasFocus==='function'&&document.hasFocus(),
|
|
23460
|
+
documentTitle:pageTitle,pageTitle:pageTitle.slice(0,160)
|
|
23412
23461
|
});
|
|
23413
23462
|
})()`;
|
|
23414
23463
|
var EXPR_HISTORY_ENTRIES = `(function(){${REACT_ADAPTER_BODY}
|
|
@@ -23826,6 +23875,7 @@ var CursorBridge = class {
|
|
|
23826
23875
|
status: outcome,
|
|
23827
23876
|
finishedAt: job.finishedAt || now,
|
|
23828
23877
|
error: job.error || null,
|
|
23878
|
+
uiDiagnostic: job.uiDiagnostic || null,
|
|
23829
23879
|
terminalEvidence: job.terminalEvidence || null,
|
|
23830
23880
|
resultUnavailable: job.resultUnavailable === true
|
|
23831
23881
|
};
|
|
@@ -24426,6 +24476,7 @@ var CursorBridge = class {
|
|
|
24426
24476
|
resultUnavailable: false,
|
|
24427
24477
|
terminalEvidence: null,
|
|
24428
24478
|
providerError: null,
|
|
24479
|
+
uiDiagnostic: null,
|
|
24429
24480
|
sendState: "not_sent",
|
|
24430
24481
|
reservationScope: null,
|
|
24431
24482
|
controlTail: Promise.resolve(),
|
|
@@ -24460,6 +24511,7 @@ var CursorBridge = class {
|
|
|
24460
24511
|
const e = error2 instanceof Error ? error2 : new Error(String(error2));
|
|
24461
24512
|
job.error = e.message;
|
|
24462
24513
|
if (e.providerError) job.providerError = e.providerError;
|
|
24514
|
+
if (e.uiDiagnostic) job.uiDiagnostic = e.uiDiagnostic;
|
|
24463
24515
|
if (e.terminalEvidence) job.terminalEvidence = e.terminalEvidence;
|
|
24464
24516
|
job.status = "failed";
|
|
24465
24517
|
job.phase = "failed";
|
|
@@ -24770,6 +24822,7 @@ var CursorBridge = class {
|
|
|
24770
24822
|
await this._applyModelPreference(c, options.modelPreference, options);
|
|
24771
24823
|
this._throwIfCancelledBeforeSend(options);
|
|
24772
24824
|
const filled = await evalJS(c, exprFill(prompt));
|
|
24825
|
+
if (filled === "NO_INPUT") await this._throwChatPanelUnavailableAfterNoInput(c);
|
|
24773
24826
|
if (filled === "NO_INPUT" || filled === "EXEC_FAIL") throw new Error("Failed to enter the query because the input state was invalid");
|
|
24774
24827
|
await sleep2(450);
|
|
24775
24828
|
this._throwIfCancelledBeforeSend(options);
|
|
@@ -24985,19 +25038,24 @@ var CursorBridge = class {
|
|
|
24985
25038
|
if (job) job.modelSelection = result;
|
|
24986
25039
|
return result;
|
|
24987
25040
|
}
|
|
24988
|
-
async
|
|
24989
|
-
|
|
24990
|
-
|
|
24991
|
-
|
|
24992
|
-
|
|
24993
|
-
vis = await evalJS(c, EXPR_VISIBLE);
|
|
24994
|
-
}
|
|
24995
|
-
if (!vis) {
|
|
24996
|
-
await chord(c, 2, "I", "KeyI", 73);
|
|
24997
|
-
await sleep2(1300);
|
|
24998
|
-
vis = await evalJS(c, EXPR_VISIBLE);
|
|
25041
|
+
async _readChatPanelDiagnostic(c) {
|
|
25042
|
+
try {
|
|
25043
|
+
return JSON.parse(await evalJS(c, EXPR_PAGE_CAPABILITIES) || "{}");
|
|
25044
|
+
} catch (error2) {
|
|
25045
|
+
return { probeError: error2 instanceof Error ? error2.message : String(error2) };
|
|
24999
25046
|
}
|
|
25000
|
-
|
|
25047
|
+
}
|
|
25048
|
+
async _ensureChatPanel(c) {
|
|
25049
|
+
const snapshot = await this._readChatPanelDiagnostic(c);
|
|
25050
|
+
if (snapshot.modalVisible !== true && snapshot.hasWritableInput === true) return snapshot;
|
|
25051
|
+
throw createChatPanelUnavailableError(snapshot);
|
|
25052
|
+
}
|
|
25053
|
+
async _throwChatPanelUnavailableAfterNoInput(c) {
|
|
25054
|
+
const snapshot = await this._readChatPanelDiagnostic(c);
|
|
25055
|
+
throw createChatPanelUnavailableError({
|
|
25056
|
+
...snapshot,
|
|
25057
|
+
inputStateChanged: snapshot.hasWritableInput === true
|
|
25058
|
+
});
|
|
25001
25059
|
}
|
|
25002
25060
|
// 清空对话上下文:定位 "New Agent" 钮后【Alt+click】——Alt 修饰使其执行 Replace Agent(清空旧对话),
|
|
25003
25061
|
// 而非新建(aria 标注 "New Agent (Ctrl+N) / [Alt] Replace Agent")。2026-06-08 实测回复区 markdown DOM 清空
|
|
@@ -25235,6 +25293,7 @@ var CursorBridge = class {
|
|
|
25235
25293
|
await this._applyModelPreference(c, job.modelPreference, job);
|
|
25236
25294
|
this._throwIfCancelledBeforeSend(job);
|
|
25237
25295
|
const filled = await evalJS(c, exprFill(job.prompt));
|
|
25296
|
+
if (filled === "NO_INPUT") await this._throwChatPanelUnavailableAfterNoInput(c);
|
|
25238
25297
|
if (filled === "NO_INPUT" || filled === "EXEC_FAIL") throw new Error("Failed to enter the parallel_agent task");
|
|
25239
25298
|
await sleep2(350);
|
|
25240
25299
|
this._throwIfCancelledBeforeSend(job);
|
|
@@ -25354,6 +25413,7 @@ var CursorBridge = class {
|
|
|
25354
25413
|
job.responseBaseline = await this._captureSessionResponseBaseline(c);
|
|
25355
25414
|
const providerErrorBaseline = providerErrorSignature(await this._readProviderError(c));
|
|
25356
25415
|
const filled = await evalJS(c, exprFill(job.prompt));
|
|
25416
|
+
if (filled === "NO_INPUT") await this._throwChatPanelUnavailableAfterNoInput(c);
|
|
25357
25417
|
if (filled === "NO_INPUT" || filled === "EXEC_FAIL") {
|
|
25358
25418
|
throw cursorSessionError("SESSION_INPUT_FAILED", "failed to enter the continued task");
|
|
25359
25419
|
}
|
|
@@ -26197,6 +26257,7 @@ var CursorBridge = class {
|
|
|
26197
26257
|
resultUnavailable: job.resultUnavailable,
|
|
26198
26258
|
terminalEvidence: job.terminalEvidence,
|
|
26199
26259
|
providerError: job.providerError,
|
|
26260
|
+
uiDiagnostic: job.uiDiagnostic,
|
|
26200
26261
|
sendState: job.sendState,
|
|
26201
26262
|
reservationScope: job.reservationScope,
|
|
26202
26263
|
reservationHeld: this.activeParallel.has(job.id),
|
|
@@ -26412,6 +26473,21 @@ async function ensureBridgeCursor(targetBridge, reason) {
|
|
|
26412
26473
|
}
|
|
26413
26474
|
return r;
|
|
26414
26475
|
}
|
|
26476
|
+
function toolErrorResult(error2) {
|
|
26477
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
26478
|
+
if (error2 && error2.uiDiagnostic) {
|
|
26479
|
+
const payload = {
|
|
26480
|
+
error: { code: error2.code || error2.uiDiagnostic.code || "CURSOR_BRIDGE_ERROR", message },
|
|
26481
|
+
uiDiagnostic: error2.uiDiagnostic
|
|
26482
|
+
};
|
|
26483
|
+
return {
|
|
26484
|
+
content: [{ type: "text", text: JSON.stringify(payload, null, 2) }],
|
|
26485
|
+
structuredContent: payload,
|
|
26486
|
+
isError: true
|
|
26487
|
+
};
|
|
26488
|
+
}
|
|
26489
|
+
return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
|
|
26490
|
+
}
|
|
26415
26491
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
26416
26492
|
tools: buildToolDefinitions(bridge)
|
|
26417
26493
|
}));
|
|
@@ -26513,7 +26589,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request2) => {
|
|
|
26513
26589
|
}
|
|
26514
26590
|
throw new Error(`Unknown tool: ${name}`);
|
|
26515
26591
|
} catch (error2) {
|
|
26516
|
-
return
|
|
26592
|
+
return toolErrorResult(error2);
|
|
26517
26593
|
}
|
|
26518
26594
|
});
|
|
26519
26595
|
async function main() {
|
|
@@ -26560,7 +26636,9 @@ export {
|
|
|
26560
26636
|
bridge,
|
|
26561
26637
|
buildContextEnginePrompt,
|
|
26562
26638
|
buildToolDefinitions,
|
|
26639
|
+
classifyChatPanelDiagnostic,
|
|
26563
26640
|
classifyParallelTerminalIcon,
|
|
26641
|
+
createChatPanelUnavailableError,
|
|
26564
26642
|
createProviderError,
|
|
26565
26643
|
cursorStartupBehavior,
|
|
26566
26644
|
exprClickBoundComposerStop,
|
|
@@ -26569,7 +26647,6 @@ export {
|
|
|
26569
26647
|
exprFill,
|
|
26570
26648
|
exprInspectWorkspaceRepository,
|
|
26571
26649
|
exprOpenAgent,
|
|
26572
|
-
isBlankAgentsWindow,
|
|
26573
26650
|
isConfirmedCompletedReply,
|
|
26574
26651
|
isDurablyRegisteredParallelEntry,
|
|
26575
26652
|
isSessionTurnReplyReady,
|
|
@@ -26597,6 +26674,7 @@ export {
|
|
|
26597
26674
|
shouldRecoverNormalAgentsPresentation,
|
|
26598
26675
|
shouldScheduleParallelOriginRestore,
|
|
26599
26676
|
summarizeCdpPages,
|
|
26677
|
+
toolErrorResult,
|
|
26600
26678
|
uncertainSubmissionReservationScope,
|
|
26601
26679
|
updateStableEntryObservation
|
|
26602
26680
|
};
|
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.1.
|
|
13
|
+
packageVersion: "0.1.11",
|
|
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.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "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": "5.8.
|
|
50
|
+
"embeddedProductVersion": "5.8.1"
|
|
51
51
|
}
|
|
52
52
|
}
|