@emmaneugene/pi-cursor-sdk 0.3.7 → 0.4.0

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.
Files changed (79) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +99 -126
  3. package/dist/cursor-agents-context-registration.js +1 -3
  4. package/dist/cursor-agents-context.js +2 -2
  5. package/dist/cursor-config.js +2 -290
  6. package/dist/cursor-provider-errors.js +3 -58
  7. package/dist/cursor-provider-live-run-drain.js +0 -3
  8. package/dist/cursor-provider-run-finalizer.js +4 -7
  9. package/dist/cursor-provider-run-outcome.js +1 -1
  10. package/dist/cursor-provider-turn-finalize.js +3 -55
  11. package/dist/cursor-provider-turn-prepare.js +8 -144
  12. package/dist/cursor-provider-turn-runner.js +9 -23
  13. package/dist/cursor-provider-turn-send.js +8 -35
  14. package/dist/cursor-runtime-state.js +6 -268
  15. package/dist/cursor-sdk-billed-usage.js +3 -18
  16. package/dist/cursor-sdk-platform-package.js +88 -0
  17. package/dist/cursor-session-agent.js +18 -14
  18. package/dist/cursor-skill-tool.js +12 -22
  19. package/dist/cursor-state.js +5 -8
  20. package/dist/cursor-usage-accounting.js +1 -1
  21. package/docs/cursor-dogfood-checklist.md +4 -4
  22. package/docs/cursor-live-smoke-checklist.md +23 -23
  23. package/docs/cursor-model-ux-spec.md +27 -30
  24. package/docs/cursor-native-tool-replay.md +4 -4
  25. package/docs/cursor-native-tool-visual-audit.md +7 -7
  26. package/docs/cursor-testing-lessons.md +23 -16
  27. package/docs/cursor-tool-surfaces.md +2 -4
  28. package/docs/platform-smoke-implementation.md +5 -5
  29. package/docs/platform-smoke.md +27 -72
  30. package/package.json +3 -17
  31. package/platform-smoke.config.mjs +2 -1
  32. package/scripts/lib/local-resume-smoke-harness.mjs +0 -18
  33. package/scripts/platform-smoke/card-detect.mjs +1 -1
  34. package/scripts/platform-smoke/local-resume-runner.mjs +1 -1
  35. package/scripts/platform-smoke/scenarios.mjs +1 -1
  36. package/scripts/platform-smoke/targets.mjs +14 -5
  37. package/src/cursor-agents-context-registration.ts +0 -5
  38. package/src/cursor-agents-context.ts +1 -3
  39. package/src/cursor-config.ts +8 -379
  40. package/src/cursor-provider-errors.ts +2 -62
  41. package/src/cursor-provider-live-run-drain.ts +0 -3
  42. package/src/cursor-provider-run-finalizer.ts +4 -12
  43. package/src/cursor-provider-run-outcome.ts +0 -3
  44. package/src/cursor-provider-turn-finalize.ts +3 -61
  45. package/src/cursor-provider-turn-prepare.ts +8 -165
  46. package/src/cursor-provider-turn-runner.ts +15 -31
  47. package/src/cursor-provider-turn-send.ts +7 -38
  48. package/src/cursor-provider-turn-types.ts +9 -30
  49. package/src/cursor-runtime-state.ts +6 -345
  50. package/src/cursor-sdk-billed-usage.ts +3 -24
  51. package/src/cursor-sdk-platform-package.ts +106 -0
  52. package/src/cursor-session-agent.ts +16 -12
  53. package/src/cursor-skill-tool.ts +10 -26
  54. package/src/cursor-state.ts +5 -10
  55. package/src/cursor-usage-accounting.ts +1 -3
  56. package/dist/cursor-cloud-lifecycle.js +0 -650
  57. package/dist/cursor-cloud-local-state.js +0 -460
  58. package/dist/cursor-cloud-options.js +0 -145
  59. package/dist/cursor-cloud-reporting.js +0 -222
  60. package/dist/cursor-ripgrep-path.js +0 -27
  61. package/scripts/cloud-runtime-smoke.d.mts +0 -42
  62. package/scripts/cloud-runtime-smoke.mjs +0 -623
  63. package/scripts/lib/cloud-smoke-artifacts.d.mts +0 -16
  64. package/scripts/lib/cloud-smoke-artifacts.mjs +0 -94
  65. package/scripts/lib/cloud-smoke-cleanup-evidence.d.mts +0 -209
  66. package/scripts/lib/cloud-smoke-cleanup-evidence.mjs +0 -585
  67. package/scripts/lib/cloud-smoke-github.d.mts +0 -78
  68. package/scripts/lib/cloud-smoke-github.mjs +0 -331
  69. package/scripts/lib/cloud-smoke-pi-runner.d.mts +0 -42
  70. package/scripts/lib/cloud-smoke-pi-runner.mjs +0 -214
  71. package/scripts/lib/cloud-smoke-shutdown.d.mts +0 -67
  72. package/scripts/lib/cloud-smoke-shutdown.mjs +0 -133
  73. package/shared/cursor-cloud-lifecycle-constants.d.mts +0 -3
  74. package/shared/cursor-cloud-lifecycle-constants.mjs +0 -7
  75. package/src/cursor-cloud-lifecycle.ts +0 -733
  76. package/src/cursor-cloud-local-state.ts +0 -536
  77. package/src/cursor-cloud-options.ts +0 -182
  78. package/src/cursor-cloud-reporting.ts +0 -267
  79. package/src/cursor-ripgrep-path.ts +0 -32
