@emmaneugene/pi-cursor-sdk 0.3.7 → 0.4.1

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 (91) hide show
  1. package/CHANGELOG.md +22 -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-extension-factory-guard.js +31 -0
  7. package/dist/cursor-pi-tool-bridge-server.js +3 -0
  8. package/dist/cursor-pi-tool-bridge.js +5 -0
  9. package/dist/cursor-provider-errors.js +3 -58
  10. package/dist/cursor-provider-live-run-drain.js +0 -3
  11. package/dist/cursor-provider-run-finalizer.js +4 -7
  12. package/dist/cursor-provider-run-outcome.js +1 -1
  13. package/dist/cursor-provider-turn-finalize.js +3 -55
  14. package/dist/cursor-provider-turn-prepare.js +8 -144
  15. package/dist/cursor-provider-turn-runner.js +9 -23
  16. package/dist/cursor-provider-turn-send.js +8 -35
  17. package/dist/cursor-runtime-state.js +6 -268
  18. package/dist/cursor-sdk-billed-usage.js +3 -18
  19. package/dist/cursor-sdk-platform-package.js +88 -0
  20. package/dist/cursor-session-agent.js +18 -14
  21. package/dist/cursor-skill-tool.js +12 -22
  22. package/dist/cursor-state.js +5 -8
  23. package/dist/cursor-usage-accounting.js +1 -1
  24. package/dist/index.js +65 -49
  25. package/docs/cursor-dogfood-checklist.md +4 -4
  26. package/docs/cursor-live-smoke-checklist.md +24 -24
  27. package/docs/cursor-model-ux-spec.md +27 -30
  28. package/docs/cursor-native-tool-replay.md +4 -4
  29. package/docs/cursor-native-tool-visual-audit.md +10 -10
  30. package/docs/cursor-testing-lessons.md +38 -16
  31. package/docs/cursor-tool-surfaces.md +2 -4
  32. package/docs/platform-smoke-implementation.md +5 -5
  33. package/docs/platform-smoke.md +28 -73
  34. package/node_modules/cross-spawn/node_modules/which/CHANGELOG.md +166 -0
  35. package/package.json +3 -17
  36. package/platform-smoke.config.mjs +2 -1
  37. package/scripts/lib/cursor-visual-render.mjs +12 -2
  38. package/scripts/lib/local-resume-smoke-harness.mjs +0 -18
  39. package/scripts/platform-smoke/card-detect.mjs +1 -1
  40. package/scripts/platform-smoke/local-resume-runner.mjs +1 -1
  41. package/scripts/platform-smoke/scenarios.mjs +1 -1
  42. package/scripts/platform-smoke/targets.mjs +14 -5
  43. package/scripts/visual-tui-smoke-self-test.mjs +9 -33
  44. package/scripts/visual-tui-smoke.mjs +54 -11
  45. package/src/cursor-agents-context-registration.ts +0 -5
  46. package/src/cursor-agents-context.ts +1 -3
  47. package/src/cursor-config.ts +8 -379
  48. package/src/cursor-extension-factory-guard.ts +57 -0
  49. package/src/cursor-pi-tool-bridge-server.ts +4 -0
  50. package/src/cursor-pi-tool-bridge.ts +5 -0
  51. package/src/cursor-provider-errors.ts +2 -62
  52. package/src/cursor-provider-live-run-drain.ts +0 -3
  53. package/src/cursor-provider-run-finalizer.ts +4 -12
  54. package/src/cursor-provider-run-outcome.ts +0 -3
  55. package/src/cursor-provider-turn-finalize.ts +3 -61
  56. package/src/cursor-provider-turn-prepare.ts +8 -165
  57. package/src/cursor-provider-turn-runner.ts +15 -31
  58. package/src/cursor-provider-turn-send.ts +7 -38
  59. package/src/cursor-provider-turn-types.ts +9 -30
  60. package/src/cursor-runtime-state.ts +6 -345
  61. package/src/cursor-sdk-billed-usage.ts +3 -24
  62. package/src/cursor-sdk-platform-package.ts +106 -0
  63. package/src/cursor-session-agent.ts +16 -12
  64. package/src/cursor-skill-tool.ts +10 -26
  65. package/src/cursor-state.ts +5 -10
  66. package/src/cursor-usage-accounting.ts +1 -3
  67. package/src/index.ts +70 -49
  68. package/dist/cursor-cloud-lifecycle.js +0 -650
  69. package/dist/cursor-cloud-local-state.js +0 -460
  70. package/dist/cursor-cloud-options.js +0 -145
  71. package/dist/cursor-cloud-reporting.js +0 -222
  72. package/dist/cursor-ripgrep-path.js +0 -27
  73. package/scripts/cloud-runtime-smoke.d.mts +0 -42
  74. package/scripts/cloud-runtime-smoke.mjs +0 -623
  75. package/scripts/lib/cloud-smoke-artifacts.d.mts +0 -16
  76. package/scripts/lib/cloud-smoke-artifacts.mjs +0 -94
  77. package/scripts/lib/cloud-smoke-cleanup-evidence.d.mts +0 -209
  78. package/scripts/lib/cloud-smoke-cleanup-evidence.mjs +0 -585
  79. package/scripts/lib/cloud-smoke-github.d.mts +0 -78
  80. package/scripts/lib/cloud-smoke-github.mjs +0 -331
  81. package/scripts/lib/cloud-smoke-pi-runner.d.mts +0 -42
  82. package/scripts/lib/cloud-smoke-pi-runner.mjs +0 -214
  83. package/scripts/lib/cloud-smoke-shutdown.d.mts +0 -67
  84. package/scripts/lib/cloud-smoke-shutdown.mjs +0 -133
  85. package/shared/cursor-cloud-lifecycle-constants.d.mts +0 -3
  86. package/shared/cursor-cloud-lifecycle-constants.mjs +0 -7
  87. package/src/cursor-cloud-lifecycle.ts +0 -733
  88. package/src/cursor-cloud-local-state.ts +0 -536
  89. package/src/cursor-cloud-options.ts +0 -182
  90. package/src/cursor-cloud-reporting.ts +0 -267
  91. package/src/cursor-ripgrep-path.ts +0 -32
