pi-cursor-sdk 0.5.2 → 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 +66 -1
- package/README.md +62 -795
- package/dist/context.js +13 -7
- 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-custom-subagent-definitions.js +1 -1
- package/dist/cursor-fallback-models.generated.js +665 -1
- package/dist/cursor-live-run-coordinator.js +1 -0
- package/dist/cursor-local-agent-ownership.js +17 -0
- package/dist/cursor-mcp-timeout-override.js +7 -18
- package/dist/cursor-native-tool-display-replay.js +5 -5
- package/dist/cursor-native-tools.js +11 -0
- package/dist/cursor-pi-tool-bridge-diagnostics.js +4 -0
- package/dist/cursor-pi-tool-bridge-env.js +25 -2
- package/dist/cursor-pi-tool-bridge-run.js +10 -3
- 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 +2 -8
- 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-turn-summary.js +1 -1
- 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-cleanup.js +10 -1
- package/dist/cursor-session-agent-lifecycle.js +2 -2
- package/dist/cursor-session-agent-lineage.js +11 -7
- package/dist/cursor-session-agent-resume.js +15 -9
- package/dist/cursor-session-agent.js +28 -15
- package/dist/cursor-session-scope.js +28 -21
- package/dist/cursor-session-settings.js +3 -3
- package/dist/cursor-session-store.js +2 -2
- package/dist/cursor-state.js +26 -29
- 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 +8 -10
- package/dist/model-list-cache.js +4 -9
- package/docs/cursor-live-smoke-checklist.md +4 -4
- package/docs/cursor-model-ux-spec.md +36 -19
- package/docs/cursor-native-tool-replay.md +8 -5
- package/docs/cursor-native-tool-visual-audit.md +1 -1
- package/docs/cursor-testing-lessons.md +39 -9
- package/docs/cursor-tool-surfaces.md +48 -4
- package/docs/development.md +93 -0
- package/docs/platform-smoke-implementation.md +3 -2
- package/docs/reference.md +806 -0
- package/package.json +13 -11
- 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 +18 -11
- 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-custom-subagent-definitions.ts +1 -1
- package/src/cursor-fallback-models.generated.ts +665 -1
- package/src/cursor-live-run-coordinator.ts +5 -0
- package/src/cursor-local-agent-ownership.ts +18 -0
- package/src/cursor-mcp-timeout-override.ts +7 -31
- package/src/cursor-native-tool-display-replay.ts +4 -6
- package/src/cursor-native-tools.ts +14 -0
- package/src/cursor-pi-tool-bridge-diagnostics.ts +17 -0
- package/src/cursor-pi-tool-bridge-env.ts +31 -2
- package/src/cursor-pi-tool-bridge-run.ts +10 -3
- 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 +2 -10
- 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-turn-summary.ts +1 -1
- 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-cleanup.ts +6 -1
- package/src/cursor-session-agent-lifecycle.ts +2 -2
- package/src/cursor-session-agent-lineage.ts +10 -5
- package/src/cursor-session-agent-resume.ts +14 -7
- package/src/cursor-session-agent.ts +31 -15
- package/src/cursor-session-scope.ts +34 -20
- package/src/cursor-session-settings.ts +3 -3
- package/src/cursor-session-store.ts +2 -2
- package/src/cursor-state.ts +34 -41
- 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 +7 -9
- 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) {
|
|
@@ -90,7 +95,7 @@ function formatContentBlocks(content) {
|
|
|
90
95
|
}
|
|
91
96
|
function formatToolCall(toolCall) {
|
|
92
97
|
const args = JSON.stringify(toolCall.arguments) ?? "";
|
|
93
|
-
return `
|
|
98
|
+
return `Historical tool request (${getCursorReplayPromptLabel(toolCall.name)}, call ${toolCall.id}): ${args}`;
|
|
94
99
|
}
|
|
95
100
|
function sanitizeSystemPromptForCursor(systemPrompt) {
|
|
96
101
|
let sanitized = systemPrompt;
|
|
@@ -126,7 +131,7 @@ function formatMessage(msg) {
|
|
|
126
131
|
}
|
|
127
132
|
case "toolResult": {
|
|
128
133
|
const text = formatContentBlocks(msg.content);
|
|
129
|
-
const label = msg.isError ? "
|
|
134
|
+
const label = msg.isError ? "Historical tool error" : "Historical tool result";
|
|
130
135
|
return `${label} (${getCursorReplayPromptLabel(msg.toolName)}, call ${msg.toolCallId}): ${text}`;
|
|
131
136
|
}
|
|
132
137
|
}
|
|
@@ -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
|
}
|
|
@@ -10,5 +10,5 @@ export function buildCursorCustomSubagentDefinitions(config) {
|
|
|
10
10
|
}),
|
|
11
11
|
}]));
|
|
12
12
|
}
|
|
13
|
-
// ponytail: SDK 1.0.
|
|
13
|
+
// ponytail: SDK 1.0.37 LOCAL conversion keeps only model ID/inherit; it drops params.
|
|
14
14
|
// Upgrade this claim only after the installed public converter preserves them.
|