pi-cursor-bridge 0.2.7 → 0.2.9
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 +255 -70
- package/dist/cursor-lifecycle-supervisor.mjs +40 -0
- 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.9 embeds Cursor Bridge 6.0.9, 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
|
@@ -3115,7 +3115,6 @@ var require_utils = __commonJS({
|
|
|
3115
3115
|
"use strict";
|
|
3116
3116
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
3117
3117
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
3118
|
-
var isPort = RegExp.prototype.test.bind(/^\d*$/u);
|
|
3119
3118
|
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
3120
3119
|
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
3121
3120
|
var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
|
|
@@ -3581,12 +3580,8 @@ var require_utils = __commonJS({
|
|
|
3581
3580
|
uriTokens.push(host);
|
|
3582
3581
|
}
|
|
3583
3582
|
if (typeof component.port === "number" || typeof component.port === "string") {
|
|
3584
|
-
const port = String(component.port);
|
|
3585
|
-
if (!isPort(port)) {
|
|
3586
|
-
throw new TypeError("URI port is malformed.");
|
|
3587
|
-
}
|
|
3588
3583
|
uriTokens.push(":");
|
|
3589
|
-
uriTokens.push(port);
|
|
3584
|
+
uriTokens.push(String(component.port));
|
|
3590
3585
|
}
|
|
3591
3586
|
return uriTokens.length ? uriTokens.join("") : void 0;
|
|
3592
3587
|
}
|
|
@@ -4029,15 +4024,12 @@ var require_fast_uri = __commonJS({
|
|
|
4029
4024
|
}
|
|
4030
4025
|
return false;
|
|
4031
4026
|
}
|
|
4032
|
-
function isIPLiteral(host) {
|
|
4033
|
-
return host[0] === "[" && host[host.length - 1] === "]";
|
|
4034
|
-
}
|
|
4035
4027
|
function hasMalformedComponentPercentEncoding(matches) {
|
|
4036
4028
|
const host = matches[4];
|
|
4037
|
-
return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !
|
|
4029
|
+
return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !(host[0] === "[" && host[host.length - 1] === "]") && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
|
|
4038
4030
|
}
|
|
4039
4031
|
function canonicalizeHost(parsed, options, schemeHandler, isIP) {
|
|
4040
|
-
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host &&
|
|
4032
|
+
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && parsed.host[0] !== "[" && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
4041
4033
|
try {
|
|
4042
4034
|
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
4043
4035
|
} catch (e) {
|
|
@@ -4124,11 +4116,10 @@ var require_fast_uri = __commonJS({
|
|
|
4124
4116
|
if (parsed.host) {
|
|
4125
4117
|
const ipv4result = isIPv4(parsed.host);
|
|
4126
4118
|
if (ipv4result === false) {
|
|
4127
|
-
const bracketedIPLiteral =
|
|
4128
|
-
const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
|
|
4119
|
+
const bracketedIPLiteral = parsed.host[0] === "[" && parsed.host[parsed.host.length - 1] === "]";
|
|
4129
4120
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
4130
4121
|
isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
|
|
4131
|
-
malformedIPLiteral =
|
|
4122
|
+
malformedIPLiteral = bracketedIPLiteral && ipv6result.error === true;
|
|
4132
4123
|
parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
|
|
4133
4124
|
if (malformedIPLiteral) {
|
|
4134
4125
|
parsed.error = parsed.error || "URI host is malformed.";
|
|
@@ -4151,17 +4142,14 @@ var require_fast_uri = __commonJS({
|
|
|
4151
4142
|
parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
|
|
4152
4143
|
}
|
|
4153
4144
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
4154
|
-
|
|
4155
|
-
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
4156
|
-
}
|
|
4157
|
-
if (uri.indexOf("%") !== -1 && parsed.host !== void 0 && !malformedIPLiteral) {
|
|
4158
|
-
let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
4159
|
-
if (!isIP) {
|
|
4160
|
-
host = normalizePercentEncoding(host.toLowerCase());
|
|
4161
|
-
}
|
|
4162
|
-
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
4163
|
-
}
|
|
4145
|
+
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
4164
4146
|
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
4147
|
+
if (uri.indexOf("%") !== -1) {
|
|
4148
|
+
if (parsed.host !== void 0 && !malformedIPLiteral) {
|
|
4149
|
+
const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
4150
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
4151
|
+
}
|
|
4152
|
+
}
|
|
4165
4153
|
if (parsed.path) {
|
|
4166
4154
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
4167
4155
|
}
|
|
@@ -11402,6 +11390,36 @@ import { mkdirSync as mkdirSync6, readFileSync as readFileSync5, renameSync as r
|
|
|
11402
11390
|
import { createHash as createHash2 } from "node:crypto";
|
|
11403
11391
|
import { homedir as homedir6 } from "node:os";
|
|
11404
11392
|
import { dirname as dirname5, join as join6, resolve as resolve5 } from "node:path";
|
|
11393
|
+
import * as startupModule from "node:module";
|
|
11394
|
+
function readCursorStartupPreference(options = {}) {
|
|
11395
|
+
let database;
|
|
11396
|
+
try {
|
|
11397
|
+
const { DatabaseSync } = (options.requireImpl || requireOptional)("node:sqlite");
|
|
11398
|
+
const file = join6(dirname5(options.file || cursorWindowStatePath(options)), "state.vscdb");
|
|
11399
|
+
database = new DatabaseSync(file, { readOnly: true });
|
|
11400
|
+
const rows = database.prepare("SELECT key, value FROM ItemTable WHERE key IN (?, ?)").all(STARTUP_PREFERENCE_KEY, LEGACY_STARTUP_PREFERENCE_KEY);
|
|
11401
|
+
const values = new Map(rows.map(({ key, value }) => {
|
|
11402
|
+
try {
|
|
11403
|
+
return [key, JSON.parse(value)];
|
|
11404
|
+
} catch {
|
|
11405
|
+
return [key, value];
|
|
11406
|
+
}
|
|
11407
|
+
}));
|
|
11408
|
+
const preference = values.get(STARTUP_PREFERENCE_KEY);
|
|
11409
|
+
if (["default", "agentWindow", "lastUsedWindows"].includes(preference)) return preference;
|
|
11410
|
+
const legacy = values.get(LEGACY_STARTUP_PREFERENCE_KEY);
|
|
11411
|
+
if (legacy === true || legacy === "true" || legacy === "agentWindow") return "agentWindow";
|
|
11412
|
+
if (legacy === false || legacy === "false" || legacy === "lastUsedWindows") return "lastUsedWindows";
|
|
11413
|
+
return "default";
|
|
11414
|
+
} catch {
|
|
11415
|
+
return null;
|
|
11416
|
+
} finally {
|
|
11417
|
+
try {
|
|
11418
|
+
database?.close();
|
|
11419
|
+
} catch {
|
|
11420
|
+
}
|
|
11421
|
+
}
|
|
11422
|
+
}
|
|
11405
11423
|
function cursorWindowStatePath(options = {}) {
|
|
11406
11424
|
const env = options.env || process.env;
|
|
11407
11425
|
const home = options.home || homedir6();
|
|
@@ -11431,6 +11449,12 @@ function stateSignature(last) {
|
|
|
11431
11449
|
return createHash2("sha256").update(JSON.stringify(last)).digest("hex");
|
|
11432
11450
|
}
|
|
11433
11451
|
function readCursorStartupWindow(options = {}) {
|
|
11452
|
+
let preference = null;
|
|
11453
|
+
try {
|
|
11454
|
+
preference = (options.readStartupPreferenceImpl || readCursorStartupPreference)(options);
|
|
11455
|
+
} catch {
|
|
11456
|
+
}
|
|
11457
|
+
if (preference === "agentWindow") return { uiFlavor: "agents_v2", source: "cursor-startup-preference" };
|
|
11434
11458
|
const file = options.file || cursorWindowStatePath(options);
|
|
11435
11459
|
const last = nativeWindowState(options);
|
|
11436
11460
|
try {
|
|
@@ -11449,8 +11473,12 @@ function cursorStartupWindowArgs(startupWindow, projectPath) {
|
|
|
11449
11473
|
if (startupWindow.uiFlavor !== "legacy") return ["--glass"];
|
|
11450
11474
|
return ["--classic", ...projectPath ? [projectPath] : ["--new-window"]];
|
|
11451
11475
|
}
|
|
11476
|
+
var requireOptional, STARTUP_PREFERENCE_KEY, LEGACY_STARTUP_PREFERENCE_KEY;
|
|
11452
11477
|
var init_cursor_startup_window = __esm({
|
|
11453
11478
|
"cursor-startup-window.mjs"() {
|
|
11479
|
+
requireOptional = startupModule.createRequire(import.meta.url);
|
|
11480
|
+
STARTUP_PREFERENCE_KEY = "cursor/userWindowRestorationPreference";
|
|
11481
|
+
LEGACY_STARTUP_PREFERENCE_KEY = "cursor/userOpenAgentsWindowOnStartupPreference";
|
|
11454
11482
|
}
|
|
11455
11483
|
});
|
|
11456
11484
|
|
|
@@ -22990,7 +23018,7 @@ function updateCursorSessionRegistry(filePath, mutator, options = {}) {
|
|
|
22990
23018
|
// server.mjs
|
|
22991
23019
|
init_cursor_ensure_core();
|
|
22992
23020
|
init_lifecycle_paths();
|
|
22993
|
-
var PLUGIN_VERSION = "6.0.
|
|
23021
|
+
var PLUGIN_VERSION = "6.0.9";
|
|
22994
23022
|
var CDP_PORT2 = Number(process.env.CURSOR_BRIDGE_CDP_PORT || 9223);
|
|
22995
23023
|
var ORIGIN = `http://localhost:${CDP_PORT2}`;
|
|
22996
23024
|
var QUERY_TIMEOUT = Number(process.env.CURSOR_BRIDGE_TIMEOUT || 3e5);
|
|
@@ -23481,21 +23509,54 @@ function exprClickBoundComposerStop(agentId) {
|
|
|
23481
23509
|
}
|
|
23482
23510
|
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)});})()`;
|
|
23483
23511
|
var MODEL_PICKER_VISIBLE_BODY = `
|
|
23512
|
+
${INPUT_PICKER_BODY}
|
|
23484
23513
|
const visible=(node)=>!!(node&&(node.offsetParent!==null||(node.getClientRects&&node.getClientRects().length>0)));
|
|
23485
|
-
const
|
|
23486
|
-
const
|
|
23514
|
+
const inputs=inputCandidates();
|
|
23515
|
+
const ownerSelector='.composer-bar[data-composer-id],.composer-bar,.ui-prompt-input-root,.agent-prompt-input-root,.ui-prompt-input';
|
|
23516
|
+
const composer=inputs.length===1?inputs[0].closest(ownerSelector):null;
|
|
23517
|
+
const triggerSelector='.ui-model-picker__trigger,.vscode-model-picker__trigger';
|
|
23518
|
+
const candidates=composer?[...composer.querySelectorAll(triggerSelector)]
|
|
23519
|
+
.filter(node=>visible(node)&&node.closest(ownerSelector)===composer):[];
|
|
23520
|
+
const trigger=candidates.length===1?candidates[0]:null;
|
|
23521
|
+
const shell=inputs.length===1?inputs[0].closest('[data-agent-panel-conversation-shell][data-glass-agent-id]'):null;
|
|
23522
|
+
const owner=trigger?{triggerId:trigger.getAttribute('id'),composerId:composer.getAttribute('data-composer-id'),agentId:shell&&shell.getAttribute('data-glass-agent-id')}:null;
|
|
23487
23523
|
`;
|
|
23488
23524
|
var EXPR_MODEL_PICKER_TRIGGER = `(function(){
|
|
23489
23525
|
${MODEL_PICKER_VISIBLE_BODY}
|
|
23490
|
-
|
|
23491
|
-
const candidates=[...composer.querySelectorAll(triggerSelector)].filter(visible);
|
|
23492
|
-
const trigger=candidates[candidates.length-1]||[...document.querySelectorAll(triggerSelector)].filter(visible).pop();
|
|
23493
|
-
if(!trigger)return JSON.stringify({found:false,state:'trigger_missing'});
|
|
23526
|
+
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});
|
|
23494
23527
|
const rect=trigger.getBoundingClientRect();
|
|
23495
23528
|
const text=String(trigger.querySelector('.ui-model-picker__trigger-text,.vscode-model-picker__trigger-text')?.innerText||trigger.innerText||'').replace(/\\s+/g,' ').trim();
|
|
23496
23529
|
const detail=String(trigger.querySelector('.ui-model-picker__trigger-variant-suffix,.vscode-model-picker__trigger-variant-suffix')?.innerText||'').replace(/\\s+/g,' ').trim();
|
|
23497
|
-
|
|
23530
|
+
const x=Math.round(rect.x+rect.width/2),y=Math.round(rect.y+rect.height/2);
|
|
23531
|
+
let state='ready',occluder=null;
|
|
23532
|
+
if(trigger.disabled||trigger.getAttribute('aria-disabled')==='true'||trigger.closest('[inert]')||getComputedStyle(trigger).pointerEvents==='none')state='trigger_disabled';
|
|
23533
|
+
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';
|
|
23534
|
+
else {
|
|
23535
|
+
const hit=document.elementFromPoint(x,y);
|
|
23536
|
+
if(!hit||hit!==trigger&&!trigger.contains(hit)){
|
|
23537
|
+
state='trigger_occluded';
|
|
23538
|
+
const menu=hit&&hit.closest('[data-component="menu-popup"]');
|
|
23539
|
+
// A transient Cursor menu can consume/block a click on the composer.
|
|
23540
|
+
// Never dismiss dialogs, arbitrary overlays, or offscreen controls.
|
|
23541
|
+
if(menu&&!hit.closest('[role="dialog"],[aria-modal="true"]'))occluder={kind:'menu',id:menu.getAttribute('id')||null};
|
|
23542
|
+
}
|
|
23543
|
+
}
|
|
23544
|
+
return JSON.stringify({found:true,state,interactive:state==='ready',expanded:trigger.getAttribute('aria-expanded'),occluder,text,detail,x,y,...owner});
|
|
23498
23545
|
})()`;
|
|
23546
|
+
function exprActivateClosedModelPicker(expected) {
|
|
23547
|
+
return `(function(){
|
|
23548
|
+
const expected=${JSON.stringify(expected)};
|
|
23549
|
+
const current=JSON.parse(${EXPR_MODEL_PICKER_TRIGGER});
|
|
23550
|
+
if(!current.found||current.interactive!==true||current.expanded!=='false')return JSON.stringify({clicked:false,state:'trigger_not_closed_and_interactive'});
|
|
23551
|
+
if(!current.triggerId||['triggerId','composerId','agentId','x','y'].some(key=>(current[key]??null)!==(expected[key]??null)))return JSON.stringify({clicked:false,state:'trigger_changed'});
|
|
23552
|
+
${MODEL_PICKER_VISIBLE_BODY}
|
|
23553
|
+
if(!trigger||trigger.getAttribute('id')!==current.triggerId)return JSON.stringify({clicked:false,state:'trigger_changed'});
|
|
23554
|
+
// Use the same button's normal click handler after a native click failed
|
|
23555
|
+
// to expand it. The closed-state and hit checks occur in this same turn.
|
|
23556
|
+
trigger.click();
|
|
23557
|
+
return JSON.stringify({clicked:true,state:'closed_trigger_activated',owner});
|
|
23558
|
+
})()`;
|
|
23559
|
+
}
|
|
23499
23560
|
function classifyModelPickerRowKind(text, hasItemName, menuTestId, submenuTestId, ariaHaspopup, hasParamCheck, inSubmenu) {
|
|
23500
23561
|
const menu = String(menuTestId || "").toLowerCase();
|
|
23501
23562
|
const submenu = String(submenuTestId || "").toLowerCase();
|
|
@@ -23512,7 +23573,32 @@ function classifyModelPickerRowKind(text, hasItemName, menuTestId, submenuTestId
|
|
|
23512
23573
|
var EXPR_MODEL_PICKER_ROWS = `(function(){
|
|
23513
23574
|
${MODEL_PICKER_VISIBLE_BODY}
|
|
23514
23575
|
${classifyModelPickerRowKind.toString()}
|
|
23515
|
-
const
|
|
23576
|
+
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);
|
|
23577
|
+
const menus=[];
|
|
23578
|
+
if(trigger){
|
|
23579
|
+
// Modern menus are portalled. Follow the exact trigger's accessibility
|
|
23580
|
+
// links, including submenu triggers, instead of adopting another picker.
|
|
23581
|
+
const ids=new Set(),controls=new Set();
|
|
23582
|
+
const link=node=>{
|
|
23583
|
+
const id=node.getAttribute('id');if(id)ids.add(id);
|
|
23584
|
+
for(const id of String(node.getAttribute('aria-controls')||'').split(/\\s+/).filter(Boolean))controls.add(id);
|
|
23585
|
+
};
|
|
23586
|
+
link(trigger);
|
|
23587
|
+
for(let pass=0;pass<visibleMenus.length;pass++){
|
|
23588
|
+
let changed=false;
|
|
23589
|
+
for(const menu of visibleMenus){
|
|
23590
|
+
if(menus.includes(menu))continue;
|
|
23591
|
+
const id=menu.getAttribute('id'),labelledBy=String(menu.getAttribute('aria-labelledby')||'').split(/\\s+/).filter(Boolean);
|
|
23592
|
+
if(!(id&&controls.has(id))&&!labelledBy.some(id=>ids.has(id)))continue;
|
|
23593
|
+
menus.push(menu);link(menu);
|
|
23594
|
+
for(const node of menu.querySelectorAll('[id],[aria-controls]'))link(node);
|
|
23595
|
+
changed=true;
|
|
23596
|
+
}
|
|
23597
|
+
if(!changed)break;
|
|
23598
|
+
}
|
|
23599
|
+
if(!ids.size&&!controls.size&&visibleMenus.length===1
|
|
23600
|
+
&&[...document.querySelectorAll(triggerSelector)].filter(visible).length===1)menus.push(visibleMenus[0]);
|
|
23601
|
+
}
|
|
23516
23602
|
const rows=[];
|
|
23517
23603
|
const seen=new Set();
|
|
23518
23604
|
for(const menu of menus){
|
|
@@ -23547,8 +23633,11 @@ var EXPR_MODEL_PICKER_ROWS = `(function(){
|
|
|
23547
23633
|
});
|
|
23548
23634
|
}
|
|
23549
23635
|
}
|
|
23550
|
-
return JSON.stringify({open:menus.length>0,rows});
|
|
23636
|
+
return JSON.stringify({open:menus.length>0,rows,owner});
|
|
23551
23637
|
})()`;
|
|
23638
|
+
function modelPickerOwnerKey(owner) {
|
|
23639
|
+
return owner && JSON.stringify([owner.triggerId || null, owner.composerId || null, owner.agentId || null]);
|
|
23640
|
+
}
|
|
23552
23641
|
var EXPR_SELECTED_AGENT_MODEL_CONFIG = `(function(){
|
|
23553
23642
|
${INPUT_PICKER_BODY}
|
|
23554
23643
|
const inputs=inputCandidates();
|
|
@@ -23820,19 +23909,24 @@ function exprSelectAgentWorkspace(projectPath) {
|
|
|
23820
23909
|
const fail=(state,extra={})=>JSON.stringify({ok:false,state,wanted,...extra,
|
|
23821
23910
|
nextStep:'Select the exact local workspace '+${JSON.stringify(String(projectPath || ""))}+' in the new Agent project picker before retrying.'});
|
|
23822
23911
|
if(triggers.length!==1)return fail(triggers.length?'workspace_project_selector_ambiguous':'workspace_project_selector_unavailable',{triggerCount:triggers.length});
|
|
23823
|
-
triggers[0].click();
|
|
23912
|
+
if(triggers[0].getAttribute?.('aria-expanded')!=='true')triggers[0].click();
|
|
23824
23913
|
await new Promise(resolve=>setTimeout(resolve,350));
|
|
23825
|
-
const
|
|
23914
|
+
const readMenus=()=>[...new Set([...document.querySelectorAll('[data-component="menu-popup"],[role="menu"]')].filter(visible)
|
|
23826
23915
|
.map(menu=>menu.getAttribute('role')==='menu'&&menu.getAttribute('aria-label')==='Select a project'
|
|
23827
23916
|
?menu:menu.querySelector('[role="menu"][aria-label="Select a project"]')).filter(visible))];
|
|
23917
|
+
let menus=readMenus();
|
|
23828
23918
|
if(menus.length!==1)return fail(menus.length?'workspace_project_option_ambiguous':'workspace_project_option_unavailable',{menuCount:menus.length});
|
|
23829
|
-
const
|
|
23830
|
-
|
|
23831
|
-
for(const
|
|
23832
|
-
|
|
23919
|
+
const readRows=()=>{
|
|
23920
|
+
const rows=[];const seen=new Set();
|
|
23921
|
+
for(const menu of menus){
|
|
23922
|
+
for(const row of menu.querySelectorAll('[data-component="menu-row"][role="menuitem"],[role="option"]')){
|
|
23923
|
+
if(!visible(row)||seen.has(row))continue;seen.add(row);rows.push(row);
|
|
23924
|
+
}
|
|
23833
23925
|
}
|
|
23834
|
-
|
|
23835
|
-
|
|
23926
|
+
return rows;
|
|
23927
|
+
};
|
|
23928
|
+
let rows=readRows();
|
|
23929
|
+
let available=rows.map(row=>String(row.innerText||row.textContent||'').replace(/\s+/g,' ').trim());
|
|
23836
23930
|
const rowWorkspace=row=>{
|
|
23837
23931
|
const key=Object.keys(row).find(key=>key.startsWith('__reactFiber$'));
|
|
23838
23932
|
const levels=[];const visited=new Set();
|
|
@@ -23892,7 +23986,26 @@ function exprSelectAgentWorkspace(projectPath) {
|
|
|
23892
23986
|
const [workspaceId,path]=JSON.parse([...identities][0]);
|
|
23893
23987
|
return {path,workspaceId,root,currentRoot};
|
|
23894
23988
|
};
|
|
23895
|
-
const
|
|
23989
|
+
const findMatches=()=>rows.map(row=>({row,identity:rowWorkspace(row)})).filter(match=>match.identity&&match.identity.path===wanted);
|
|
23990
|
+
let matches=findMatches();
|
|
23991
|
+
if(!matches.length){
|
|
23992
|
+
// Cursor's Recents view omits older registered workspaces. Search the
|
|
23993
|
+
// full path, then apply the same committed local-identity checks.
|
|
23994
|
+
const searches=[...menus[0].querySelectorAll('input[aria-label="Search menu items"]')].filter(visible);
|
|
23995
|
+
if(searches.length===1&&typeof HTMLInputElement!=='undefined'){
|
|
23996
|
+
const setter=Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,'value')?.set;
|
|
23997
|
+
if(setter){
|
|
23998
|
+
setter.call(searches[0],${JSON.stringify(String(projectPath || ""))});
|
|
23999
|
+
searches[0].dispatchEvent(new Event('input',{bubbles:true}));
|
|
24000
|
+
await new Promise(resolve=>setTimeout(resolve,350));
|
|
24001
|
+
menus=readMenus();
|
|
24002
|
+
if(menus.length!==1)return fail(menus.length?'workspace_project_option_ambiguous':'workspace_project_option_unavailable',{menuCount:menus.length});
|
|
24003
|
+
rows=readRows();
|
|
24004
|
+
available=rows.map(row=>String(row.innerText||row.textContent||'').replace(/\s+/g,' ').trim());
|
|
24005
|
+
matches=findMatches();
|
|
24006
|
+
}
|
|
24007
|
+
}
|
|
24008
|
+
}
|
|
23896
24009
|
if(matches.length!==1)return fail(matches.length?'workspace_project_option_ambiguous':'workspace_project_option_unavailable',{available});
|
|
23897
24010
|
const selected=matches[0];
|
|
23898
24011
|
if(selected.identity.root&&selected.identity.root.current!==selected.identity.currentRoot)return fail('workspace_project_option_unavailable',{available});
|
|
@@ -25843,7 +25956,7 @@ var CursorBridge = class {
|
|
|
25843
25956
|
}
|
|
25844
25957
|
async _readModelPickerRows(c, options) {
|
|
25845
25958
|
const snapshot = await this._readModelPickerValue(c, EXPR_MODEL_PICKER_ROWS, "rows", options);
|
|
25846
|
-
return { open: snapshot.open === true, rows: Array.isArray(snapshot.rows) ? snapshot.rows : [] };
|
|
25959
|
+
return { open: snapshot.open === true, rows: Array.isArray(snapshot.rows) ? snapshot.rows : [], owner: snapshot.owner || null };
|
|
25847
25960
|
}
|
|
25848
25961
|
async _readSelectedAgentModelConfig(c, options) {
|
|
25849
25962
|
return this._readModelPickerValue(c, EXPR_SELECTED_AGENT_MODEL_CONFIG, "selected_agent_model_config", options);
|
|
@@ -25861,19 +25974,83 @@ var CursorBridge = class {
|
|
|
25861
25974
|
if (!point || !Number.isFinite(Number(point.x)) || !Number.isFinite(Number(point.y))) return;
|
|
25862
25975
|
await c.send("Input.dispatchMouseEvent", { type: "mouseMoved", x: Number(point.x), y: Number(point.y) });
|
|
25863
25976
|
}
|
|
25864
|
-
async
|
|
25865
|
-
|
|
25866
|
-
|
|
25867
|
-
|
|
25868
|
-
|
|
25869
|
-
|
|
25870
|
-
|
|
25871
|
-
|
|
25872
|
-
|
|
25873
|
-
|
|
25874
|
-
|
|
25875
|
-
|
|
25876
|
-
|
|
25977
|
+
async _activateClosedModelPicker(c, trigger, options) {
|
|
25978
|
+
return this._readModelPickerValue(c, exprActivateClosedModelPicker(trigger), "closed_trigger_activation", options);
|
|
25979
|
+
}
|
|
25980
|
+
async _openModelPicker(c, job = null, options = {}) {
|
|
25981
|
+
const timeoutMs = Math.max(0, Number(options.timeoutMs ?? 2e3));
|
|
25982
|
+
const pollMs = Math.max(10, Number(options.pollMs ?? 50));
|
|
25983
|
+
const stableMs = Math.max(0, Number(options.stableMs ?? 100));
|
|
25984
|
+
const recoveryDelayMs = Math.max(0, Number(options.recoveryDelayMs ?? 750));
|
|
25985
|
+
const deadline = Date.now() + timeoutMs;
|
|
25986
|
+
let trigger = null, snapshot = { open: false, rows: [] };
|
|
25987
|
+
let stableSignature = null, stableSince = 0, clicked = false, clickedOwner = null;
|
|
25988
|
+
let clickedAt = 0, recoveryAttempted = false, lastPollError = null;
|
|
25989
|
+
let dismissedMenus = 0, dismissalOwner = null;
|
|
25990
|
+
const attempts = [];
|
|
25991
|
+
do {
|
|
25992
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25993
|
+
if (deadline - Date.now() < 10) break;
|
|
25994
|
+
try {
|
|
25995
|
+
snapshot = await this._readModelPickerRows(c, { timeoutMs: deadline - Date.now() });
|
|
25996
|
+
if (deadline - Date.now() < 10) break;
|
|
25997
|
+
trigger = await this._readModelPickerTrigger(c, { timeoutMs: deadline - Date.now() });
|
|
25998
|
+
} catch (error2) {
|
|
25999
|
+
if (error2.code !== "CDP_COMMAND_TIMEOUT" || Date.now() < deadline) throw error2;
|
|
26000
|
+
lastPollError = error2.pickerRead || { code: error2.code, message: error2.message };
|
|
26001
|
+
break;
|
|
26002
|
+
}
|
|
26003
|
+
this._throwIfCancelledBeforeSend(job);
|
|
26004
|
+
const sameOwner = modelPickerOwnerKey(snapshot.owner) === modelPickerOwnerKey(trigger);
|
|
26005
|
+
if (dismissalOwner !== null && dismissalOwner !== modelPickerOwnerKey(trigger)) {
|
|
26006
|
+
attempts.push("owner_changed_after_menu_dismissal");
|
|
26007
|
+
break;
|
|
26008
|
+
}
|
|
26009
|
+
if (snapshot.open && trigger.found && sameOwner && (!clicked || clickedOwner === modelPickerOwnerKey(trigger))) return { trigger, ...snapshot };
|
|
26010
|
+
if (snapshot.open && !sameOwner && !attempts.includes("owner_changed")) attempts.push("owner_changed");
|
|
26011
|
+
if (!clicked && !snapshot.open && trigger.found && trigger.state === "trigger_occluded" && trigger.expanded === "false" && trigger.occluder?.kind === "menu" && dismissedMenus < 3) {
|
|
26012
|
+
this._throwIfCancelledBeforeSend(job);
|
|
26013
|
+
dismissalOwner = modelPickerOwnerKey(trigger);
|
|
26014
|
+
dismissedMenus++;
|
|
26015
|
+
attempts.push("dismiss_occluding_menu");
|
|
26016
|
+
await c.send("Input.dispatchKeyEvent", { type: "keyDown", key: "Escape", code: "Escape", windowsVirtualKeyCode: 27, nativeVirtualKeyCode: 27 });
|
|
26017
|
+
await c.send("Input.dispatchKeyEvent", { type: "keyUp", key: "Escape", code: "Escape", windowsVirtualKeyCode: 27, nativeVirtualKeyCode: 27 });
|
|
26018
|
+
stableSignature = null;
|
|
26019
|
+
await sleep2(Math.min(150, Math.max(0, deadline - Date.now())));
|
|
26020
|
+
continue;
|
|
26021
|
+
}
|
|
26022
|
+
if (!clicked) {
|
|
26023
|
+
const interactive = trigger.found && trigger.interactive !== false;
|
|
26024
|
+
const signature = interactive ? JSON.stringify([trigger.triggerId, trigger.composerId, trigger.agentId, trigger.x, trigger.y]) : null;
|
|
26025
|
+
if (!interactive || signature !== stableSignature) {
|
|
26026
|
+
stableSignature = signature;
|
|
26027
|
+
stableSince = Date.now();
|
|
26028
|
+
const state = trigger.state || (interactive ? "ready" : "trigger_missing");
|
|
26029
|
+
if (!attempts.includes(state)) attempts.push(state);
|
|
26030
|
+
}
|
|
26031
|
+
if (interactive && Date.now() - stableSince >= stableMs) {
|
|
26032
|
+
this._throwIfCancelledBeforeSend(job);
|
|
26033
|
+
await this._clickModelPickerPoint(c, trigger);
|
|
26034
|
+
clicked = true;
|
|
26035
|
+
clickedAt = Date.now();
|
|
26036
|
+
clickedOwner = modelPickerOwnerKey(trigger);
|
|
26037
|
+
attempts.push("click_once", "wait_menu");
|
|
26038
|
+
}
|
|
26039
|
+
} else if (!recoveryAttempted && !snapshot.open && sameOwner && clickedOwner === modelPickerOwnerKey(trigger) && trigger.interactive === true && trigger.expanded === "false" && Date.now() - clickedAt >= recoveryDelayMs && deadline - Date.now() >= 10) {
|
|
26040
|
+
this._throwIfCancelledBeforeSend(job);
|
|
26041
|
+
recoveryAttempted = true;
|
|
26042
|
+
const recovered = await this._activateClosedModelPicker(c, trigger, { timeoutMs: deadline - Date.now() });
|
|
26043
|
+
attempts.push(recovered.clicked ? "activate_confirmed_closed_trigger" : recovered.state || "activation_rejected");
|
|
26044
|
+
}
|
|
26045
|
+
if (Date.now() >= deadline) break;
|
|
26046
|
+
await sleep2(Math.min(pollMs, Math.max(0, deadline - Date.now())));
|
|
26047
|
+
} while (Date.now() < deadline);
|
|
26048
|
+
throw createModelSelectionError("Cursor model picker did not open", "picker_did_not_open", true, {
|
|
26049
|
+
attempts,
|
|
26050
|
+
trigger,
|
|
26051
|
+
lastPollError,
|
|
26052
|
+
menu: { open: snapshot.open, rows: (snapshot.rows || []).slice(0, 20) }
|
|
26053
|
+
});
|
|
25877
26054
|
}
|
|
25878
26055
|
async _closeModelPicker(c) {
|
|
25879
26056
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
@@ -25885,24 +26062,29 @@ var CursorBridge = class {
|
|
|
25885
26062
|
}
|
|
25886
26063
|
if ((await this._readModelPickerRows(c)).open) throw new Error("Cursor model picker did not close after selection");
|
|
25887
26064
|
}
|
|
25888
|
-
async _openModelPickerControl(c, snapshot, controlKind) {
|
|
26065
|
+
async _openModelPickerControl(c, snapshot, controlKind, job = null) {
|
|
26066
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25889
26067
|
const control = (snapshot && snapshot.rows || []).find((row) => row.kind === controlKind && row.disabled !== true);
|
|
25890
26068
|
if (!control) return snapshot;
|
|
26069
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25891
26070
|
await this._clickModelPickerPoint(c, control);
|
|
25892
26071
|
await sleep2(400);
|
|
25893
26072
|
let next = await this._readModelPickerRows(c);
|
|
25894
26073
|
const expectedKind = controlKind === "model_control" ? "model" : "parameter";
|
|
25895
26074
|
if (!next.rows.some((row) => row.kind === expectedKind)) {
|
|
26075
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25896
26076
|
await this._hoverModelPickerPoint(c, control);
|
|
25897
26077
|
await sleep2(350);
|
|
25898
26078
|
next = await this._readModelPickerRows(c);
|
|
25899
26079
|
}
|
|
25900
26080
|
return next;
|
|
25901
26081
|
}
|
|
25902
|
-
async _findModelPickerModel(c, snapshot, requestedModel) {
|
|
26082
|
+
async _findModelPickerModel(c, snapshot, requestedModel, job = null) {
|
|
26083
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25903
26084
|
let modelRow = selectModelPickerRow(snapshot && snapshot.rows, requestedModel, "model");
|
|
25904
26085
|
if (modelRow) return { snapshot, modelRow };
|
|
25905
|
-
const expanded = await this._openModelPickerControl(c, snapshot, "model_control");
|
|
26086
|
+
const expanded = await this._openModelPickerControl(c, snapshot, "model_control", job);
|
|
26087
|
+
this._throwIfCancelledBeforeSend(job);
|
|
25906
26088
|
modelRow = selectModelPickerRow(expanded && expanded.rows, requestedModel, "model");
|
|
25907
26089
|
return { snapshot: expanded, modelRow };
|
|
25908
26090
|
}
|
|
@@ -26047,9 +26229,9 @@ var CursorBridge = class {
|
|
|
26047
26229
|
if (job) job.modelSelection = result2;
|
|
26048
26230
|
return result2;
|
|
26049
26231
|
}
|
|
26050
|
-
const opened = await this._openModelPicker(c);
|
|
26232
|
+
const opened = await this._openModelPicker(c, job);
|
|
26051
26233
|
stage = "locate_model";
|
|
26052
|
-
let located = await this._findModelPickerModel(c, opened, requestedModel);
|
|
26234
|
+
let located = await this._findModelPickerModel(c, opened, requestedModel, job);
|
|
26053
26235
|
modelRow = located.modelRow;
|
|
26054
26236
|
if (!modelRow) {
|
|
26055
26237
|
throw createModelSelectionError(
|
|
@@ -26065,8 +26247,8 @@ var CursorBridge = class {
|
|
|
26065
26247
|
if (!outcome.row && outcome.state === "not_rendered" && !effortPickerReopened) {
|
|
26066
26248
|
effortPickerReopened = true;
|
|
26067
26249
|
await this._closeModelPicker(c);
|
|
26068
|
-
const reopened = await this._openModelPicker(c);
|
|
26069
|
-
located = await this._findModelPickerModel(c, reopened, requestedModel);
|
|
26250
|
+
const reopened = await this._openModelPicker(c, job);
|
|
26251
|
+
located = await this._findModelPickerModel(c, reopened, requestedModel, job);
|
|
26070
26252
|
modelRow = located.modelRow;
|
|
26071
26253
|
if (!modelRow) {
|
|
26072
26254
|
throw createModelSelectionError(
|
|
@@ -26109,8 +26291,8 @@ var CursorBridge = class {
|
|
|
26109
26291
|
this._throwIfCancelledBeforeSend(job);
|
|
26110
26292
|
await this._clickModelPickerPoint(c, modelRow);
|
|
26111
26293
|
await sleep2(550);
|
|
26112
|
-
const reopened = await this._openModelPicker(c);
|
|
26113
|
-
located = await this._findModelPickerModel(c, reopened, requestedModel);
|
|
26294
|
+
const reopened = await this._openModelPicker(c, job);
|
|
26295
|
+
located = await this._findModelPickerModel(c, reopened, requestedModel, job);
|
|
26114
26296
|
modelRow = located.modelRow;
|
|
26115
26297
|
if (!modelRow) {
|
|
26116
26298
|
throw createModelSelectionError(
|
|
@@ -26137,8 +26319,8 @@ var CursorBridge = class {
|
|
|
26137
26319
|
stage = "verify_model";
|
|
26138
26320
|
let trigger2 = await this._readModelPickerTrigger(c);
|
|
26139
26321
|
if (!trigger2.found || !normalizeModelPickerModelText(trigger2.text).includes(normalizeModelPickerModelText(requestedModel))) {
|
|
26140
|
-
const reopened = await this._openModelPicker(c);
|
|
26141
|
-
located = await this._findModelPickerModel(c, reopened, requestedModel);
|
|
26322
|
+
const reopened = await this._openModelPicker(c, job);
|
|
26323
|
+
located = await this._findModelPickerModel(c, reopened, requestedModel, job);
|
|
26142
26324
|
const selected = selectModelPickerRow(located.snapshot.rows.filter((row) => row.selected), requestedModel, "model");
|
|
26143
26325
|
if (!selected) {
|
|
26144
26326
|
throw createModelSelectionError(
|
|
@@ -26151,8 +26333,8 @@ var CursorBridge = class {
|
|
|
26151
26333
|
}
|
|
26152
26334
|
if (requestedEffort) {
|
|
26153
26335
|
stage = "verify_effort";
|
|
26154
|
-
const reopened = await this._openModelPicker(c);
|
|
26155
|
-
located = await this._findModelPickerModel(c, reopened, requestedModel);
|
|
26336
|
+
const reopened = await this._openModelPicker(c, job);
|
|
26337
|
+
located = await this._findModelPickerModel(c, reopened, requestedModel, job);
|
|
26156
26338
|
modelRow = located.modelRow;
|
|
26157
26339
|
if (!modelRow) {
|
|
26158
26340
|
throw createModelSelectionError(
|
|
@@ -26207,6 +26389,8 @@ var CursorBridge = class {
|
|
|
26207
26389
|
errorCode: primaryError.code || `CURSOR_MODEL_${String(failure.failureClass).toUpperCase()}`,
|
|
26208
26390
|
available: failure.available || [],
|
|
26209
26391
|
attempts: failure.attempts || [],
|
|
26392
|
+
trigger: failure.trigger || null,
|
|
26393
|
+
lastPollError: failure.lastPollError || null,
|
|
26210
26394
|
menu: failure.menu || null,
|
|
26211
26395
|
runtimeMode: this.runtimeMode,
|
|
26212
26396
|
lastError: primaryError.message,
|
|
@@ -28294,6 +28478,7 @@ export {
|
|
|
28294
28478
|
createChatPanelUnavailableError,
|
|
28295
28479
|
createProviderError,
|
|
28296
28480
|
cursorStartupBehavior,
|
|
28481
|
+
exprActivateClosedModelPicker,
|
|
28297
28482
|
exprClickBoundComposerStop,
|
|
28298
28483
|
exprClickSelectedAgentStop,
|
|
28299
28484
|
exprCreateAgentForWorkspace,
|
|
@@ -3713,6 +3713,36 @@ import { mkdirSync, readFileSync, renameSync, writeFileSync, rmSync } from "node
|
|
|
3713
3713
|
import { createHash } from "node:crypto";
|
|
3714
3714
|
import { homedir } from "node:os";
|
|
3715
3715
|
import { dirname, join, resolve } from "node:path";
|
|
3716
|
+
import * as startupModule from "node:module";
|
|
3717
|
+
function readCursorStartupPreference(options = {}) {
|
|
3718
|
+
let database;
|
|
3719
|
+
try {
|
|
3720
|
+
const { DatabaseSync } = (options.requireImpl || requireOptional)("node:sqlite");
|
|
3721
|
+
const file = join(dirname(options.file || cursorWindowStatePath(options)), "state.vscdb");
|
|
3722
|
+
database = new DatabaseSync(file, { readOnly: true });
|
|
3723
|
+
const rows = database.prepare("SELECT key, value FROM ItemTable WHERE key IN (?, ?)").all(STARTUP_PREFERENCE_KEY, LEGACY_STARTUP_PREFERENCE_KEY);
|
|
3724
|
+
const values = new Map(rows.map(({ key, value }) => {
|
|
3725
|
+
try {
|
|
3726
|
+
return [key, JSON.parse(value)];
|
|
3727
|
+
} catch {
|
|
3728
|
+
return [key, value];
|
|
3729
|
+
}
|
|
3730
|
+
}));
|
|
3731
|
+
const preference = values.get(STARTUP_PREFERENCE_KEY);
|
|
3732
|
+
if (["default", "agentWindow", "lastUsedWindows"].includes(preference)) return preference;
|
|
3733
|
+
const legacy = values.get(LEGACY_STARTUP_PREFERENCE_KEY);
|
|
3734
|
+
if (legacy === true || legacy === "true" || legacy === "agentWindow") return "agentWindow";
|
|
3735
|
+
if (legacy === false || legacy === "false" || legacy === "lastUsedWindows") return "lastUsedWindows";
|
|
3736
|
+
return "default";
|
|
3737
|
+
} catch {
|
|
3738
|
+
return null;
|
|
3739
|
+
} finally {
|
|
3740
|
+
try {
|
|
3741
|
+
database?.close();
|
|
3742
|
+
} catch {
|
|
3743
|
+
}
|
|
3744
|
+
}
|
|
3745
|
+
}
|
|
3716
3746
|
function cursorWindowStatePath(options = {}) {
|
|
3717
3747
|
const env = options.env || process.env;
|
|
3718
3748
|
const home = options.home || homedir();
|
|
@@ -3742,6 +3772,12 @@ function stateSignature(last) {
|
|
|
3742
3772
|
return createHash("sha256").update(JSON.stringify(last)).digest("hex");
|
|
3743
3773
|
}
|
|
3744
3774
|
function readCursorStartupWindow(options = {}) {
|
|
3775
|
+
let preference = null;
|
|
3776
|
+
try {
|
|
3777
|
+
preference = (options.readStartupPreferenceImpl || readCursorStartupPreference)(options);
|
|
3778
|
+
} catch {
|
|
3779
|
+
}
|
|
3780
|
+
if (preference === "agentWindow") return { uiFlavor: "agents_v2", source: "cursor-startup-preference" };
|
|
3745
3781
|
const file = options.file || cursorWindowStatePath(options);
|
|
3746
3782
|
const last = nativeWindowState(options);
|
|
3747
3783
|
try {
|
|
@@ -3779,8 +3815,12 @@ function cursorStartupWindowArgs(startupWindow, projectPath) {
|
|
|
3779
3815
|
if (startupWindow.uiFlavor !== "legacy") return ["--glass"];
|
|
3780
3816
|
return ["--classic", ...projectPath ? [projectPath] : ["--new-window"]];
|
|
3781
3817
|
}
|
|
3818
|
+
var requireOptional, STARTUP_PREFERENCE_KEY, LEGACY_STARTUP_PREFERENCE_KEY;
|
|
3782
3819
|
var init_cursor_startup_window = __esm({
|
|
3783
3820
|
"cursor-startup-window.mjs"() {
|
|
3821
|
+
requireOptional = startupModule.createRequire(import.meta.url);
|
|
3822
|
+
STARTUP_PREFERENCE_KEY = "cursor/userWindowRestorationPreference";
|
|
3823
|
+
LEGACY_STARTUP_PREFERENCE_KEY = "cursor/userOpenAgentsWindowOnStartupPreference";
|
|
3784
3824
|
}
|
|
3785
3825
|
});
|
|
3786
3826
|
|
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.9",
|
|
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.9",
|
|
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.9"
|
|
51
51
|
}
|
|
52
52
|
}
|