@@ -1,8 +1,5 @@
1
1
  import { loadCursorTranscriptWebToolCallsAfterOffset } from "./cursor-agent-message-web-tools.js";
2
- import { collectCursorCloudRunReport, formatCursorCloudRunReport, } from "./cursor-cloud-reporting.js";
3
- import { recordCursorCloudLifecycleRun } from "./cursor-cloud-lifecycle.js";
4
2
  import { getCheckpointContextWindow, saveCachedContextWindow } from "./context-window-cache.js";
5
- import { scrubSensitiveText } from "./cursor-sensitive-text.js";
6
3
  import { isCursorRunFinishedSuccessfully, resolveCursorRunOutcome, } from "./cursor-provider-run-outcome.js";
7
4
  import { loadCursorSdk } from "./cursor-sdk-runtime.js";
8
5
  import { attachCursorSdkBilledTurnUsage } from "./cursor-sdk-billed-usage.js";
@@ -39,7 +36,6 @@ export function buildCursorRunOutcomeFromWait(params) {
39
36
  runErrorFallback: params.runErrorFallback,
40
37
  resolvedApiKey: params.resolvedApiKey,
41
38
  optionsApiKey: params.optionsApiKey,
42
- runtimeTarget: prepared.runtimeTarget,
43
39
  });
44
40
  }
45
41
  async function replayCursorTranscriptWebToolCalls(agentId, cwd, messageOffset, turnStore, turnCoordinator, sdkEventDebug) {
@@ -63,20 +59,8 @@ async function replayCursorTranscriptWebToolCalls(agentId, cwd, messageOffset, t
63
59
  sdkEventDebug?.recordError("cursor_transcript_web_tools", error);
64
60
  }
65
61
  }
66
- function scrubCursorCloudReportingError(error, apiKey) {
67
- return new Error(scrubSensitiveText(error instanceof Error ? error.message : String(error), apiKey));
68
- }
69
- function recordCursorCloudReportingError(sdkEventDebug, error, apiKey) {
70
- try {
71
- sdkEventDebug?.recordError("cloud_run_report", scrubCursorCloudReportingError(error, apiKey));
72
- }
73
- catch {
74
- // Debug reporting must never affect provider execution.
75
- }
76
- }
77
62
  /** Single wait/finalize path for SDK runs: wait, debug capture, transcript replay, incomplete tools, artifacts, context cache. */
