pi-cursor-sdk 0.5.3 → 0.5.4
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/CHANGELOG.md +40 -1
- package/README.md +62 -816
- package/dist/context.js +11 -5
- package/dist/cursor-agents-context.js +6 -6
- package/dist/cursor-api-key.js +1 -1
- package/dist/cursor-bridge-contract.js +1 -13
- package/dist/cursor-cloud-local-state.js +0 -1
- package/dist/cursor-config.js +1 -17
- package/dist/cursor-fallback-models.generated.js +264 -1
- package/dist/cursor-live-run-coordinator.js +1 -0
- package/dist/cursor-mcp-timeout-override.js +6 -17
- package/dist/cursor-native-tool-display-replay.js +5 -5
- package/dist/cursor-native-tools.js +11 -0
- package/dist/cursor-pi-tool-bridge-env.js +25 -2
- package/dist/cursor-pi-tool-bridge-server.js +98 -48
- package/dist/cursor-pi-tool-bridge-snapshot.js +1 -1
- package/dist/cursor-pi-tool-bridge.js +4 -12
- package/dist/cursor-provider-errors.js +0 -6
- package/dist/cursor-provider-live-run-drain.js +8 -3
- package/dist/cursor-provider-overflow.js +7 -21
- package/dist/cursor-provider-turn-prepare.js +8 -1
- package/dist/cursor-provider-turn-runner.js +17 -6
- package/dist/cursor-provider.js +1 -4
- package/dist/cursor-runtime-state.js +3 -3
- package/dist/cursor-sdk-event-debug.js +2 -2
- package/dist/cursor-sdk-output-filter.js +1 -1
- package/dist/cursor-sdk-process-error-guard.js +1 -2
- package/dist/cursor-session-agent.js +6 -8
- package/dist/cursor-session-scope.js +1 -7
- package/dist/cursor-session-store.js +1 -1
- package/dist/cursor-state.js +9 -23
- package/dist/cursor-tool-lifecycle.js +0 -3
- package/dist/cursor-tool-manifest.js +3 -1
- package/dist/cursor-tool-presentation-registry.js +2 -4
- package/dist/cursor-tool-visibility.js +0 -3
- package/dist/cursor-transcript-tool-specs.js +1 -2
- package/dist/index.js +21 -0
- package/dist/model-discovery.js +0 -1
- package/dist/model-list-cache.js +4 -9
- package/docs/cursor-live-smoke-checklist.md +3 -3
- package/docs/cursor-model-ux-spec.md +16 -8
- package/docs/cursor-native-tool-replay.md +2 -2
- package/docs/cursor-native-tool-visual-audit.md +1 -1
- package/docs/cursor-testing-lessons.md +15 -3
- package/docs/cursor-tool-surfaces.md +32 -3
- package/docs/development.md +93 -0
- package/docs/platform-smoke-implementation.md +3 -2
- package/docs/reference.md +806 -0
- package/package.json +6 -4
- package/scripts/platform-smoke/artifact-secrets.mjs +13 -4
- package/scripts/platform-smoke/local-resume-runner.mjs +0 -1
- package/scripts/platform-smoke/target-runtime.mjs +4 -2
- package/scripts/platform-smoke/targets.mjs +0 -1
- package/shared/cursor-sdk-output-filter.d.mts +2 -0
- package/shared/cursor-sdk-output-filter.mjs +92 -28
- package/shared/cursor-sensitive-text.d.mts +1 -0
- package/shared/cursor-sensitive-text.mjs +7 -0
- package/src/context.ts +16 -9
- package/src/cursor-agents-context.ts +6 -6
- package/src/cursor-api-key.ts +1 -1
- package/src/cursor-bridge-contract.ts +1 -15
- package/src/cursor-cloud-local-state.ts +0 -2
- package/src/cursor-config.ts +1 -24
- package/src/cursor-fallback-models.generated.ts +264 -1
- package/src/cursor-live-run-coordinator.ts +5 -0
- package/src/cursor-mcp-timeout-override.ts +6 -30
- package/src/cursor-native-tool-display-replay.ts +4 -6
- package/src/cursor-native-tools.ts +14 -0
- package/src/cursor-pi-tool-bridge-env.ts +31 -2
- package/src/cursor-pi-tool-bridge-server.ts +89 -45
- package/src/cursor-pi-tool-bridge-snapshot.ts +0 -1
- package/src/cursor-pi-tool-bridge.ts +2 -18
- package/src/cursor-provider-errors.ts +0 -8
- package/src/cursor-provider-live-run-drain.ts +8 -2
- package/src/cursor-provider-overflow.ts +6 -24
- package/src/cursor-provider-turn-prepare.ts +10 -1
- package/src/cursor-provider-turn-runner.ts +17 -6
- package/src/cursor-provider.ts +0 -5
- package/src/cursor-runtime-state.ts +3 -3
- package/src/cursor-sdk-event-debug.ts +2 -2
- package/src/cursor-sdk-output-filter.ts +2 -1
- package/src/cursor-sdk-process-error-guard.ts +1 -3
- package/src/cursor-session-agent.ts +8 -8
- package/src/cursor-session-scope.ts +1 -9
- package/src/cursor-session-store.ts +1 -1
- package/src/cursor-state.ts +9 -36
- package/src/cursor-tool-lifecycle.ts +0 -4
- package/src/cursor-tool-manifest.ts +4 -1
- package/src/cursor-tool-presentation-registry.ts +3 -5
- package/src/cursor-tool-visibility.ts +0 -4
- package/src/cursor-transcript-tool-specs.ts +0 -3
- package/src/index.ts +18 -0
- package/src/model-discovery.ts +0 -1
- package/src/model-list-cache.ts +4 -10
package/dist/context.js
CHANGED
|
@@ -11,7 +11,9 @@ export function getCursorPlanModeToolGuidanceText(agentMode, options = {}) {
|
|
|
11
11
|
return undefined;
|
|
12
12
|
return [
|
|
13
13
|
"Cursor SDK mode is plan for this run. In pi-cursor-sdk, plan mode may still use available Cursor SDK/MCP tools for inspection when needed.",
|
|
14
|
-
|
|
14
|
+
options.nativeToolsEnabled === false
|
|
15
|
+
? "Only MCP tools exposed in this run are callable; native Shell and task/subagents are disabled."
|
|
16
|
+
: "Safe/read-only shell commands that inspect or print information are allowed when Cursor chooses to call Shell; do not say Shell is blocked by plan mode and then call it anyway.",
|
|
15
17
|
options.includePiBridgeGuidance === false
|
|
16
18
|
? undefined
|
|
17
19
|
: "Exposed pi__* bridge tools are also callable in plan mode when the user asks for them or they are needed to answer.",
|
|
@@ -19,14 +21,16 @@ export function getCursorPlanModeToolGuidanceText(agentMode, options = {}) {
|
|
|
19
21
|
}
|
|
20
22
|
export function getCursorToolTailGuardText(options = {}) {
|
|
21
23
|
return [
|
|
22
|
-
"Shell: use explicit `cd` to repo path for project commands; session cwd may differ from tool args.",
|
|
24
|
+
options.nativeToolsEnabled === false ? undefined : "Shell: use explicit `cd` to repo path for project commands; session cwd may differ from tool args.",
|
|
23
25
|
options.includePlanModeGuidance === false
|
|
24
26
|
? undefined
|
|
25
|
-
: getCursorPlanModeToolGuidanceText(options.agentMode, { includePiBridgeGuidance: options.includePiBridgeGuidance }),
|
|
27
|
+
: getCursorPlanModeToolGuidanceText(options.agentMode, { includePiBridgeGuidance: options.includePiBridgeGuidance, nativeToolsEnabled: options.nativeToolsEnabled }),
|
|
26
28
|
"Exact-output requests: output exactly the requested text; no preamble or checks unless asked.",
|
|
27
29
|
"Tools: call available Cursor SDK/MCP tools; never print tool cards as assistant text.",
|
|
28
30
|
"Do not comment on GitHub issues or PRs unless the user asked.",
|
|
29
|
-
options.includePiBridgeGuidance === false ? undefined :
|
|
31
|
+
options.includePiBridgeGuidance === false ? undefined : options.nativeToolsEnabled === false
|
|
32
|
+
? "Use only exposed pi__* MCP names for Pi work; native task/subagents are disabled."
|
|
33
|
+
: CURSOR_PI_BRIDGE_PREFERENCE_TEXT,
|
|
30
34
|
].filter((line) => line !== undefined).join("\n");
|
|
31
35
|
}
|
|
32
36
|
function getCursorToolBoundaryText(options = {}) {
|
|
@@ -35,12 +39,13 @@ function getCursorToolBoundaryText(options = {}) {
|
|
|
35
39
|
const lines = [
|
|
36
40
|
"Cursor SDK tool boundary:",
|
|
37
41
|
"Call only Cursor SDK/MCP tools exposed in this run; pi history names, replay labels, and transcript names are not callable.",
|
|
42
|
+
options.nativeToolsEnabled === false ? "Cursor native tools (including task/subagents): disabled. Only exposed MCP tools are callable." : undefined,
|
|
38
43
|
includePiBridgeGuidance
|
|
39
44
|
? "For exposed pi bridge tools, call pi__* MCP names, not pi card/history names."
|
|
40
45
|
: undefined,
|
|
41
46
|
"Do not claim pi-side or WebSearch/WebFetch tools unless Cursor ran an equivalent tool.",
|
|
42
47
|
includePiAskQuestionGuidance ? "Use pi__cursor_ask_question only if the user asked to be prompted." : undefined,
|
|
43
|
-
getCursorPlanModeToolGuidanceText(options.agentMode, { includePiBridgeGuidance }),
|
|
48
|
+
getCursorPlanModeToolGuidanceText(options.agentMode, { includePiBridgeGuidance, nativeToolsEnabled: options.nativeToolsEnabled }),
|
|
44
49
|
"Images: only latest user images are sent; ask to reattach prior images.",
|
|
45
50
|
].filter((line) => line !== undefined);
|
|
46
51
|
if (options.hasToolManifest) {
|
|
@@ -354,6 +359,7 @@ export function buildCursorPrompt(context, options = {}) {
|
|
|
354
359
|
agentMode: options.agentMode,
|
|
355
360
|
hasToolManifest: Boolean(options.toolManifest),
|
|
356
361
|
includePiBridgeGuidance: options.includePiBridgeGuidance,
|
|
362
|
+
nativeToolsEnabled: options.nativeToolsEnabled,
|
|
357
363
|
includePiAskQuestionGuidance: options.includePiAskQuestionGuidance,
|
|
358
364
|
})];
|
|
359
365
|
if (options.toolManifest) {
|
|
@@ -17,7 +17,7 @@ function normalizeDirPath(dirPath) {
|
|
|
17
17
|
}
|
|
18
18
|
/** Pi context filenames that can overlap Cursor project/user ambient rules. */
|
|
19
19
|
const CURSOR_OVERLAPPING_CONTEXT_BASE_NAMES = new Set(["agents.md", "claude.md"]);
|
|
20
|
-
|
|
20
|
+
function getAgentsContextFileBaseName(filePath) {
|
|
21
21
|
const normalized = normalizeContextPath(filePath);
|
|
22
22
|
return normalized.slice(normalized.lastIndexOf("/") + 1).toLowerCase();
|
|
23
23
|
}
|
|
@@ -27,11 +27,11 @@ function isPiAgentDirContextFilePath(filePath, fileName, agentDir = getAgentDir(
|
|
|
27
27
|
return normalized.toLowerCase() === expectedPath.toLowerCase();
|
|
28
28
|
}
|
|
29
29
|
/** Actual pi agent dir `AGENTS.md` — overlaps Cursor `user` setting source (global agent instructions). */
|
|
30
|
-
|
|
30
|
+
function isPiAgentDirAgentsMdPath(filePath, agentDir = getAgentDir()) {
|
|
31
31
|
return isPiAgentDirContextFilePath(filePath, "agents.md", agentDir);
|
|
32
32
|
}
|
|
33
33
|
/** Actual pi agent dir `CLAUDE.md` — kept because Cursor user rules use `~/.claude/CLAUDE.md`. */
|
|
34
|
-
|
|
34
|
+
function isPiAgentDirClaudeMdPath(filePath, agentDir = getAgentDir()) {
|
|
35
35
|
return isPiAgentDirContextFilePath(filePath, "claude.md", agentDir);
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
@@ -40,7 +40,7 @@ export function isPiAgentDirClaudeMdPath(filePath, agentDir = getAgentDir()) {
|
|
|
40
40
|
* Only the actual pi agent dir `AGENTS.md` overlaps Cursor `user`; agent-dir `CLAUDE.md` is kept
|
|
41
41
|
* because Cursor user rules use `~/.claude/CLAUDE.md`, not pi's agent dir path.
|
|
42
42
|
*/
|
|
43
|
-
|
|
43
|
+
function classifyContextFileOverlap(filePath, agentDir = getAgentDir()) {
|
|
44
44
|
const base = getAgentsContextFileBaseName(filePath);
|
|
45
45
|
if (!CURSOR_OVERLAPPING_CONTEXT_BASE_NAMES.has(base))
|
|
46
46
|
return "none";
|
|
@@ -50,7 +50,7 @@ export function classifyContextFileOverlap(filePath, agentDir = getAgentDir()) {
|
|
|
50
50
|
return "none";
|
|
51
51
|
return "cursor-project-rules";
|
|
52
52
|
}
|
|
53
|
-
|
|
53
|
+
function shouldRemovePiAgentsContextFile(file, settingSources, agentDir) {
|
|
54
54
|
switch (classifyContextFileOverlap(file.path, agentDir)) {
|
|
55
55
|
case "cursor-user-agents":
|
|
56
56
|
return cursorSettingSourcesIncludes(settingSources, "user");
|
|
@@ -60,7 +60,7 @@ export function shouldRemovePiAgentsContextFile(file, settingSources, agentDir)
|
|
|
60
60
|
return false;
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
function shouldSuppressPiAgentsContext(model, contextFiles, settingSources, agentDir) {
|
|
64
64
|
if (!isCursorModel(model))
|
|
65
65
|
return false;
|
|
66
66
|
if (parseEnvBoolean(process.env[CURSOR_PRESERVE_PI_AGENTS_MD_ENV], false))
|
package/dist/cursor-api-key.js
CHANGED
|
@@ -2,7 +2,7 @@ import { envApiKeyAuth } from "@earendil-works/pi-ai";
|
|
|
2
2
|
import { parseEnvBoolean } from "./cursor-env-boolean.js";
|
|
3
3
|
export const CURSOR_API_KEY_ENV_VAR = "CURSOR_API_KEY";
|
|
4
4
|
// Legacy no-auth availability policy only; never a configured models.json key.
|
|
5
|
-
|
|
5
|
+
const CURSOR_API_KEY_CONFIG_VALUE = "pi-cursor-sdk-cursor-api-key-placeholder";
|
|
6
6
|
const CURSOR_API_KEY_PLACEHOLDERS = new Set([
|
|
7
7
|
CURSOR_API_KEY_ENV_VAR,
|
|
8
8
|
`$${CURSOR_API_KEY_ENV_VAR}`,
|
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
export const CURSOR_PI_BRIDGE_MCP_TOOL_PREFIX = "pi__";
|
|
2
|
-
export const CURSOR_PI_BRIDGE_PREFERENCE_TEXT = "
|
|
3
|
-
const CURSOR_PI_BRIDGE_CONTRACT_LINES = [
|
|
4
|
-
"Pi bridge contract:",
|
|
5
|
-
`${CURSOR_PI_BRIDGE_MCP_TOOL_PREFIX}* names are live Cursor MCP bridge tool names only when exposed in the current run.`,
|
|
6
|
-
`Call the ${CURSOR_PI_BRIDGE_MCP_TOOL_PREFIX}* MCP tool name, not the real pi tool name shown in pi history or transcripts.`,
|
|
7
|
-
CURSOR_PI_BRIDGE_PREFERENCE_TEXT,
|
|
8
|
-
"Bridged calls execute through normal pi tool flow, so pi shows the real pi tool name and returns a normal pi tool result.",
|
|
9
|
-
"Replay IDs, replay labels, and transcript tool names are display-only/context-only, not callable tools.",
|
|
10
|
-
"Cursor-native host tools, settings, plugins, and configured MCP servers are separate from the pi bridge.",
|
|
11
|
-
];
|
|
12
|
-
export function getCursorPiBridgeContractText() {
|
|
13
|
-
return CURSOR_PI_BRIDGE_CONTRACT_LINES.join("\n");
|
|
14
|
-
}
|
|
2
|
+
export const CURSOR_PI_BRIDGE_PREFERENCE_TEXT = "For MCP work and delegation, prefer matching exposed pi__* tools using their listed names, schemas, and prompt guidelines; use Cursor-configured MCP or Cursor-native subagents only when the matching pi tool is not exposed or unavailable.";
|
|
15
3
|
function formatPromptGuidelines(promptGuidelines) {
|
|
16
4
|
const guidelines = promptGuidelines?.map((guideline) => guideline.trim()).filter(Boolean) ?? [];
|
|
17
5
|
if (guidelines.length === 0)
|
package/dist/cursor-config.js
CHANGED
|
@@ -231,7 +231,7 @@ function readCursorSdkConfigFile(path) {
|
|
|
231
231
|
return {};
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
|
-
|
|
234
|
+
function loadCursorSdkConfigForUpdate(path) {
|
|
235
235
|
if (!existsSync(path))
|
|
236
236
|
return {};
|
|
237
237
|
let source;
|
|
@@ -342,16 +342,6 @@ export function updateCursorSdkConfig(path, update, options = {}) {
|
|
|
342
342
|
return updated;
|
|
343
343
|
});
|
|
344
344
|
}
|
|
345
|
-
export function saveCursorSdkUserConfig(config, path = getCursorSdkUserConfigPath()) {
|
|
346
|
-
updateCursorSdkConfig(path, () => ({ ...config }), { newFileMode: 0o600 });
|
|
347
|
-
}
|
|
348
|
-
export function saveCursorSdkProjectConfig(cwd, config, configDirName = CONFIG_DIR_NAME) {
|
|
349
|
-
const path = getCursorSdkProjectConfigPath(cwd, configDirName);
|
|
350
|
-
updateCursorSdkConfig(path, () => ({ ...config }));
|
|
351
|
-
}
|
|
352
|
-
export function mergeCursorSdkConfig(base, patch) {
|
|
353
|
-
return mergeCursorSdkConfigForUpdate({ ...base }, patch);
|
|
354
|
-
}
|
|
355
345
|
export function mergeCursorSdkConfigForUpdate(base, patch) {
|
|
356
346
|
const baseCloud = asRecord(base.cloud);
|
|
357
347
|
const baseLocal = asRecord(base.local);
|
|
@@ -378,12 +368,6 @@ export function mergeCursorSdkConfigForUpdate(base, patch) {
|
|
|
378
368
|
export function cursorFastDefaultsFromConfig(config) {
|
|
379
369
|
return new Map(Object.entries(config?.fastDefaults ?? {}));
|
|
380
370
|
}
|
|
381
|
-
export function withCursorFastDefaults(config, fastDefaults) {
|
|
382
|
-
return {
|
|
383
|
-
...config,
|
|
384
|
-
fastDefaults: Object.fromEntries([...fastDefaults.entries()].sort(([a], [b]) => a.localeCompare(b))),
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
371
|
function resolved(source, value, cappedBy) {
|
|
388
372
|
return { value, source, trustLevel: TRUST_LEVELS[source], ...(cappedBy ? { cappedBy } : {}) };
|
|
389
373
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Generated with @cursor/sdk@1.0.37 from
|
|
1
|
+
// Generated with @cursor/sdk@1.0.37 from 48 Cursor models.
|
|
2
2
|
// Refresh with: npm run refresh:cursor-snapshots -- --write
|
|
3
3
|
// Do not add secrets; this file stores public model metadata only.
|
|
4
4
|
export const FALLBACK_MODEL_ITEMS = [
|
|
@@ -6516,6 +6516,60 @@ export const FALLBACK_MODEL_ITEMS = [
|
|
|
6516
6516
|
}
|
|
6517
6517
|
]
|
|
6518
6518
|
},
|
|
6519
|
+
{
|
|
6520
|
+
id: "gemini-4-argon",
|
|
6521
|
+
displayName: "Gemini 4 Argon",
|
|
6522
|
+
parameters: [
|
|
6523
|
+
{
|
|
6524
|
+
id: "reasoning_effort",
|
|
6525
|
+
displayName: "Effort",
|
|
6526
|
+
values: [
|
|
6527
|
+
{
|
|
6528
|
+
value: "low",
|
|
6529
|
+
displayName: "Low"
|
|
6530
|
+
},
|
|
6531
|
+
{
|
|
6532
|
+
value: "medium",
|
|
6533
|
+
displayName: "Medium"
|
|
6534
|
+
},
|
|
6535
|
+
{
|
|
6536
|
+
value: "high",
|
|
6537
|
+
displayName: "High"
|
|
6538
|
+
}
|
|
6539
|
+
]
|
|
6540
|
+
}
|
|
6541
|
+
],
|
|
6542
|
+
variants: [
|
|
6543
|
+
{
|
|
6544
|
+
params: [
|
|
6545
|
+
{
|
|
6546
|
+
id: "reasoning_effort",
|
|
6547
|
+
value: "low"
|
|
6548
|
+
}
|
|
6549
|
+
],
|
|
6550
|
+
displayName: "Gemini 4 Argon Low"
|
|
6551
|
+
},
|
|
6552
|
+
{
|
|
6553
|
+
params: [
|
|
6554
|
+
{
|
|
6555
|
+
id: "reasoning_effort",
|
|
6556
|
+
value: "medium"
|
|
6557
|
+
}
|
|
6558
|
+
],
|
|
6559
|
+
displayName: "Gemini 4 Argon Medium",
|
|
6560
|
+
isDefault: true
|
|
6561
|
+
},
|
|
6562
|
+
{
|
|
6563
|
+
params: [
|
|
6564
|
+
{
|
|
6565
|
+
id: "reasoning_effort",
|
|
6566
|
+
value: "high"
|
|
6567
|
+
}
|
|
6568
|
+
],
|
|
6569
|
+
displayName: "Gemini 4 Argon High"
|
|
6570
|
+
}
|
|
6571
|
+
]
|
|
6572
|
+
},
|
|
6519
6573
|
{
|
|
6520
6574
|
id: "glm-5.2",
|
|
6521
6575
|
displayName: "GLM 5.2",
|
|
@@ -10155,5 +10209,214 @@ export const FALLBACK_MODEL_ITEMS = [
|
|
|
10155
10209
|
displayName: "Muse Spark 1.3"
|
|
10156
10210
|
}
|
|
10157
10211
|
]
|
|
10212
|
+
},
|
|
10213
|
+
{
|
|
10214
|
+
id: "muse-wonder-1.0",
|
|
10215
|
+
displayName: "Muse Wonder",
|
|
10216
|
+
parameters: [
|
|
10217
|
+
{
|
|
10218
|
+
id: "context",
|
|
10219
|
+
displayName: "Context",
|
|
10220
|
+
values: [
|
|
10221
|
+
{
|
|
10222
|
+
value: "300k",
|
|
10223
|
+
displayName: "300K"
|
|
10224
|
+
},
|
|
10225
|
+
{
|
|
10226
|
+
value: "1m",
|
|
10227
|
+
displayName: "1M"
|
|
10228
|
+
}
|
|
10229
|
+
]
|
|
10230
|
+
},
|
|
10231
|
+
{
|
|
10232
|
+
id: "reasoning_effort",
|
|
10233
|
+
displayName: "Reasoning",
|
|
10234
|
+
values: [
|
|
10235
|
+
{
|
|
10236
|
+
value: "minimal",
|
|
10237
|
+
displayName: "Minimal"
|
|
10238
|
+
},
|
|
10239
|
+
{
|
|
10240
|
+
value: "low",
|
|
10241
|
+
displayName: "Low"
|
|
10242
|
+
},
|
|
10243
|
+
{
|
|
10244
|
+
value: "medium",
|
|
10245
|
+
displayName: "Medium"
|
|
10246
|
+
},
|
|
10247
|
+
{
|
|
10248
|
+
value: "high",
|
|
10249
|
+
displayName: "High"
|
|
10250
|
+
},
|
|
10251
|
+
{
|
|
10252
|
+
value: "xhigh",
|
|
10253
|
+
displayName: "Extra High"
|
|
10254
|
+
},
|
|
10255
|
+
{
|
|
10256
|
+
value: "max",
|
|
10257
|
+
displayName: "Max"
|
|
10258
|
+
}
|
|
10259
|
+
]
|
|
10260
|
+
}
|
|
10261
|
+
],
|
|
10262
|
+
variants: [
|
|
10263
|
+
{
|
|
10264
|
+
params: [
|
|
10265
|
+
{
|
|
10266
|
+
id: "context",
|
|
10267
|
+
value: "300k"
|
|
10268
|
+
},
|
|
10269
|
+
{
|
|
10270
|
+
id: "reasoning_effort",
|
|
10271
|
+
value: "minimal"
|
|
10272
|
+
}
|
|
10273
|
+
],
|
|
10274
|
+
displayName: "Muse Wonder Minimal"
|
|
10275
|
+
},
|
|
10276
|
+
{
|
|
10277
|
+
params: [
|
|
10278
|
+
{
|
|
10279
|
+
id: "context",
|
|
10280
|
+
value: "300k"
|
|
10281
|
+
},
|
|
10282
|
+
{
|
|
10283
|
+
id: "reasoning_effort",
|
|
10284
|
+
value: "low"
|
|
10285
|
+
}
|
|
10286
|
+
],
|
|
10287
|
+
displayName: "Muse Wonder Low"
|
|
10288
|
+
},
|
|
10289
|
+
{
|
|
10290
|
+
params: [
|
|
10291
|
+
{
|
|
10292
|
+
id: "context",
|
|
10293
|
+
value: "300k"
|
|
10294
|
+
},
|
|
10295
|
+
{
|
|
10296
|
+
id: "reasoning_effort",
|
|
10297
|
+
value: "medium"
|
|
10298
|
+
}
|
|
10299
|
+
],
|
|
10300
|
+
displayName: "Muse Wonder Medium"
|
|
10301
|
+
},
|
|
10302
|
+
{
|
|
10303
|
+
params: [
|
|
10304
|
+
{
|
|
10305
|
+
id: "context",
|
|
10306
|
+
value: "300k"
|
|
10307
|
+
},
|
|
10308
|
+
{
|
|
10309
|
+
id: "reasoning_effort",
|
|
10310
|
+
value: "high"
|
|
10311
|
+
}
|
|
10312
|
+
],
|
|
10313
|
+
displayName: "Muse Wonder High"
|
|
10314
|
+
},
|
|
10315
|
+
{
|
|
10316
|
+
params: [
|
|
10317
|
+
{
|
|
10318
|
+
id: "context",
|
|
10319
|
+
value: "300k"
|
|
10320
|
+
},
|
|
10321
|
+
{
|
|
10322
|
+
id: "reasoning_effort",
|
|
10323
|
+
value: "xhigh"
|
|
10324
|
+
}
|
|
10325
|
+
],
|
|
10326
|
+
displayName: "Muse Wonder Extra High"
|
|
10327
|
+
},
|
|
10328
|
+
{
|
|
10329
|
+
params: [
|
|
10330
|
+
{
|
|
10331
|
+
id: "context",
|
|
10332
|
+
value: "300k"
|
|
10333
|
+
},
|
|
10334
|
+
{
|
|
10335
|
+
id: "reasoning_effort",
|
|
10336
|
+
value: "max"
|
|
10337
|
+
}
|
|
10338
|
+
],
|
|
10339
|
+
displayName: "Muse Wonder Max"
|
|
10340
|
+
},
|
|
10341
|
+
{
|
|
10342
|
+
params: [
|
|
10343
|
+
{
|
|
10344
|
+
id: "context",
|
|
10345
|
+
value: "1m"
|
|
10346
|
+
},
|
|
10347
|
+
{
|
|
10348
|
+
id: "reasoning_effort",
|
|
10349
|
+
value: "minimal"
|
|
10350
|
+
}
|
|
10351
|
+
],
|
|
10352
|
+
displayName: "Muse Wonder 1M Minimal"
|
|
10353
|
+
},
|
|
10354
|
+
{
|
|
10355
|
+
params: [
|
|
10356
|
+
{
|
|
10357
|
+
id: "context",
|
|
10358
|
+
value: "1m"
|
|
10359
|
+
},
|
|
10360
|
+
{
|
|
10361
|
+
id: "reasoning_effort",
|
|
10362
|
+
value: "low"
|
|
10363
|
+
}
|
|
10364
|
+
],
|
|
10365
|
+
displayName: "Muse Wonder 1M Low"
|
|
10366
|
+
},
|
|
10367
|
+
{
|
|
10368
|
+
params: [
|
|
10369
|
+
{
|
|
10370
|
+
id: "context",
|
|
10371
|
+
value: "1m"
|
|
10372
|
+
},
|
|
10373
|
+
{
|
|
10374
|
+
id: "reasoning_effort",
|
|
10375
|
+
value: "medium"
|
|
10376
|
+
}
|
|
10377
|
+
],
|
|
10378
|
+
displayName: "Muse Wonder 1M Medium"
|
|
10379
|
+
},
|
|
10380
|
+
{
|
|
10381
|
+
params: [
|
|
10382
|
+
{
|
|
10383
|
+
id: "context",
|
|
10384
|
+
value: "1m"
|
|
10385
|
+
},
|
|
10386
|
+
{
|
|
10387
|
+
id: "reasoning_effort",
|
|
10388
|
+
value: "high"
|
|
10389
|
+
}
|
|
10390
|
+
],
|
|
10391
|
+
displayName: "Muse Wonder 1M High"
|
|
10392
|
+
},
|
|
10393
|
+
{
|
|
10394
|
+
params: [
|
|
10395
|
+
{
|
|
10396
|
+
id: "context",
|
|
10397
|
+
value: "1m"
|
|
10398
|
+
},
|
|
10399
|
+
{
|
|
10400
|
+
id: "reasoning_effort",
|
|
10401
|
+
value: "xhigh"
|
|
10402
|
+
}
|
|
10403
|
+
],
|
|
10404
|
+
displayName: "Muse Wonder 1M Extra High",
|
|
10405
|
+
isDefault: true
|
|
10406
|
+
},
|
|
10407
|
+
{
|
|
10408
|
+
params: [
|
|
10409
|
+
{
|
|
10410
|
+
id: "context",
|
|
10411
|
+
value: "1m"
|
|
10412
|
+
},
|
|
10413
|
+
{
|
|
10414
|
+
id: "reasoning_effort",
|
|
10415
|
+
value: "max"
|
|
10416
|
+
}
|
|
10417
|
+
],
|
|
10418
|
+
displayName: "Muse Wonder 1M Max"
|
|
10419
|
+
}
|
|
10420
|
+
]
|
|
10158
10421
|
}
|
|
10159
10422
|
];
|
|
@@ -150,6 +150,7 @@ export function createCursorLiveRunCoordinator(deps) {
|
|
|
150
150
|
const run = {
|
|
151
151
|
id: params.id,
|
|
152
152
|
agent: params.agent,
|
|
153
|
+
nativeToolsEnabled: params.nativeToolsEnabled !== false,
|
|
153
154
|
bridgeRun: params.bridgeRun,
|
|
154
155
|
sessionBridgeRun: params.sessionBridgeRun,
|
|
155
156
|
sessionAgentScopeKey,
|
|
@@ -36,7 +36,7 @@ function normalizeConnectTimeoutMs(timeoutMs) {
|
|
|
36
36
|
return DEFAULT_CURSOR_MCP_CONNECT_TIMEOUT_MS;
|
|
37
37
|
return Math.min(Math.max(Math.trunc(timeoutMs), MIN_CURSOR_MCP_CONNECT_TIMEOUT_MS), CURSOR_SDK_MCP_DEFAULT_TIMEOUT_MS);
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
function resolveCursorMcpConnectTimeoutMs(env = process.env) {
|
|
40
40
|
const explicitMs = parsePositiveNumber(env[CURSOR_MCP_CONNECT_TIMEOUT_MS_ENV]);
|
|
41
41
|
if (explicitMs !== undefined)
|
|
42
42
|
return normalizeConnectTimeoutMs(explicitMs);
|
|
@@ -51,13 +51,13 @@ function isCursorSdkMcpProtocolTimeoutStack(stack) {
|
|
|
51
51
|
return (/(?:node_modules[/\\]@cursor[/\\]sdk|node_modules\/\@cursor\/sdk|@cursor\/sdk\/dist)/.test(stack) &&
|
|
52
52
|
/\b_setupTimeout\b|\bProtocol\._setupTimeout\b/.test(stack));
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
function isCursorSdkMcpToolTimeoutStack(stack) {
|
|
55
55
|
if (!stack)
|
|
56
56
|
return false;
|
|
57
57
|
return (isCursorSdkMcpProtocolTimeoutStack(stack) &&
|
|
58
58
|
/\bcallTool\b|\bClient\.callTool\b|\bMcpSdkClient\.callTool\b/.test(stack));
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
function isCursorSdkMcpConnectTimeoutStack(stack) {
|
|
61
61
|
if (!stack || !isCursorSdkMcpProtocolTimeoutStack(stack))
|
|
62
62
|
return false;
|
|
63
63
|
// The SDK minifies the Client class name; the protocol method and SDK
|
|
@@ -83,9 +83,9 @@ function patchedSetTimeout(handler, delay, ...args) {
|
|
|
83
83
|
}
|
|
84
84
|
return Reflect.apply(delegate, globalThis, [handler, nextDelay, ...args]);
|
|
85
85
|
}
|
|
86
|
-
export function installCursorMcpToolTimeoutOverride(
|
|
87
|
-
installedToolTimeoutMs =
|
|
88
|
-
installedConnectTimeoutMs =
|
|
86
|
+
export function installCursorMcpToolTimeoutOverride() {
|
|
87
|
+
installedToolTimeoutMs = resolveCursorMcpToolTimeoutMs();
|
|
88
|
+
installedConnectTimeoutMs = resolveCursorMcpConnectTimeoutMs();
|
|
89
89
|
if (!originalSetTimeout) {
|
|
90
90
|
originalSetTimeout = globalThis.setTimeout;
|
|
91
91
|
globalThis.setTimeout = patchedSetTimeout;
|
|
@@ -105,14 +105,3 @@ export function restoreCursorMcpToolTimeoutOverride() {
|
|
|
105
105
|
installedToolTimeoutMs = DEFAULT_CURSOR_MCP_TOOL_TIMEOUT_MS;
|
|
106
106
|
installedConnectTimeoutMs = DEFAULT_CURSOR_MCP_CONNECT_TIMEOUT_MS;
|
|
107
107
|
}
|
|
108
|
-
export const cursorMcpToolTimeoutOverrideDefaults = {
|
|
109
|
-
cursorSdkDefaultTimeoutMs: CURSOR_SDK_MCP_DEFAULT_TIMEOUT_MS,
|
|
110
|
-
defaultOverrideTimeoutMs: DEFAULT_CURSOR_MCP_TOOL_TIMEOUT_MS,
|
|
111
|
-
defaultConnectTimeoutMs: DEFAULT_CURSOR_MCP_CONNECT_TIMEOUT_MS,
|
|
112
|
-
minConnectTimeoutMs: MIN_CURSOR_MCP_CONNECT_TIMEOUT_MS,
|
|
113
|
-
maxNodeTimerDelayMs: MAX_NODE_TIMER_DELAY_MS,
|
|
114
|
-
timeoutMsEnv: CURSOR_MCP_TOOL_TIMEOUT_MS_ENV,
|
|
115
|
-
timeoutSecondsEnv: CURSOR_MCP_TOOL_TIMEOUT_SECONDS_ENV,
|
|
116
|
-
connectTimeoutMsEnv: CURSOR_MCP_CONNECT_TIMEOUT_MS_ENV,
|
|
117
|
-
connectTimeoutSecondsEnv: CURSOR_MCP_CONNECT_TIMEOUT_SECONDS_ENV,
|
|
118
|
-
};
|
|
@@ -8,9 +8,9 @@ import { inferImageMimeType } from "./cursor-tool-result-display-readers.js";
|
|
|
8
8
|
import { LOCAL_READ_PREVIEW_NOTICE, isLocalReadPreviewContent } from "./cursor-transcript-utils.js";
|
|
9
9
|
import { CURSOR_REPLAY_ACTIVITY_TOOL_NAME, getCursorReplayCallSummary, shouldShowCursorReplayCollapsedExpandHint, } from "./cursor-tool-presentation-registry.js";
|
|
10
10
|
import { CURSOR_REPLAY_GENERATE_IMAGE_RESULT_TITLE, isCursorReplayGenerateImageDetails, isCursorReplayActivityDetails, parseCursorReplayToolDetails, } from "./cursor-replay-tool-details.js";
|
|
11
|
-
export { isCursorReplayNativeEditDetails,
|
|
11
|
+
export { isCursorReplayNativeEditDetails, isCursorReplayNativeWriteDetails, parseCursorReplayToolDetails, } from "./cursor-replay-tool-details.js";
|
|
12
12
|
export const CURSOR_REPLAY_COLLAPSED_PREVIEW_LINES = 8;
|
|
13
|
-
|
|
13
|
+
const CURSOR_REPLAY_PREVIEW_MAX_CHARS = 4000;
|
|
14
14
|
export const CURSOR_REPLAY_PREVIEW_MAX_LINE_CHARS = 240;
|
|
15
15
|
const CURSOR_REPLAY_HIGHLIGHT_MAX_CHARS = 12000;
|
|
16
16
|
export const cursorReplayToolSchema = Type.Object({}, { additionalProperties: true });
|
|
@@ -40,7 +40,7 @@ function buildImageReplayComponent(text, imageData, mimeType, filename, theme) {
|
|
|
40
40
|
},
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
function getCursorReplayPath(args, details) {
|
|
44
44
|
const argPath = args?.path;
|
|
45
45
|
return details?.path ?? (typeof argPath === "string" && argPath.trim() ? argPath : "unknown");
|
|
46
46
|
}
|
|
@@ -202,7 +202,7 @@ function formatCursorReplayActivityPreview(details, text, theme, maxLines, strip
|
|
|
202
202
|
}
|
|
203
203
|
return stripHeader ? formatCursorReplayPreview(text, theme, maxLines, true) : formatMutedBlock(text, theme);
|
|
204
204
|
}
|
|
205
|
-
|
|
205
|
+
function formatCursorReplayPreview(text, theme, maxLines = CURSOR_REPLAY_COLLAPSED_PREVIEW_LINES, stripHeader = true) {
|
|
206
206
|
const body = (stripHeader ? stripCursorReplayHeader(text) : text).trimEnd();
|
|
207
207
|
if (!body)
|
|
208
208
|
return undefined;
|
|
@@ -240,7 +240,7 @@ function getCursorReplayCardTitle(toolName, args) {
|
|
|
240
240
|
}
|
|
241
241
|
return "Cursor activity";
|
|
242
242
|
}
|
|
243
|
-
|
|
243
|
+
function renderCursorReplayCall(toolName, args, theme, isPartial) {
|
|
244
244
|
if (!isPartial)
|
|
245
245
|
return new Text("", 0, 0);
|
|
246
246
|
let text = theme.fg("toolTitle", theme.bold(`${getCursorReplayCardTitle(toolName, args)} `));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { parseEnvBoolean } from "./cursor-env-boolean.js";
|
|
2
|
+
export const CURSOR_NATIVE_TOOLS_ENV = "PI_CURSOR_NATIVE_TOOLS";
|
|
3
|
+
/** Default preserves the SDK toolset; false selects the public MCP-only main loop. */
|
|
4
|
+
export function resolveCursorNativeToolsEnabled(env = process.env) {
|
|
5
|
+
return parseEnvBoolean(env[CURSOR_NATIVE_TOOLS_ENV], true);
|
|
6
|
+
}
|
|
7
|
+
export function assertCursorNativeToolsRuntime(runtime, nativeToolsEnabled) {
|
|
8
|
+
if (runtime === "cloud" && !nativeToolsEnabled) {
|
|
9
|
+
throw new Error("PI_CURSOR_NATIVE_TOOLS=0 requires local runtime; Cursor Cloud does not support the SDK tools restriction. Select local runtime or remove the opt-out.");
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { parseEnvBoolean } from "./cursor-env-boolean.js";
|
|
2
2
|
import { resolveCursorMcpToolTimeoutMs } from "./cursor-mcp-timeout-override.js";
|
|
3
3
|
export const CURSOR_PI_TOOL_BRIDGE_ENV = "PI_CURSOR_PI_TOOL_BRIDGE";
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const CURSOR_PI_TOOL_BRIDGE_BUILTINS_ENV = "PI_CURSOR_EXPOSE_BUILTIN_TOOLS";
|
|
5
|
+
const CURSOR_PI_TOOL_BRIDGE_CALL_TIMEOUT_MS_ENV = "PI_CURSOR_PI_BRIDGE_CALL_TIMEOUT_MS";
|
|
6
6
|
export function resolveCursorPiToolBridgeEnabled(env = process.env) {
|
|
7
7
|
return parseEnvBoolean(env[CURSOR_PI_TOOL_BRIDGE_ENV], true);
|
|
8
8
|
}
|
|
@@ -16,3 +16,26 @@ export function resolveCursorPiToolBridgeCallTimeoutMs(env = process.env) {
|
|
|
16
16
|
return mcpToolTimeoutMs;
|
|
17
17
|
return Math.min(Math.max(Math.trunc(parsed), 1), mcpToolTimeoutMs);
|
|
18
18
|
}
|
|
19
|
+
const CURSOR_PI_TOOL_BRIDGE_HOST_ENV = "PI_CURSOR_PI_TOOL_BRIDGE_HOST";
|
|
20
|
+
const CURSOR_PI_TOOL_BRIDGE_PORT_ENV = "PI_CURSOR_PI_TOOL_BRIDGE_PORT";
|
|
21
|
+
const DEFAULT_URL_HOST = "127.0.0.1";
|
|
22
|
+
const PORT_PATTERN = /^\d{1,5}$/;
|
|
23
|
+
export function resolveCursorPiToolBridgeUrlHost(env = process.env) {
|
|
24
|
+
return env[CURSOR_PI_TOOL_BRIDGE_HOST_ENV]?.trim().toLowerCase() === "localhost" ? "localhost" : DEFAULT_URL_HOST;
|
|
25
|
+
}
|
|
26
|
+
function parsePort(text) {
|
|
27
|
+
if (!PORT_PATTERN.test(text))
|
|
28
|
+
return undefined;
|
|
29
|
+
const port = Number(text);
|
|
30
|
+
return port >= 1 && port <= 65535 ? port : undefined;
|
|
31
|
+
}
|
|
32
|
+
export function resolveCursorPiToolBridgePortRange(env = process.env) {
|
|
33
|
+
const parts = env[CURSOR_PI_TOOL_BRIDGE_PORT_ENV]?.trim().split("-");
|
|
34
|
+
if (!parts || parts.length > 2)
|
|
35
|
+
return undefined;
|
|
36
|
+
const first = parsePort(parts[0]);
|
|
37
|
+
const last = parts.length === 2 ? parsePort(parts[1]) : first;
|
|
38
|
+
if (first === undefined || last === undefined || first > last)
|
|
39
|
+
return undefined;
|
|
40
|
+
return { first, last };
|
|
41
|
+
}
|