pi-cursor-sdk 0.1.56 → 0.1.58
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 +49 -1
- package/README.md +104 -29
- package/docs/cursor-live-smoke-checklist.md +7 -7
- package/docs/cursor-model-ux-spec.md +55 -44
- 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 +20 -7
- package/docs/cursor-tool-surfaces.md +13 -2
- package/docs/platform-smoke-implementation.md +220 -0
- package/docs/platform-smoke.md +183 -247
- package/package.json +38 -6
- package/platform-smoke.config.mjs +5 -1
- package/scripts/cloud-runtime-smoke.d.mts +3 -0
- package/scripts/cloud-runtime-smoke.mjs +502 -0
- package/scripts/debug-provider-events.mjs +8 -3
- package/scripts/isolated-cursor-smoke.sh +4 -6
- package/scripts/lib/cursor-child-process.d.mts +1 -0
- package/scripts/lib/cursor-child-process.mjs +137 -7
- package/scripts/lib/local-resume-smoke-harness.mjs +543 -0
- package/scripts/local-resume-cleanup-smoke.mjs +108 -0
- package/scripts/local-resume-smoke.d.mts +1 -0
- package/scripts/local-resume-smoke.mjs +642 -0
- package/scripts/platform-smoke/artifact-anchored-extract.d.mts +10 -0
- package/scripts/platform-smoke/artifact-anchored-extract.mjs +111 -0
- package/scripts/platform-smoke/artifact-bundle-chunk.mjs +57 -0
- package/scripts/platform-smoke/artifact-bundle-contract.mjs +34 -0
- package/scripts/platform-smoke/artifact-fs-safety.mjs +311 -0
- package/scripts/platform-smoke/artifact-openat-extract.c +335 -0
- package/scripts/platform-smoke/artifact-secrets.mjs +155 -0
- package/scripts/platform-smoke/artifacts.mjs +293 -65
- package/scripts/platform-smoke/card-detect.mjs +16 -4
- package/scripts/platform-smoke/crabbox-runner.mjs +45 -3
- package/scripts/platform-smoke/doctor.mjs +20 -10
- package/scripts/platform-smoke/live-suite-runner.mjs +18 -57
- package/scripts/platform-smoke/local-resume-runner.mjs +252 -0
- package/scripts/platform-smoke/local-resume-suites.d.mts +15 -0
- package/scripts/platform-smoke/local-resume-suites.mjs +104 -0
- package/scripts/platform-smoke/scenarios.mjs +16 -2
- package/scripts/platform-smoke/target-runtime.mjs +206 -0
- package/scripts/platform-smoke/targets.mjs +33 -141
- package/scripts/platform-smoke/visual-evidence.mjs +6 -7
- package/scripts/platform-smoke/wrapped-line-match.mjs +9 -0
- package/scripts/platform-smoke.mjs +40 -27
- package/scripts/refresh-cursor-model-snapshots.mjs +18 -6
- package/scripts/steering-rpc-smoke.mjs +16 -6
- package/scripts/tmux-live-smoke.sh +3 -5
- package/shared/cursor-cloud-lifecycle-constants.d.mts +3 -0
- package/shared/cursor-cloud-lifecycle-constants.mjs +7 -0
- package/shared/cursor-sensitive-text.mjs +7 -1
- package/src/context.ts +5 -2
- package/src/cursor-agents-context-registration.ts +7 -0
- package/src/cursor-agents-context.ts +3 -1
- package/src/cursor-api-key.ts +15 -1
- package/src/cursor-bridge-contract.ts +3 -0
- package/src/cursor-cloud-lifecycle.ts +733 -0
- package/src/cursor-cloud-options.ts +206 -0
- package/src/cursor-cloud-reporting.ts +246 -0
- package/src/cursor-config.ts +659 -0
- package/src/cursor-display-only-trace.ts +14 -0
- package/src/cursor-display-text.ts +8 -2
- package/src/cursor-durable-fs.ts +49 -0
- package/src/cursor-fallback-models.generated.ts +2045 -485
- package/src/cursor-live-run-accounting.ts +7 -1
- package/src/cursor-live-run-coordinator.ts +1 -0
- package/src/cursor-pi-tool-bridge-run.ts +14 -4
- package/src/cursor-provider-live-run-drain.ts +5 -0
- package/src/cursor-provider-run-finalizer.ts +36 -28
- package/src/cursor-provider-turn-finalize.ts +72 -6
- package/src/cursor-provider-turn-prepare.ts +228 -12
- package/src/cursor-provider-turn-runner.ts +41 -13
- package/src/cursor-provider-turn-send.ts +59 -16
- package/src/cursor-provider-turn-types.ts +44 -10
- package/src/cursor-runtime-state.ts +478 -0
- package/src/cursor-sdk-event-debug.ts +46 -6
- package/src/cursor-sdk-process-error-guard.ts +101 -30
- package/src/cursor-session-agent-cleanup.ts +328 -0
- package/src/cursor-session-agent-resume.ts +439 -0
- package/src/cursor-session-agent.ts +109 -13
- package/src/cursor-session-scope.ts +35 -2
- package/src/cursor-session-send-policy.ts +1 -1
- package/src/cursor-skill-tool.ts +30 -11
- package/src/cursor-state.ts +112 -69
- package/src/cursor-usage-accounting.ts +14 -4
- package/src/index.ts +11 -2
- package/src/model-discovery.ts +13 -57
package/src/model-discovery.ts
CHANGED
|
@@ -8,7 +8,8 @@ import type { ProviderModelConfig } from "@earendil-works/pi-coding-agent";
|
|
|
8
8
|
import type { ModelThinkingLevel, ThinkingLevelMap } from "@earendil-works/pi-ai/compat";
|
|
9
9
|
import { loadContextWindowCache } from "./context-window-cache.js";
|
|
10
10
|
import { loadCursorSdk } from "./cursor-sdk-runtime.js";
|
|
11
|
-
import { resolveCursorApiKey } from "./cursor-api-key.js";
|
|
11
|
+
import { resolveCursorApiKey, resolveCursorRuntimeApiKey } from "./cursor-api-key.js";
|
|
12
|
+
import { scrubSensitiveText } from "./cursor-sensitive-text.js";
|
|
12
13
|
import {
|
|
13
14
|
fingerprintApiKey,
|
|
14
15
|
loadAnyCachedModelCatalog,
|
|
@@ -16,12 +17,11 @@ import {
|
|
|
16
17
|
saveModelListCache,
|
|
17
18
|
} from "./model-list-cache.js";
|
|
18
19
|
|
|
19
|
-
const CURSOR_PROVIDER_ID = "cursor";
|
|
20
20
|
const FALLBACK_CONTEXT_WINDOW = 128000;
|
|
21
21
|
const FALLBACK_MAX_TOKENS = 16384;
|
|
22
22
|
const ZERO_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
|
23
23
|
const TEXT_AND_IMAGE_INPUT: ProviderModelConfig["input"] = ["text", "image"];
|
|
24
|
-
const AUTH_SETUP_HINT = "/login (Use an API key -> Cursor)
|
|
24
|
+
const AUTH_SETUP_HINT = "/login (Use an API key -> Cursor) or CURSOR_API_KEY; startup discovery does not parse Pi CLI arguments, and Cursor Agent CLI/Desktop login is not reused";
|
|
25
25
|
const CATALOG_REFRESH_HINT =
|
|
26
26
|
"After adding auth to an already-started pi session, run /cursor-refresh-models to refresh the full live Cursor model catalog without restarting pi.";
|
|
27
27
|
|
|
@@ -35,47 +35,15 @@ export interface CursorModelFallbackIssue {
|
|
|
35
35
|
|
|
36
36
|
export interface DiscoverModelsOptions {
|
|
37
37
|
onFallback?: (issue: CursorModelFallbackIssue) => void;
|
|
38
|
+
apiKey?: string;
|
|
38
39
|
// Bypass the on-disk model cache and always hit the live catalog. Used by the
|
|
39
40
|
// /cursor-refresh-models command; the startup path leaves this false so warm
|
|
40
41
|
// boots skip the slow network round-trip.
|
|
41
42
|
forceRefresh?: boolean;
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
function
|
|
45
|
-
|
|
46
|
-
const arg = argv[index];
|
|
47
|
-
if (arg === "--api-key") {
|
|
48
|
-
const value = argv[index + 1];
|
|
49
|
-
if (!value || value.startsWith("--")) return undefined;
|
|
50
|
-
const trimmed = value.trim();
|
|
51
|
-
return trimmed || undefined;
|
|
52
|
-
}
|
|
53
|
-
const prefix = "--api-key=";
|
|
54
|
-
if (arg.startsWith(prefix)) {
|
|
55
|
-
const trimmed = arg.slice(prefix.length).trim();
|
|
56
|
-
return trimmed || undefined;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return undefined;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async function getStoredCursorApiKey(): Promise<string | undefined> {
|
|
63
|
-
try {
|
|
64
|
-
const { AuthStorage } = await import("@earendil-works/pi-coding-agent");
|
|
65
|
-
return resolveCursorApiKey(await AuthStorage.create().getApiKey(CURSOR_PROVIDER_ID, { includeFallback: false }));
|
|
66
|
-
} catch {
|
|
67
|
-
return undefined;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async function getDiscoveryApiKey(): Promise<string | undefined> {
|
|
72
|
-
const cliApiKey = resolveCursorApiKey(getCliApiKeyFromArgv());
|
|
73
|
-
if (cliApiKey) return cliApiKey;
|
|
74
|
-
|
|
75
|
-
const storedApiKey = await getStoredCursorApiKey();
|
|
76
|
-
if (storedApiKey) return storedApiKey;
|
|
77
|
-
|
|
78
|
-
return resolveCursorApiKey(process.env.CURSOR_API_KEY);
|
|
45
|
+
async function getDiscoveryApiKey(apiKey?: string): Promise<string | undefined> {
|
|
46
|
+
return resolveCursorApiKey(apiKey) ?? resolveCursorRuntimeApiKey();
|
|
79
47
|
}
|
|
80
48
|
|
|
81
49
|
export interface CursorModelMetadata {
|
|
@@ -136,7 +104,7 @@ function mapComparableLevel(
|
|
|
136
104
|
level: Exclude<ModelThinkingLevel, "off">,
|
|
137
105
|
): string | null {
|
|
138
106
|
if (level === "xhigh") {
|
|
139
|
-
return getPreferredParameterValue(parameter, ["xhigh", "
|
|
107
|
+
return getPreferredParameterValue(parameter, ["xhigh", "extra-high"]);
|
|
140
108
|
}
|
|
141
109
|
return getParameterValue(parameter, level);
|
|
142
110
|
}
|
|
@@ -156,6 +124,7 @@ function getThinkingLevelMap(item: ModelListItem): ThinkingLevelMap | undefined
|
|
|
156
124
|
medium: null,
|
|
157
125
|
high: getParameterValue(valueParameter, "true"),
|
|
158
126
|
xhigh: null,
|
|
127
|
+
max: null,
|
|
159
128
|
};
|
|
160
129
|
}
|
|
161
130
|
|
|
@@ -169,6 +138,7 @@ function getThinkingLevelMap(item: ModelListItem): ThinkingLevelMap | undefined
|
|
|
169
138
|
medium: mapComparableLevel(valueParameter, "medium"),
|
|
170
139
|
high: mapComparableLevel(valueParameter, "high"),
|
|
171
140
|
xhigh: mapComparableLevel(valueParameter, "xhigh"),
|
|
141
|
+
max: mapComparableLevel(valueParameter, "max"),
|
|
172
142
|
};
|
|
173
143
|
}
|
|
174
144
|
|
|
@@ -444,22 +414,9 @@ export function buildCursorModelSelection(
|
|
|
444
414
|
return params.length > 0 ? { id: metadata.selectionModelId, params } : { id: metadata.selectionModelId };
|
|
445
415
|
}
|
|
446
416
|
|
|
447
|
-
function scrubDiscoveryErrorText(text: string, apiKey: string): string {
|
|
448
|
-
let scrubbed = text.replace(new RegExp(apiKey.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "g"), "[redacted]");
|
|
449
|
-
return scrubbed
|
|
450
|
-
.replace(/Bearer\s+[A-Za-z0-9._~+/=-]+/gi, "Bearer [redacted]")
|
|
451
|
-
.replace(/((?:^|[\s,{])cookie["']?\s*[:=]\s*["']?)[^\n]+/gi, "$1[redacted]")
|
|
452
|
-
.replace(
|
|
453
|
-
/((?:authorization|api[_-]?key|apiKey|token|session(?:[_-]?id)?)["']?\s*[:=]\s*["']?)[^"'\s,;}]+/gi,
|
|
454
|
-
"$1[redacted]",
|
|
455
|
-
)
|
|
456
|
-
.trim();
|
|
457
|
-
}
|
|
458
|
-
|
|
459
417
|
function sanitizeDiscoveryError(error: unknown, apiKey: string): string | undefined {
|
|
460
418
|
const message = error instanceof Error ? error.message : typeof error === "string" ? error : "";
|
|
461
|
-
|
|
462
|
-
return scrubbed || undefined;
|
|
419
|
+
return scrubSensitiveText(message, apiKey).trim() || undefined;
|
|
463
420
|
}
|
|
464
421
|
|
|
465
422
|
async function useFallbackModels(options: DiscoverModelsOptions, issue: CursorModelFallbackIssue): Promise<ProviderModelConfig[]> {
|
|
@@ -469,7 +426,7 @@ async function useFallbackModels(options: DiscoverModelsOptions, issue: CursorMo
|
|
|
469
426
|
}
|
|
470
427
|
|
|
471
428
|
export async function discoverModels(options: DiscoverModelsOptions = {}): Promise<ProviderModelConfig[]> {
|
|
472
|
-
const apiKey = await getDiscoveryApiKey();
|
|
429
|
+
const apiKey = await getDiscoveryApiKey(options.apiKey);
|
|
473
430
|
if (!apiKey) {
|
|
474
431
|
return useFallbackModels(options, {
|
|
475
432
|
reason: "missing-api-key",
|
|
@@ -506,8 +463,8 @@ export async function discoverModels(options: DiscoverModelsOptions = {}): Promi
|
|
|
506
463
|
if (cachedCatalog && cachedCatalog.models.length > 0) {
|
|
507
464
|
options.onFallback?.({
|
|
508
465
|
reason: "cached-after-error",
|
|
509
|
-
message: `Cursor model discovery failed; using cached Cursor model catalog from ${new Date(cachedCatalog.fetchedAt).toISOString()}
|
|
510
|
-
errorMessage,
|
|
466
|
+
message: `Cursor model discovery failed; using cached Cursor model catalog from ${new Date(cachedCatalog.fetchedAt).toISOString()}.${errorMessage ? ` ${errorMessage}` : ""}`,
|
|
467
|
+
...(errorMessage ? { errorMessage } : {}),
|
|
511
468
|
});
|
|
512
469
|
return registerModelItems(cachedCatalog.models);
|
|
513
470
|
}
|
|
@@ -522,6 +479,5 @@ export async function discoverModels(options: DiscoverModelsOptions = {}): Promi
|
|
|
522
479
|
export const __testUtils = {
|
|
523
480
|
parseContextWindow,
|
|
524
481
|
registerModelItems,
|
|
525
|
-
getCliApiKeyFromArgv,
|
|
526
482
|
normalizeApiKey: resolveCursorApiKey,
|
|
527
483
|
};
|