@@ -14,6 +14,7 @@ import {
14
14
  } from "./cursor-session-agent-resume.js";
15
15
  import type { CursorSdkEventDebugRecorder } from "./cursor-sdk-event-debug.js";
16
16
  import { loadCursorSdk, type CursorSdkModule } from "./cursor-sdk-runtime.js";
17
+ import { runWithCursorSdkPlatformPackageVisible } from "./cursor-sdk-platform-package.js";
17
18
  import {
18
19
  cursorSessionStoreIdentitiesEqual,
19
20
  openCursorSessionStore,
@@ -501,20 +502,23 @@ async function createSessionAgentEntry(
501
502
  let agent: SDKAgent | undefined;
502
503
  let effectiveSendState = sendState;
503
504
  let resumed = false;
504
- if (resumeHandle && resumeAttemptAllowed && resumeAgent) {
505
- try {
506
- agent = await resumeAgent(resumeHandle.agentId, buildAgentOptions());
507
- effectiveSendState = { ...resumeHandle.sendState };
508
- resumed = true;
509
- } catch {
510
- if (persistentStore) resumeNotice = LOCAL_RESUME_FALLBACK_NOTICE;
511
- if (!cursorSessionStoreIdentitiesEqual(sessionStore.identity, identities.sessionStore)) {
512
- await sessionStore.dispose().catch(() => undefined);
513
- sessionStore = await openCursorSessionStore(params.cwd, identities.sessionStore);
505
+ await runWithCursorSdkPlatformPackageVisible(async () => {
506
+ if (resumeHandle && resumeAttemptAllowed && resumeAgent) {
507
+ try {
508
+ agent = await resumeAgent(resumeHandle.agentId, buildAgentOptions());
509
+ effectiveSendState = { ...resumeHandle.sendState };
510
+ resumed = true;
511
+ } catch {
512
+ if (persistentStore) resumeNotice = LOCAL_RESUME_FALLBACK_NOTICE;
513
+ const currentStore = sessionStore;
514
+ if (currentStore && !cursorSessionStoreIdentitiesEqual(currentStore.identity, identities.sessionStore)) {
515
+ await currentStore.dispose().catch(() => undefined);
516
+ sessionStore = await openCursorSessionStore(params.cwd, identities.sessionStore);
517
+ }
514
518
  }
515
519
  }
516
- }
517
- agent ??= await createAgent(buildAgentOptions());
520
+ agent ??= await createAgent(buildAgentOptions());
521
+ });
518
522
  if (!agent) throw new Error("Cursor SDK agent creation returned no agent");
519
523
  if (!sessionStore) throw new Error("Cursor SDK session store was not opened");
520
524
 
@@ -9,11 +9,9 @@ import type {
9
9
  } from "@earendil-works/pi-coding-agent";
10
10
  import { Type } from "typebox";
11
11
  import { arePiToolsDisabled } from "./cursor-active-tools.js";
12
- import type { CursorRuntime } from "./cursor-config.js";
13
12
  import { isCursorModel } from "./cursor-model.js";
14
13
  import { registerCursorModelLifecycle, type CursorModelLifecycleExtensionApi } from "./cursor-model-lifecycle.js";
15
14
  import { resolveCursorPiToolBridgeEnabled } from "./cursor-pi-tool-bridge-env.js";
16
- import { resolveEffectiveCursorConfigForContext } from "./cursor-runtime-state.js";
17
15
 
18
16
  export const CURSOR_ACTIVATE_SKILL_TOOL_NAME = "cursor_activate_skill";
19
17
  export const CURSOR_ACTIVATE_SKILL_MCP_NAME = "pi__cursor_activate_skill";
@@ -59,24 +57,16 @@ function getAvailableSkillNames(): string[] {
59
57
  return [...currentSkillsByName.keys()].sort();
60
58
  }
61
59
 
62
- function resolveEffectiveRuntimeForSkillLifecycle(
63
- cursorModel: boolean,
64
- ctx: Pick<ExtensionContext, "cwd"> & Partial<Pick<ExtensionContext, "isProjectTrusted">>,
65
- ): CursorRuntime {
66
- return cursorModel ? resolveEffectiveCursorConfigForContext(ctx).runtime.value : "local";
67
- }
68
-
69
- function shouldExposeSkillTool(model: ExtensionContext["model"], runtime: CursorRuntime): boolean {
70
- return runtime === "local" && isCursorModel(model) && resolveCursorPiToolBridgeEnabled() && currentSkillsByName.size > 0;
60
+ function shouldExposeSkillTool(model: ExtensionContext["model"]): boolean {
61
+ return isCursorModel(model) && resolveCursorPiToolBridgeEnabled() && currentSkillsByName.size > 0;
71
62
  }
72
63
 
73
64
  function syncCursorSkillToolForModel(
74
65
  pi: Pick<ExtensionAPI, "getActiveTools" | "setActiveTools">,
75
66
  model: ExtensionContext["model"],
76
- runtime: CursorRuntime,
77
67
  ): void {
78
68
  const activeToolNames = new Set(pi.getActiveTools());
79
- const shouldBeActive = !arePiToolsDisabled(pi) && shouldExposeSkillTool(model, runtime);
69
+ const shouldBeActive = !arePiToolsDisabled(pi) && shouldExposeSkillTool(model);
80
70
  const alreadyActive = activeToolNames.has(CURSOR_ACTIVATE_SKILL_TOOL_NAME);
81
71
  if (shouldBeActive === alreadyActive) return;
82
72
  if (shouldBeActive) {
@@ -114,10 +104,8 @@ export function resolveCursorSkillSystemPrompt(
114
104
  systemPrompt: string,
115
105
  model: ExtensionContext["model"],
116
106
  systemPromptOptions?: BuildSystemPromptOptions,
117
- runtime: CursorRuntime = "local",
118
107
  ): string {
119
108
  if (!isCursorModel(model)) return systemPrompt;
120
- if (runtime === "cloud") return systemPrompt.replace(AVAILABLE_SKILLS_SECTION_PATTERN, "");
121
109
  const skills = getVisibleSkills(systemPromptOptions?.skills);
122
110
  if (skills.length === 0) return systemPrompt;
123
111
  const replacement = formatCursorSkillsForPrompt(skills);
@@ -231,9 +219,9 @@ export function registerCursorSkillTool(pi: CursorSkillToolExtensionApi): void {
231
219
  },
232
220
  });
233
221
 
234
- const clearSkillsAndSync = (model: ExtensionContext["model"], runtime: CursorRuntime = "local"): void => {
222
+ const clearSkillsAndSync = (model: ExtensionContext["model"]): void => {
235
223
  setCurrentSkills([]);
236
- syncCursorSkillToolForModel(pi, model, runtime);
224
+ syncCursorSkillToolForModel(pi, model);
237
225
  };
238
226
 
239
227
  registerCursorModelLifecycle(pi, {
@@ -244,21 +232,17 @@ export function registerCursorSkillTool(pi: CursorSkillToolExtensionApi): void {
244
232
  clearSkillsAndSync(event.model);
245
233
  },
246
234
  turnStart: (_event, ctx) => {
247
- const cursorModel = isCursorModel(ctx.model);
248
- const runtime = resolveEffectiveRuntimeForSkillLifecycle(cursorModel, ctx);
249
- if (!cursorModel || runtime === "cloud") setCurrentSkills([]);
250
- syncCursorSkillToolForModel(pi, ctx.model, runtime);
235
+ if (!isCursorModel(ctx.model)) setCurrentSkills([]);
236
+ syncCursorSkillToolForModel(pi, ctx.model);
251
237
  },
252
238
  beforeAgentStart: (event, ctx) => {
253
- const cursorModel = isCursorModel(ctx.model);
254
- const runtime = resolveEffectiveRuntimeForSkillLifecycle(cursorModel, ctx);
255
- if (cursorModel && runtime === "local") {
239
+ if (isCursorModel(ctx.model)) {
256
240
  setCurrentSkills(event.systemPromptOptions?.skills);
257
241
  } else {
258
242
  setCurrentSkills([]);
259
243
  }
260
- syncCursorSkillToolForModel(pi, ctx.model, runtime);
261
- const resolved = resolveCursorSkillSystemPrompt(event.systemPrompt, ctx.model, event.systemPromptOptions, runtime);
244
+ syncCursorSkillToolForModel(pi, ctx.model);
245
+ const resolved = resolveCursorSkillSystemPrompt(event.systemPrompt, ctx.model, event.systemPromptOptions);
262
246
  if (resolved === event.systemPrompt) return undefined;
263
247
  return { systemPrompt: resolved };
264
248
  },
@@ -42,16 +42,14 @@ import {
42
42
  } from "./cursor-config.js";
43
43
  import {
44
44
  consumeCursorLocalForceOverride,
45
- CURSOR_RUNTIME_ENTRY_TYPE,
46
45
  formatCursorStatus,
47
46
  getCursorCliConfig,
48
47
  getCursorSessionConfig,
49
- registerCursorCloudRuntimeControls,
48
+ registerCursorLocalRuntimeFlags,
50
49
  resetCursorRuntimeStateForTests,
51
50
  resolveCursorStatusRuntime,
52
51
  resolveEffectiveCursorConfigForContext,
53
52
  restoreCursorCliState,
54
- restoreSessionCursorRuntimeState,
55
53
  type CursorRuntimeStateExtensionApi,
56
54
  } from "./cursor-runtime-state.js";
57
55
 
@@ -178,7 +176,6 @@ function restoreSessionCursorMode(branch: readonly SessionEntry[]): void {
178
176
 
179
177
  function restoreSessionCursorPreferences(ctx: { sessionManager: Pick<ExtensionContext["sessionManager"], "getBranch"> }): void {
180
178
  const branch = ctx.sessionManager.getBranch();
181
- restoreSessionCursorRuntimeState(branch);
182
179
  restoreSessionFastPreferences(branch);
183
180
  restoreSessionCursorMode(branch);
184
181
  restoreSessionCursorHttp1(branch);
@@ -266,14 +263,13 @@ function updateCursorStatus(ctx: CursorStatusContext & Pick<ExtensionContext, "m
266
263
  const modeResolution = resolveCursorAgentMode();
267
264
  const mode = modeResolution.kind === "invalid" ? "invalid" : modeResolution.mode;
268
265
  if (resolution.kind === "invalid") {
269
- ctx.ui.setStatus("cursor", formatCursorStatus("invalid", undefined, mode));
266
+ ctx.ui.setStatus("cursor", formatCursorStatus(undefined, "invalid"));
270
267
  return;
271
268
  }
272
- const runtime = resolution.runtime.value;
273
- const fast = runtime === "cloud" ? undefined : metadata?.supportsFast ? getEffectiveFast(model.id) : undefined;
269
+ const fast = metadata?.supportsFast ? getEffectiveFast(model.id) : undefined;
274
270
  ctx.ui.setStatus(
275
271
  "cursor",
276
- formatCursorStatus(runtime, fast, mode, resolution.useHttp1ForAgent.value),
272
+ formatCursorStatus(fast, mode, resolution.useHttp1ForAgent.value),
277
273
  );
278
274
  }
279
275
 
@@ -432,7 +428,7 @@ export function getEffectiveFastForModelId(modelId: string): boolean | undefined
432
428
  }
433
429
 
434
430
  export function registerCursorRuntimeControls(pi: CursorRuntimeControlsExtensionApi): void {
435
- registerCursorCloudRuntimeControls(pi, { refreshStatus: updateCursorStatus });
431
+ registerCursorLocalRuntimeFlags(pi);
436
432
 
437
433
  pi.registerFlag("cursor-fast", {
438
434
  description: "Force Cursor fast mode for this run when the selected Cursor model supports it",
@@ -673,7 +669,6 @@ export const __testUtils = {
673
669
  FAST_ENTRY_TYPE,
674
670
  MODE_ENTRY_TYPE,
675
671
  CURSOR_HTTP1_ENTRY_TYPE,
676
- RUNTIME_ENTRY_TYPE: CURSOR_RUNTIME_ENTRY_TYPE,
677
672
  DEFAULT_CURSOR_AGENT_MODE,
678
673
  getConfigPath,
679
674
  loadGlobalFastPreferences,
@@ -7,7 +7,6 @@ import {
7
7
  type CursorPromptOptions,
8
8
  } from "./context.js";
9
9
  import { asRecord, getNumber } from "./cursor-record-utils.js";
10
- import type { CursorRuntime } from "./cursor-config.js";
11
10
 
12
11
  export interface CursorUsagePromptOptions extends CursorPromptOptions {
13
12
  maxInputTokens: number;
@@ -110,7 +109,6 @@ export function isCursorSdkUsageSafeForPiMessage(turnUsage: CursorSdkTurnUsage,
110
109
  }
111
110
 
112
111
  export interface CursorSdkUsageApplyOptions {
113
- runtime: CursorRuntime;
114
112
  turn?: CursorSdkTurnUsage;
115
113
  billed?: CursorSdkTurnUsage;
116
114
  }
@@ -209,7 +207,7 @@ export function applyCursorUsage(
209
207
  sdkUsage?: CursorSdkUsageApplyOptions,
210
208
  ): void {
211
209
  const billed = sdkUsage?.billed;
212
- const localTurn = sdkUsage?.runtime === "local" ? sdkUsage.turn : undefined;
210
+ const localTurn = sdkUsage?.turn;
213
211
  if (billed && isCursorSdkUsagePartitionSafe(billed, model)) {
214
212
  applyCursorSdkUsage(partial, billed);
215
213
  applyResolvedCursorOccupancy(partial, model, context, localTurn);