pi-cursor-sdk 0.2.0 → 0.3.7
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 +73 -0
- package/README.md +55 -51
- package/dist/bundled-context-windows.js +39 -0
- package/dist/context-window-cache.js +92 -0
- package/dist/context.js +353 -0
- package/dist/cursor-active-tools.js +3 -0
- package/dist/cursor-agent-message-web-tools.js +165 -0
- package/dist/cursor-agents-context-registration.js +17 -0
- package/dist/cursor-agents-context.js +127 -0
- package/dist/cursor-api-key.js +34 -0
- package/dist/cursor-bridge-contract.js +27 -0
- package/dist/cursor-cloud-lifecycle.js +650 -0
- package/dist/cursor-cloud-local-state.js +460 -0
- package/dist/cursor-cloud-options.js +145 -0
- package/dist/cursor-cloud-reporting.js +222 -0
- package/dist/cursor-compact-tool-summary.js +75 -0
- package/dist/cursor-config.js +613 -0
- package/dist/cursor-context-tools.js +6 -0
- package/dist/cursor-display-only-trace.js +11 -0
- package/dist/cursor-display-text.js +18 -0
- package/dist/cursor-durable-fs.js +53 -0
- package/dist/cursor-edit-diff.js +13 -0
- package/dist/cursor-env-boolean.js +19 -0
- package/dist/cursor-fallback-models.generated.js +7760 -0
- package/dist/cursor-fallback-warning.js +15 -0
- package/dist/cursor-http1.js +45 -0
- package/dist/cursor-incomplete-tool-visibility.js +83 -0
- package/dist/cursor-live-run-accounting.js +55 -0
- package/dist/cursor-live-run-coordinator.js +409 -0
- package/dist/cursor-mcp-timeout-override.js +116 -0
- package/dist/cursor-model-lifecycle.js +32 -0
- package/dist/cursor-model.js +5 -0
- package/dist/cursor-native-replay-routing.js +35 -0
- package/dist/cursor-native-replay-trace.js +28 -0
- package/dist/cursor-native-tool-display-registration.js +102 -0
- package/dist/cursor-native-tool-display-replay.js +428 -0
- package/dist/cursor-native-tool-display-state.js +70 -0
- package/dist/cursor-native-tool-display-tools.js +123 -0
- package/dist/cursor-native-tool-names.js +11 -0
- package/dist/cursor-partial-content-emitter.js +130 -0
- package/dist/cursor-pi-context.js +30 -0
- package/dist/cursor-pi-tool-bridge-abort.js +114 -0
- package/dist/cursor-pi-tool-bridge-constants.js +6 -0
- package/dist/cursor-pi-tool-bridge-diagnostics.js +125 -0
- package/dist/cursor-pi-tool-bridge-env.js +18 -0
- package/dist/cursor-pi-tool-bridge-mcp.js +100 -0
- package/dist/cursor-pi-tool-bridge-run.js +355 -0
- package/dist/cursor-pi-tool-bridge-server.js +163 -0
- package/dist/cursor-pi-tool-bridge-snapshot.js +63 -0
- package/dist/cursor-pi-tool-bridge-types.js +1 -0
- package/dist/cursor-pi-tool-bridge.js +123 -0
- package/dist/cursor-provider-errors.js +311 -0
- package/dist/cursor-provider-lazy.js +39 -0
- package/dist/cursor-provider-live-run-drain.js +420 -0
- package/dist/cursor-provider-overflow.js +90 -0
- package/dist/cursor-provider-run-finalizer.js +176 -0
- package/dist/cursor-provider-run-outcome.js +76 -0
- package/dist/cursor-provider-turn-coordinator.js +293 -0
- package/dist/cursor-provider-turn-display-router.js +158 -0
- package/dist/cursor-provider-turn-emit.js +41 -0
- package/dist/cursor-provider-turn-finalize.js +154 -0
- package/dist/cursor-provider-turn-lifecycle-emitter.js +126 -0
- package/dist/cursor-provider-turn-prepare.js +379 -0
- package/dist/cursor-provider-turn-runner.js +146 -0
- package/dist/cursor-provider-turn-sdk-normalizer.js +74 -0
- package/dist/cursor-provider-turn-send.js +138 -0
- package/dist/cursor-provider-turn-shell-output.js +117 -0
- package/dist/cursor-provider-turn-tool-ledger.js +99 -0
- package/dist/cursor-provider-turn-types.js +1 -0
- package/dist/cursor-provider.js +72 -0
- package/dist/cursor-question-tool.js +194 -0
- package/dist/cursor-record-utils.js +61 -0
- package/dist/cursor-replay-activity-builders.js +114 -0
- package/dist/cursor-replay-source-names.js +27 -0
- package/dist/cursor-replay-summary-args.js +105 -0
- package/dist/cursor-replay-tool-details.js +167 -0
- package/dist/cursor-ripgrep-path.js +27 -0
- package/dist/cursor-run-final-text.js +63 -0
- package/dist/cursor-runtime-state.js +380 -0
- package/dist/cursor-sdk-billed-usage.js +86 -0
- package/dist/cursor-sdk-event-debug-constants.js +33 -0
- package/dist/cursor-sdk-event-debug-session.js +107 -0
- package/dist/cursor-sdk-event-debug.js +461 -0
- package/dist/cursor-sdk-output-filter.js +1 -0
- package/dist/cursor-sdk-process-error-guard.js +221 -0
- package/dist/cursor-sdk-runtime.js +3 -0
- package/dist/cursor-sensitive-text.js +23 -0
- package/dist/cursor-session-agent-cleanup.js +311 -0
- package/dist/cursor-session-agent-lifecycle.js +32 -0
- package/dist/cursor-session-agent-lineage.js +103 -0
- package/dist/cursor-session-agent-resume.js +417 -0
- package/dist/cursor-session-agent.js +507 -0
- package/dist/cursor-session-compaction-prep.js +21 -0
- package/dist/cursor-session-scope.js +113 -0
- package/dist/cursor-session-send-policy.js +18 -0
- package/dist/cursor-session-store.js +105 -0
- package/dist/cursor-session-turn-queue.js +50 -0
- package/dist/cursor-setting-sources.js +15 -0
- package/dist/cursor-skill-tool.js +230 -0
- package/dist/cursor-state.js +519 -0
- package/dist/cursor-task-presentation.js +59 -0
- package/dist/cursor-tool-lifecycle.js +94 -0
- package/dist/cursor-tool-manifest.js +34 -0
- package/dist/cursor-tool-presentation-registry.js +305 -0
- package/dist/cursor-tool-result-display-readers.js +158 -0
- package/dist/cursor-tool-transcript.js +32 -0
- package/dist/cursor-tool-visibility.js +28 -0
- package/dist/cursor-transcript-tool-formatters.js +618 -0
- package/dist/cursor-transcript-tool-specs.js +284 -0
- package/dist/cursor-transcript-utils.js +170 -0
- package/dist/cursor-usage-accounting.js +166 -0
- package/dist/cursor-web-tool-activity.js +23 -0
- package/dist/cursor-web-tool-args.js +12 -0
- package/dist/index.js +82 -0
- package/dist/model-discovery.js +305 -0
- package/dist/model-list-cache.js +156 -0
- package/docs/cursor-dogfood-checklist.md +2 -1
- package/docs/cursor-live-smoke-checklist.md +13 -12
- package/docs/cursor-model-ux-spec.md +27 -6
- package/docs/cursor-native-tool-replay.md +13 -13
- package/docs/cursor-native-tool-visual-audit.md +6 -3
- package/docs/cursor-testing-lessons.md +14 -8
- package/docs/cursor-tool-surfaces.md +5 -5
- package/docs/platform-smoke.md +3 -3
- package/package.json +19 -7
- package/platform-smoke.config.mjs +1 -1
- package/scripts/build.mjs +126 -0
- package/scripts/cloud-runtime-smoke.mjs +3 -1
- package/scripts/debug-provider-events.mjs +3 -1
- package/scripts/debug-sdk-events.mjs +1 -1
- package/scripts/isolated-cursor-smoke.sh +5 -4
- package/scripts/lib/cloud-smoke-cleanup-evidence.mjs +1 -1
- package/scripts/lib/cursor-visual-render.mjs +1 -1
- package/scripts/lib/ensure-built.mjs +16 -0
- package/scripts/lib/local-resume-smoke-harness.mjs +1 -1
- package/scripts/local-resume-smoke.mjs +3 -1
- package/scripts/platform-smoke/card-detect.mjs +1 -1
- package/scripts/platform-smoke/live-suite-runner.mjs +1 -1
- package/scripts/platform-smoke/render-ansi.mjs +1 -1
- package/scripts/platform-smoke/targets.mjs +2 -2
- package/scripts/prepare.mjs +102 -0
- package/scripts/steering-rpc-smoke.mjs +4 -2
- package/scripts/tmux-live-smoke.sh +11 -11
- package/scripts/visual-tui-smoke-self-test.mjs +4 -1
- package/scripts/visual-tui-smoke.mjs +51 -7
- package/src/bundled-context-windows.ts +4 -1
- package/src/context.ts +27 -4
- package/src/cursor-agents-context-registration.ts +2 -2
- package/src/cursor-agents-context.ts +24 -10
- package/src/cursor-api-key.ts +5 -4
- package/src/cursor-cloud-reporting.ts +23 -2
- package/src/cursor-context-tools.ts +3 -1
- package/src/cursor-fallback-models.generated.ts +592 -204
- package/src/cursor-live-run-coordinator.ts +11 -6
- package/src/cursor-native-tool-display-registration.ts +10 -11
- package/src/cursor-partial-content-emitter.ts +13 -0
- package/src/cursor-pi-context.ts +44 -0
- package/src/cursor-provider-errors.ts +1 -1
- package/src/cursor-provider-lazy.ts +5 -4
- package/src/cursor-provider-live-run-drain.ts +14 -9
- package/src/cursor-provider-run-finalizer.ts +1 -0
- package/src/cursor-provider-turn-coordinator.ts +15 -0
- package/src/cursor-provider-turn-emit.ts +6 -0
- package/src/cursor-provider-turn-finalize.ts +12 -0
- package/src/cursor-provider-turn-prepare.ts +10 -5
- package/src/cursor-provider-turn-types.ts +2 -0
- package/src/cursor-sdk-billed-usage.ts +107 -0
- package/src/cursor-sdk-process-error-guard.ts +6 -4
- package/src/cursor-session-agent-lifecycle.ts +8 -9
- package/src/cursor-session-agent-resume.ts +23 -0
- package/src/cursor-session-compaction-prep.ts +4 -0
- package/src/cursor-skill-tool.ts +1 -1
- package/src/cursor-tool-manifest.ts +1 -1
- package/src/cursor-usage-accounting.ts +70 -9
- package/src/index.ts +1 -1
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +16 -0
package/src/context.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
+
import { getCursorConversationMessages, resolveCursorPiContext } from "./cursor-pi-context.js";
|
|
2
3
|
import type { Context, Message, ToolCall } from "@earendil-works/pi-ai";
|
|
3
4
|
import { convertToLlm } from "@earendil-works/pi-coding-agent";
|
|
4
5
|
import type { AgentModeOption, SDKImage } from "@cursor/sdk";
|
|
@@ -85,7 +86,7 @@ function getCursorBootstrapTailSections(
|
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
function normalizePiContextMessages(messages: Context["messages"]): Message[] {
|
|
88
|
-
return convertToLlm(messages as Parameters<typeof convertToLlm>[0]);
|
|
89
|
+
return convertToLlm(getCursorConversationMessages({ messages }) as Parameters<typeof convertToLlm>[0]);
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
function isTextBlock(block: { type: string }): block is { type: "text"; text: string } {
|
|
@@ -137,6 +138,15 @@ function formatToolCall(toolCall: ToolCall): string {
|
|
|
137
138
|
|
|
138
139
|
function sanitizeSystemPromptForCursor(systemPrompt: string): string {
|
|
139
140
|
let sanitized = systemPrompt;
|
|
141
|
+
// Transcript-era Pi wraps its built-in tool catalog/rules in XML sections.
|
|
142
|
+
sanitized = sanitized.replace(
|
|
143
|
+
/<tools>\n[\s\S]*?\n\nIn addition to the tools above, you may have access to other custom tools depending on the project\.\n<\/tools>/g,
|
|
144
|
+
"Pi tool catalog omitted: Cursor can call only Cursor SDK tools exposed in this run.",
|
|
145
|
+
);
|
|
146
|
+
sanitized = sanitized.replace(
|
|
147
|
+
/<rules>\n[\s\S]*?\n<\/rules>\n\n(?=<docs>\nPi documentation )/g,
|
|
148
|
+
"<rules>\n- Be concise in your responses.\n- Show file paths clearly when working with files.\n</rules>\n\n",
|
|
149
|
+
);
|
|
140
150
|
sanitized = sanitized.replace(
|
|
141
151
|
/Available tools:\n[\s\S]*?\n\nIn addition to the tools above, you may have access to other custom tools depending on the project\.\n\n/g,
|
|
142
152
|
"Pi tool catalog omitted: Cursor can call only Cursor SDK tools exposed in this run.\n\n",
|
|
@@ -279,12 +289,24 @@ function serializeMessageForFingerprint(message: Message, index: number): string
|
|
|
279
289
|
return hashCursorContextValue(
|
|
280
290
|
`toolResult:${message.timestamp ?? index}:${message.toolCallId}:${message.toolName}:${JSON.stringify(message.content)}:${message.isError === true}`,
|
|
281
291
|
);
|
|
292
|
+
default:
|
|
293
|
+
// System messages are handled by serializeRawPiMessageForFingerprint.
|
|
294
|
+
throw new Error("Unsupported Pi message role in Cursor context fingerprint.");
|
|
282
295
|
}
|
|
283
296
|
}
|
|
284
297
|
|
|
285
298
|
function serializeRawPiMessageForFingerprint(message: Context["messages"][number], index: number): string {
|
|
286
299
|
const role = (message as { role?: string }).role;
|
|
287
300
|
switch (role) {
|
|
301
|
+
case "system": {
|
|
302
|
+
const entry = message as {
|
|
303
|
+
content: unknown; sections?: unknown; toolsAdded?: unknown; toolsRemoved?: unknown;
|
|
304
|
+
};
|
|
305
|
+
return hashCursorContextValue(JSON.stringify({
|
|
306
|
+
role, content: entry.content, sections: entry.sections,
|
|
307
|
+
toolsAdded: entry.toolsAdded, toolsRemoved: entry.toolsRemoved,
|
|
308
|
+
}));
|
|
309
|
+
}
|
|
288
310
|
case "branchSummary": {
|
|
289
311
|
const entry = message as { summary?: string; fromId?: string; timestamp?: number };
|
|
290
312
|
return hashCursorContextValue(
|
|
@@ -337,7 +359,7 @@ function parseCursorContextFingerprint(fingerprint: string): CursorContextFinger
|
|
|
337
359
|
|
|
338
360
|
export function computeCursorContextFingerprint(context: Context): string {
|
|
339
361
|
const payload: CursorContextFingerprintPayload = {
|
|
340
|
-
systemHash: hashCursorContextValue(context
|
|
362
|
+
systemHash: hashCursorContextValue(JSON.stringify(resolveCursorPiContext(context))),
|
|
341
363
|
messageHashes: context.messages.map((message, index) => serializeRawPiMessageForFingerprint(message, index)),
|
|
342
364
|
};
|
|
343
365
|
return JSON.stringify(payload);
|
|
@@ -412,8 +434,9 @@ export function buildCursorPrompt(context: Context, options: CursorPromptOptions
|
|
|
412
434
|
sectionsBeforeMessages.push(options.toolManifest);
|
|
413
435
|
}
|
|
414
436
|
|
|
415
|
-
|
|
416
|
-
|
|
437
|
+
const { systemPrompt } = resolveCursorPiContext(context);
|
|
438
|
+
if (systemPrompt) {
|
|
439
|
+
sectionsBeforeMessages.push(`System instructions from pi:\n${sanitizeSystemPromptForCursor(systemPrompt)}`);
|
|
417
440
|
}
|
|
418
441
|
|
|
419
442
|
const messages = normalizePiContextMessages(context.messages);
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { isCursorModel } from "./cursor-model.js";
|
|
2
2
|
import { registerCursorModelLifecycle, type CursorModelLifecycleExtensionApi } from "./cursor-model-lifecycle.js";
|
|
3
3
|
import { resolveEffectiveCursorConfigForContext } from "./cursor-runtime-state.js";
|
|
4
|
+
import { resolveCursorFacingSystemPrompt } from "./cursor-agents-context.js";
|
|
4
5
|
|
|
5
6
|
export type CursorAgentsContextExtensionApi = CursorModelLifecycleExtensionApi;
|
|
6
7
|
|
|
7
8
|
export function registerCursorAgentsContextDedup(pi: CursorAgentsContextExtensionApi): void {
|
|
8
9
|
registerCursorModelLifecycle(pi, {
|
|
9
|
-
beforeAgentStart:
|
|
10
|
+
beforeAgentStart: (event, ctx) => {
|
|
10
11
|
if (!isCursorModel(ctx.model)) return undefined;
|
|
11
|
-
const { resolveCursorFacingSystemPrompt } = await import("./cursor-agents-context.js");
|
|
12
12
|
const runtime = resolveEffectiveCursorConfigForContext(ctx).runtime.value;
|
|
13
13
|
const resolved = resolveCursorFacingSystemPrompt(
|
|
14
14
|
event.systemPrompt,
|
|
@@ -12,8 +12,6 @@ import {
|
|
|
12
12
|
} from "./cursor-setting-sources.js";
|
|
13
13
|
import type { SettingSource } from "@cursor/sdk";
|
|
14
14
|
import type { CursorRuntime } from "./cursor-config.js";
|
|
15
|
-
export { registerCursorAgentsContextDedup, type CursorAgentsContextExtensionApi } from "./cursor-agents-context-registration.js";
|
|
16
|
-
|
|
17
15
|
export const CURSOR_PRESERVE_PI_AGENTS_MD_ENV = "PI_CURSOR_PRESERVE_PI_AGENTS_MD";
|
|
18
16
|
|
|
19
17
|
/** Opening tag prefix pi `buildSystemPrompt()` uses for each context file (path attribute only). */
|
|
@@ -116,9 +114,21 @@ export function serializePiProjectInstructionsBlock(file: PiAgentsContextFile):
|
|
|
116
114
|
return `${PI_PROJECT_INSTRUCTIONS_OPEN_PREFIX}${file.path}">\n${file.content}\n${PI_PROJECT_INSTRUCTIONS_CLOSE}\n\n`;
|
|
117
115
|
}
|
|
118
116
|
|
|
119
|
-
/**
|
|
120
|
-
export function serializePiProjectContextSection(
|
|
117
|
+
/** The two supported Pi project-context serializations; legacy includes outer spacing. */
|
|
118
|
+
export function serializePiProjectContextSection(
|
|
119
|
+
contextFiles: readonly PiAgentsContextFile[],
|
|
120
|
+
format: "legacy" | "transcript" = "legacy",
|
|
121
|
+
): string {
|
|
121
122
|
if (contextFiles.length === 0) return "";
|
|
123
|
+
if (format === "transcript") {
|
|
124
|
+
return [
|
|
125
|
+
"<project_context>",
|
|
126
|
+
"Project-specific instructions and guidelines:",
|
|
127
|
+
"",
|
|
128
|
+
contextFiles.map((file) => serializePiProjectInstructionsBlock(file).trimEnd()).join("\n\n"),
|
|
129
|
+
"</project_context>",
|
|
130
|
+
].join("\n");
|
|
131
|
+
}
|
|
122
132
|
return `${PI_PROJECT_CONTEXT_OPEN}${contextFiles.map(serializePiProjectInstructionsBlock).join("")}${PI_PROJECT_CONTEXT_CLOSE}`;
|
|
123
133
|
}
|
|
124
134
|
|
|
@@ -140,12 +150,16 @@ export function removePiAgentsContextFromSystemPrompt(
|
|
|
140
150
|
}
|
|
141
151
|
if (!removedAny) return systemPrompt;
|
|
142
152
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
153
|
+
// Match only the exact known files in either supported serialization; never
|
|
154
|
+
// strip arbitrary user-authored XML or neighboring custom sections.
|
|
155
|
+
for (const format of ["legacy", "transcript"] as const) {
|
|
156
|
+
const originalSection = serializePiProjectContextSection(contextFiles, format);
|
|
157
|
+
const start = systemPrompt.indexOf(originalSection);
|
|
158
|
+
if (start < 0) continue;
|
|
159
|
+
const replacementSection = serializePiProjectContextSection(retainedContextFiles, format);
|
|
160
|
+
return systemPrompt.slice(0, start) + replacementSection + systemPrompt.slice(start + originalSection.length);
|
|
161
|
+
}
|
|
162
|
+
return systemPrompt;
|
|
149
163
|
}
|
|
150
164
|
|
|
151
165
|
export function resolveCursorFacingSystemPrompt(
|
package/src/cursor-api-key.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { readStoredCredential } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
|
|
1
3
|
export const CURSOR_API_KEY_ENV_VAR = "CURSOR_API_KEY";
|
|
2
4
|
const CURSOR_PROVIDER_ID = "cursor";
|
|
3
5
|
|
|
@@ -21,9 +23,8 @@ export function resolveCursorApiKey(apiKey?: string): string | undefined {
|
|
|
21
23
|
return trimmed;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
function getStoredCursorApiKey(): string | undefined {
|
|
25
27
|
try {
|
|
26
|
-
const { readStoredCredential } = await import("@earendil-works/pi-coding-agent");
|
|
27
28
|
const credential = readStoredCredential(CURSOR_PROVIDER_ID);
|
|
28
29
|
return resolveCursorApiKey(credential?.type === "api_key" ? credential.key : undefined);
|
|
29
30
|
} catch {
|
|
@@ -31,6 +32,6 @@ async function getStoredCursorApiKey(): Promise<string | undefined> {
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
export
|
|
35
|
-
return (
|
|
35
|
+
export function resolveCursorRuntimeApiKey(): Promise<string | undefined> {
|
|
36
|
+
return Promise.resolve(getStoredCursorApiKey() ?? resolveCursorApiKey(process.env.CURSOR_API_KEY));
|
|
36
37
|
}
|
|
@@ -170,17 +170,38 @@ export async function fetchCursorCloudRawUsage(
|
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
function mapCursorSdkAgentUsageToCloudReport(value: unknown, runId?: string): CursorCloudUsageReport | undefined {
|
|
174
|
+
const record = asRecord(value);
|
|
175
|
+
const runs = (getArray(record, "runs") ?? []).map(asRecord);
|
|
176
|
+
const matchingRun = runId ? runs.find((run) => getString(run, "runId") === runId) : undefined;
|
|
177
|
+
return normalizeUsage({
|
|
178
|
+
totalUsage: getRecord(record, "usage"),
|
|
179
|
+
runUsage: getRecord(matchingRun, "usage"),
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
173
183
|
export async function collectCursorCloudRunReport(options: {
|
|
174
184
|
agent: SDKAgent;
|
|
175
185
|
run: Run;
|
|
176
186
|
waitResult: RunResult;
|
|
177
187
|
apiKey: string | undefined;
|
|
188
|
+
agentUsage?: unknown;
|
|
178
189
|
}): Promise<CursorCloudRunReport> {
|
|
179
190
|
const listArtifacts = options.agent.listArtifacts;
|
|
180
|
-
const
|
|
191
|
+
const sdkUsage =
|
|
192
|
+
options.agentUsage !== undefined
|
|
193
|
+
? mapCursorSdkAgentUsageToCloudReport(options.agentUsage, options.run.id)
|
|
194
|
+
: typeof options.agent.getUsage === "function"
|
|
195
|
+
? mapCursorSdkAgentUsageToCloudReport(
|
|
196
|
+
await withTimeout(Promise.resolve(options.agent.getUsage({ runId: options.run.id }))),
|
|
197
|
+
options.run.id,
|
|
198
|
+
)
|
|
199
|
+
: undefined;
|
|
200
|
+
const [artifactResult, restUsage] = await Promise.all([
|
|
181
201
|
typeof listArtifacts === "function" ? withTimeout(listArtifacts.call(options.agent)) : undefined,
|
|
182
|
-
fetchCursorCloudRawUsage({ agentId: options.run.agentId, runId: options.run.id, apiKey: options.apiKey }),
|
|
202
|
+
sdkUsage ? undefined : fetchCursorCloudRawUsage({ agentId: options.run.agentId, runId: options.run.id, apiKey: options.apiKey }),
|
|
183
203
|
]);
|
|
204
|
+
const usage = sdkUsage ?? restUsage;
|
|
184
205
|
const waitBranches = getArray(getRecord(asRecord(options.waitResult), "git"), "branches");
|
|
185
206
|
const runBranches = getArray(getRecord(asRecord(options.run), "git"), "branches");
|
|
186
207
|
return {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { Context } from "@earendil-works/pi-ai";
|
|
2
|
+
import { resolveCursorPiContext } from "./cursor-pi-context.js";
|
|
2
3
|
|
|
3
4
|
/** Tool names from the provider context snapshot at stream start (not live pi.getActiveTools()). */
|
|
4
5
|
export function getActiveContextToolNames(context: Context): ReadonlySet<string> | undefined {
|
|
5
|
-
|
|
6
|
+
const { tools } = resolveCursorPiContext(context);
|
|
7
|
+
return tools === undefined ? undefined : new Set(tools.map((tool) => tool.name));
|
|
6
8
|
}
|