78
63
  export async function awaitFinalizeCursorRunOutcome(params) {
79
- const apiKey = params.resolvedApiKey ?? params.optionsApiKey;
80
64
  const waitResult = params.waitResult ?? (await params.run.wait());
81
65
  const outcome = buildCursorRunOutcomeFromWait({
82
66
  waitResult,
@@ -90,54 +74,18 @@ export async function awaitFinalizeCursorRunOutcome(params) {
90
74
  const billed = await attachCursorSdkBilledTurnUsage({
91
75
  agent: params.prepared.agent,
92
76
  agentId: params.run.agentId,
93
- runtime: params.prepared.runtimeTarget,
94
- runId: params.run.id,
95
77
  });
96
78
  params.prepared.runtime.billedTurnUsage = billed.turn;
97
79
  if (params.prepared.runtime.liveRun) {
98
80
  params.prepared.runtime.liveRun.billedTurnUsage = billed.turn;
99
81
  }
100
- let displayOnlyTraceBlock;
101
- if (params.prepared.runtimeTarget === "cloud" && isCursorRunFinishedSuccessfully(outcome)) {
102
- let report = { agentId: params.run.agentId, runId: params.run.id, branches: [] };
103
- try {
104
- report = await collectCursorCloudRunReport({
105
- agent: params.prepared.agent,
106
- run: params.run,
107
- waitResult,
108
- apiKey,
109
- agentUsage: billed.agentUsage,
110
- });
111
- }
112
- catch (error) {
113
- recordCursorCloudReportingError(params.sdkEventDebug, error, apiKey);
114
- }
115
- try {
116
- recordCursorCloudLifecycleRun(report, { apiKey });
117
- }
118
- catch (error) {
119
- recordCursorCloudReportingError(params.sdkEventDebug, error, apiKey);
120
- }
121
- try {
122
- params.sdkEventDebug?.recordProviderEvent("cloud_run_report", report);
123
- }
124
- catch (error) {
125
- recordCursorCloudReportingError(params.sdkEventDebug, error, apiKey);
126
- }
127
- try {
128
- displayOnlyTraceBlock = formatCursorCloudRunReport(report, { apiKey });
129
- }
130
- catch (error) {
131
- recordCursorCloudReportingError(params.sdkEventDebug, error, apiKey);
132
- }
133
- }
134
82
  try {
135
83
  params.sdkEventDebug?.recordWaitResult(waitResult);
136
84
  }
137
85
  catch {
138
86
  // Debug reporting must never affect provider execution.
139
87
  }
140
- if (params.prepared.runtimeTarget === "local" && isCursorRunFinishedSuccessfully(outcome)) {
88
+ if (isCursorRunFinishedSuccessfully(outcome)) {
141
89
  await replayCursorTranscriptWebToolCalls(params.run.agentId, params.prepared.cwd, params.cursorAgentMessageOffset, params.prepared.sessionAgentLease.store, params.prepared.runtime.turnCoordinator, params.sdkEventDebug);
142
90
  }
143
91
  params.prepared.runtime.turnCoordinator.discardIncompleteStartedToolCalls(outcome.incompleteTools);
@@ -147,8 +95,8 @@ export async function awaitFinalizeCursorRunOutcome(params) {
147
95
  catch {
148
96
  // Debug artifact failures must never affect provider execution.
149
97
  }
150
- if (params.prepared.runtimeTarget === "local" && params.cacheContextWindow !== false) {
98
+ if (params.cacheContextWindow !== false) {
151
99
  await cacheSdkContextWindow(params.contextWindowAgentId ?? params.run.agentId, params.modelId, params.prepared.cwd, params.prepared.sessionAgentLease.store);
152
100
  }
153
- return { outcome, displayOnlyTraceBlock };
101
+ return { outcome };
154
102
  }
@@ -1,52 +1,28 @@
1
1
  import { configureCursorSdkHttp1 } from "./cursor-http1.js";
2
2
  import { installCursorMcpToolTimeoutOverride } from "./cursor-mcp-timeout-override.js";
3
- import { ensureCursorRipgrepPath } from "./cursor-ripgrep-path.js";
3
+ import { ensureCursorRipgrepPath, ensureCursorTreeSitterVendorDir } from "./cursor-sdk-platform-package.js";
4
4
  import { installCursorSdkOutputFilter, suppressCursorSdkOutput } from "./cursor-sdk-output-filter.js";
5
5
  import { acquireSessionCursorAgent, buildCursorSessionSendPrompt, planCursorSessionSend, resetSessionCursorAgent, } from "./cursor-session-agent.js";
6
- import { buildCursorPrompt, estimateCursorPromptTokens } from "./context.js";
6
+ import { estimateCursorPromptTokens } from "./context.js";
7
7
  import { getCursorPromptOptions } from "./cursor-usage-accounting.js";
8
8
  import { getActiveContextToolNames } from "./cursor-context-tools.js";
9
- import { abandonSessionCursorAgent, createCursorNativeReplayId, cursorLiveRuns, getActiveCursorLiveRunForCurrentScope, getPendingCursorLiveRun, } from "./cursor-provider-live-run-drain.js";
9
+ import { abandonSessionCursorAgent, createCursorNativeReplayId, cursorLiveRuns, } from "./cursor-provider-live-run-drain.js";
10
10
  import { getCursorProviderAgentModeOrThrow, getEffectiveFastForModelId, } from "./cursor-state.js";
11
11
  import { resolveEffectiveCursorConfig } from "./cursor-runtime-state.js";
12
12
  import { buildCursorBridgeExcludeToolNames } from "./cursor-config.js";
13
13
  import { buildCursorModelSelection } from "./model-discovery.js";
14
14
  import { getEffectiveCursorSettingSources } from "./cursor-setting-sources.js";
15
- import { formatCursorCloudPreflightError, buildCursorCloudAgentOptions, preflightCursorCloudRuntime, } from "./cursor-cloud-options.js";
16
- import { inspectCursorCloudLocalState } from "./cursor-cloud-local-state.js";
17
- import { getCursorSessionName, getCursorSessionProjectTrusted } from "./cursor-session-scope.js";
15
+ import { getCursorSessionProjectTrusted } from "./cursor-session-scope.js";
18
16
  import { resolveCursorPiToolBridgeEnabled } from "./cursor-pi-tool-bridge-env.js";
19
17
  import { buildCursorToolManifestText, resolveCursorToolManifestEnabled, } from "./cursor-tool-manifest.js";
20
18
  import { isCursorNativeToolDisplayRuntimeEnabled } from "./cursor-native-tool-display-state.js";
21
- import { createCursorCloudLifecyclePersistenceError, recordCursorCloudLifecycleSafely, } from "./cursor-cloud-lifecycle.js";
22
19
  import { MISSING_CURSOR_API_KEY_MESSAGE } from "./cursor-provider-errors.js";
23
20
  import { CursorSdkTurnCoordinator } from "./cursor-provider-turn-coordinator.js";
24
21
  import { resolveCursorApiKey } from "./cursor-api-key.js";
25
22
  import { loadCursorSdk } from "./cursor-sdk-runtime.js";
26
- function buildCursorCloudPromptContext(context, handoff) {
27
- if (handoff === "bootstrap")
28
- return context;
29
- for (let index = context.messages.length - 1; index >= 0; index -= 1) {
30
- const message = context.messages[index];
31
- if (message.role === "user")
32
- return { ...context, messages: [message] };
33
- }
34
- return { ...context, messages: context.messages.slice(-1) };
35
- }
36
- const CLOUD_SEND_PLAN = { mode: "bootstrap", resetAgent: false, reason: "initial" };
37
23
  export function resolveCursorProviderTurnConfig(cwd) {
38
24
  return resolveEffectiveCursorConfig({ cwd, projectTrusted: getCursorSessionProjectTrusted() });
39
25
  }
40
- function buildCloudCursorProviderTurnLifecycle(agent) {
41
- return {
42
- trackRunCompletion: () => { },
43
- commitSend: () => { },
44
- abandon: async () => { },
45
- dispose: async () => {
46
- await agent[Symbol.asyncDispose]?.();
47
- },
48
- };
49
- }
50
26
  function buildLocalCursorProviderTurnLifecycle(lease, scopeKey) {
51
27
  return {
52
28
  trackRunCompletion: (completion) => lease.trackRunCompletion(completion),
@@ -55,115 +31,6 @@ function buildLocalCursorProviderTurnLifecycle(lease, scopeKey) {
55
31
  dispose: async () => { },
56
32
  };
57
33
  }
58
- async function prepareCursorCloudProviderTurn(prepareParams) {
59
- const { params, cwd, resolvedApiKey, sdkEventDebug, throwIfAborted, resolvedConfig, agentMode, selection, fastEnabled } = prepareParams;
60
- const { model, context, options } = params;
61
- let restoreCursorSdkOutputFilter;
62
- let cloudAgentForCleanup;
63
- let completed = false;
64
- try {
65
- const preflight = preflightCursorCloudRuntime({
66
- resolvedConfig,
67
- localState: resolvedConfig.cloud.allowLocalState.value
68
- ? { insideGitRepo: false }
69
- : inspectCursorCloudLocalState(cwd, {
70
- repo: resolvedConfig.cloud.repo.value,
71
- branch: resolvedConfig.cloud.branch.value,
72
- }),
73
- hasPriorContext: context.messages.length > 1,
74
- });
75
- if (!preflight.ok)
76
- throw new Error(formatCursorCloudPreflightError(preflight));
77
- if (getPendingCursorLiveRun(context) || getActiveCursorLiveRunForCurrentScope()) {
78
- throw new Error("Cursor cloud runtime cannot start while a local Cursor live run is pending; finish or abort the local run, then retry.");
79
- }
80
- const { Agent } = await loadCursorSdk();
81
- restoreCursorSdkOutputFilter = installCursorSdkOutputFilter();
82
- const promptOptions = {
83
- ...getCursorPromptOptions(model),
84
- agentMode,
85
- includePiBridgeGuidance: false,
86
- includePiAskQuestionGuidance: false,
87
- };
88
- const prompt = buildCursorPrompt(buildCursorCloudPromptContext(context, resolvedConfig.cloud.contextHandoff.value), promptOptions);
89
- const promptInputTokens = estimateCursorPromptTokens(prompt, promptOptions);
90
- const agent = await suppressCursorSdkOutput(() => Agent.create(buildCursorCloudAgentOptions({
91
- apiKey: resolvedApiKey,
92
- modelSelection: selection,
93
- agentMode,
94
- resolvedConfig,
95
- name: getCursorSessionName(),
96
- })));
97
- cloudAgentForCleanup = agent;
98
- if (!recordCursorCloudLifecycleSafely({ agentId: agent.agentId }, resolvedApiKey)) {
99
- throw createCursorCloudLifecyclePersistenceError(agent.agentId, "intent", undefined, resolvedApiKey);
100
- }
101
- sdkEventDebug?.recordProviderMeta({ runtime: "cloud", cloudAgentId: agent.agentId, phase: "agent_created" });
102
- throwIfAborted();
103
- const textDeltas = [];
104
- const nativeReplayId = createCursorNativeReplayId();
105
- const turnCoordinator = new CursorSdkTurnCoordinator({
106
- stream: params.stream,
107
- partial: params.partial,
108
- cwd,
109
- resolvedApiKey,
110
- useNativeToolReplay: false,
111
- nativeReplayId,
112
- textDeltas,
113
- debugRecorder: sdkEventDebug,
114
- });
115
- sdkEventDebug?.recordProviderMeta({
116
- runtime: "cloud",
117
- cloudAgentId: agent.agentId,
118
- model: {
119
- id: model.id,
120
- provider: model.provider,
121
- api: model.api,
122
- reasoning: options?.reasoning ?? "off",
123
- fastEnabled,
124
- selection,
125
- },
126
- contextHandoff: resolvedConfig.cloud.contextHandoff.value,
127
- sendPlan: CLOUD_SEND_PLAN,
128
- promptOptions,
129
- agentMode,
130
- localForce: false,
131
- });
132
- completed = true;
133
- cloudAgentForCleanup = undefined;
134
- return {
135
- runtimeTarget: "cloud",
136
- agent,
137
- cwd,
138
- payload: {
139
- text: prompt.text,
140
- images: prompt.images.length > 0 ? prompt.images : undefined,
141
- },
142
- meta: {
143
- sendPlan: CLOUD_SEND_PLAN,
144
- prompt,
145
- bootstrap: true,
146
- promptInputTokens,
147
- useNativeToolReplay: false,
148
- bridgeEnabled: false,
149
- nativeReplayId,
150
- agentMode,
151
- modelSelection: selection,
152
- },
153
- contextWindowAgentId: agent.agentId,
154
- textDeltas,
155
- restoreCursorSdkOutputFilter,
156
- lifecycle: buildCloudCursorProviderTurnLifecycle(agent),
157
- runtime: { kind: "direct", turnCoordinator },
158
- };
159
- }
160
- finally {
161
- if (!completed) {
162
- await cloudAgentForCleanup?.[Symbol.asyncDispose]?.().catch(() => { });
163
- restoreCursorSdkOutputFilter?.();
164
- }
165
- }
166
- }
167
34
  async function prepareCursorLocalProviderTurn(prepareParams) {
168
35
  const { params, cwd, resolvedApiKey, sdkEventDebug, throwIfAborted, resolvedConfig, agentMode, selection, fastEnabled } = prepareParams;
169
36
  const { model, context, options } = params;
@@ -173,6 +40,7 @@ async function prepareCursorLocalProviderTurn(prepareParams) {
173
40
  let completed = false;
174
41
  try {
175
42
  ensureCursorRipgrepPath();
43
+ ensureCursorTreeSitterVendorDir();
176
44
  const localSafety = {
177
45
  autoReview: resolvedConfig.local.autoReview.value,
178
46
  sandboxEnabled: resolvedConfig.local.sandboxEnabled.value,
@@ -315,7 +183,6 @@ async function prepareCursorLocalProviderTurn(prepareParams) {
315
183
  });
316
184
  completed = true;
317
185
  return {
318
- runtimeTarget: "local",
319
186
  agent,
320
187
  cwd,
321
188
  payload: sendPayload,
@@ -357,17 +224,14 @@ async function prepareCursorLocalProviderTurn(prepareParams) {
357
224
  }
358
225
  }
359
226
  }
360
- /** Resolves the runtime target from the caller-supplied snapshot and dispatches to the owning branch. */
361
227
  export async function prepareCursorProviderTurn(prepareParams) {
362
- const { params, resolvedConfig } = prepareParams;
228
+ const { params } = prepareParams;
363
229
  const { model, options } = params;
364
230
  const agentMode = getCursorProviderAgentModeOrThrow();
365
- const fastEnabled = resolvedConfig.runtime.value === "cloud" ? undefined : getEffectiveFastForModelId(model.id);
231
+ const fastEnabled = getEffectiveFastForModelId(model.id);
366
232
  const selection = buildCursorModelSelection(model.id, options?.reasoning ?? "off", fastEnabled);
367
233
  const context = { ...prepareParams, agentMode, selection, fastEnabled };
368
- return resolvedConfig.runtime.value === "cloud"
369
- ? prepareCursorCloudProviderTurn(context)
370
- : prepareCursorLocalProviderTurn(context);
234
+ return prepareCursorLocalProviderTurn(context);
371
235
  }
372
236
  export function requireCursorApiKey(options) {
373
237
  const apiKey = resolveCursorApiKey(options?.apiKey);
@@ -9,9 +9,9 @@ import { discardIncompleteToolsFromPrepared, emitCursorLiveTurn, } from "./curso
9
9
  import { CursorRunFinalizer } from "./cursor-provider-run-finalizer.js";
10
10
  import { prepareCursorProviderTurn, requireCursorApiKey, resolveCursorProviderTurnConfig, } from "./cursor-provider-turn-prepare.js";
11
11
  import { sendCursorProviderTurn } from "./cursor-provider-turn-send.js";
12
- function requireLocalLivePreparedTurn(prepared) {
13
- if (prepared.runtimeTarget !== "local" || prepared.runtime.kind !== "live") {
14
- throw new Error("Cursor live run requires a local live prepared turn");
12
+ function requireLivePreparedTurn(prepared) {
13
+ if (prepared.runtime.kind !== "live") {
14
+ throw new Error("Cursor live run requires a live prepared turn");
15
15
  }
16
16
  return prepared;
17
17
  }
@@ -19,7 +19,6 @@ export class CursorProviderTurnRunner {
19
19
  params;
20
20
  sdkEventDebug;
21
21
  resolvedApiKey;
22
- runtimeTarget;
23
22
  constructor(params) {
24
23
  this.params = params;
25
24
  }
@@ -40,7 +39,6 @@ export class CursorProviderTurnRunner {
40
39
  sdkEventDebug: () => this.sdkEventDebug,
41
40
  sdkProcessErrorGuard,
42
41
  resolvedApiKey: () => this.resolvedApiKey,
43
- runtimeTarget: () => this.runtimeTarget,
44
42
  });
45
43
  try {
46
44
  this.throwIfAborted();
@@ -52,21 +50,12 @@ export class CursorProviderTurnRunner {
52
50
  });
53
51
  sdkEventDebugRef.current = this.sdkEventDebug;
54
52
  this.sdkEventDebug?.recordContextSnapshot(context);
55
- // Resolved once here, before any drain await, so the drain decision and the
56
- // prepare dispatch below always act on the same config snapshot.
57
53
  const resolvedConfig = resolveCursorProviderTurnConfig(cwd);
58
- this.runtimeTarget = resolvedConfig.runtime.value;
59
- if (resolvedConfig.runtime.value === "local") {
60
- // The observed local-executor closed-pipe EPIPE is contained only from this
61
- // turn's pre-send live-run drain through run completion; for live runs the
62
- // finalizer holds the guard until run.wait() settles. A hit marks
63
- // this scope's pooled agent transport dead so the next acquire recreates it.
64
- const localScopeKey = getCursorSessionScopeKey();
65
- sdkProcessErrorGuard.containLocalTransportClosedPipe(() => invalidateSessionAgent(localScopeKey, { deadTransport: true }));
66
- if ((await drainExistingCursorLiveRunBeforeSend(stream, partial, model, context, options?.signal, this.sdkEventDebug)) ===
67
- "stream_ended") {
68
- return;
69
- }
54
+ const localScopeKey = getCursorSessionScopeKey();
55
+ sdkProcessErrorGuard.containLocalTransportClosedPipe(() => invalidateSessionAgent(localScopeKey, { deadTransport: true }));
56
+ if ((await drainExistingCursorLiveRunBeforeSend(stream, partial, model, context, options?.signal, this.sdkEventDebug)) ===
57
+ "stream_ended") {
58
+ return;
70
59
  }
71
60
  this.throwIfAborted();
72
61
  this.resolvedApiKey = requireCursorApiKey(options);
@@ -84,11 +73,10 @@ export class CursorProviderTurnRunner {
84
73
  sdkEventDebug: this.sdkEventDebug,
85
74
  sdkProcessErrorGuard,
86
75
  throwIfAborted: () => this.throwIfAborted(),
87
- resolvedApiKey: this.resolvedApiKey,
88
76
  });
89
77
  const { send } = sendResult;
90
78
  if (prepared.runtime.kind === "live") {
91
- const livePrepared = requireLocalLivePreparedTurn(prepared);
79
+ const livePrepared = requireLivePreparedTurn(prepared);
92
80
  liveCompletion = runFinalizer.startLiveRunCompletion({
93
81
  send,
94
82
  prepared: livePrepared,
@@ -122,7 +110,6 @@ export class CursorProviderTurnRunner {
122
110
  kind: "direct",
123
111
  prepared,
124
112
  outcome: finalized.outcome,
125
- displayOnlyTraceBlock: finalized.displayOnlyTraceBlock,
126
113
  });
127
114
  }
128
115
  catch (error) {
@@ -138,7 +125,6 @@ export class CursorProviderTurnRunner {
138
125
  sdkEventDebug: () => this.sdkEventDebug,
139
126
  sdkProcessErrorGuard: installCursorSdkProcessErrorGuard(),
140
127
  resolvedApiKey: () => this.resolvedApiKey,
141
- runtimeTarget: () => this.runtimeTarget,
142
128
  });
143
129
  await runFinalizer.applyTerminalEvent({ kind: "error", prepared: undefined, error });
144
130
  await runFinalizer.cleanup(undefined, undefined, undefined);
@@ -1,27 +1,8 @@
1
1
  import { countCursorAgentMessages } from "./cursor-agent-message-web-tools.js";
2
- import { createCursorCloudLifecyclePersistenceError, recordCursorCloudLifecycleSafely, } from "./cursor-cloud-lifecycle.js";
3
2
  import { CursorLiveRunAbortError } from "./cursor-live-run-coordinator.js";
4
3
  import { cursorLiveRuns } from "./cursor-provider-live-run-drain.js";
5
4
  import { consumeCursorLocalForceOverride } from "./cursor-runtime-state.js";
6
5
  import { recordCursorSessionAgentLineage } from "./cursor-session-agent-lineage.js";
7
- const CLOUD_LEDGER_CANCEL_TIMEOUT_MS = 5000;
8
- async function requestBoundedCloudRunCancellation(run) {
9
- let timer;
10
- const timeout = new Promise((resolve) => {
11
- timer = setTimeout(() => resolve(false), CLOUD_LEDGER_CANCEL_TIMEOUT_MS);
12
- timer.unref?.();
13
- });
14
- try {
15
- return await Promise.race([
16
- Promise.resolve().then(() => run.cancel()).then(() => true, () => false),
17
- timeout,
18
- ]);
19
- }
20
- finally {
21
- if (timer)
22
- clearTimeout(timer);
23
- }
24
- }
25
6
  function recordDebug(action) {
26
7
  try {
27
8
  action();
@@ -31,7 +12,7 @@ function recordDebug(action) {
31
12
  }
32
13
  }
33
14
  export async function sendCursorProviderTurn(sendParams) {
34
- const { params, prepared, sdkEventDebug, sdkProcessErrorGuard, throwIfAborted, resolvedApiKey } = sendParams;
15
+ const { params, prepared, sdkEventDebug, sdkProcessErrorGuard, throwIfAborted } = sendParams;
35
16
  const { options } = params;
36
17
  const { agent, cwd, payload, meta, runtime } = prepared;
37
18
  const { turnCoordinator, liveRun } = runtime;
@@ -52,13 +33,11 @@ export async function sendCursorProviderTurn(sendParams) {
52
33
  abortRegistration?.signal.addEventListener("abort", abortListener, { once: true });
53
34
  throwIfAborted();
54
35
  let cursorAgentMessageOffset;
55
- if (prepared.runtimeTarget === "local") {
56
- try {
57
- cursorAgentMessageOffset = await countCursorAgentMessages(agent.agentId, cwd, prepared.sessionAgentLease.store);
58
- }
59
- catch (error) {
60
- recordDebug(() => sdkEventDebug?.recordError("cursor_agent_message_count", error));
61
- }
36
+ try {
37
+ cursorAgentMessageOffset = await countCursorAgentMessages(agent.agentId, cwd, prepared.sessionAgentLease.store);
38
+ }
39
+ catch (error) {
40
+ recordDebug(() => sdkEventDebug?.recordError("cursor_agent_message_count", error));
62
41
  }
63
42
  throwIfAborted();
64
43
  recordDebug(() => sdkEventDebug?.recordSendMeta({
@@ -89,20 +68,14 @@ export async function sendCursorProviderTurn(sendParams) {
89
68
  },
90
69
  };
91
70
  throwIfAborted();
92
- if (prepared.runtimeTarget === "local" && consumeCursorLocalForceOverride(prepared.localForce)) {
71
+ if (consumeCursorLocalForceOverride(prepared.localForce)) {
93
72
  sendOptions.local = { force: true };
94
73
  }
95
74
  const runPromise = agent.send(payload, sendOptions);
96
75
  // Record at send initiation (promise created), including later reject/cancel paths.
97
- if (prepared.runtimeTarget === "local") {
98
- recordCursorSessionAgentLineage(agent.agentId);
99
- }
76
+ recordCursorSessionAgentLineage(agent.agentId);
100
77
  const run = await runPromise;
101
78
  sdkRun = run;
102
- if (prepared.runtimeTarget === "cloud" && !recordCursorCloudLifecycleSafely({ agentId: run.agentId, runId: run.id }, resolvedApiKey)) {
103
- const cancellationConfirmed = await requestBoundedCloudRunCancellation(run);
104
- throw createCursorCloudLifecyclePersistenceError(run.agentId, "run", cancellationConfirmed, resolvedApiKey);
105
- }
106
79
  recordDebug(() => sdkEventDebug?.recordRunMeta({
107
80
  runId: run.id,
108
81
  requestId: run.requestId,