pi-cursor-sdk 0.1.62 → 0.3.6
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 +85 -0
- package/README.md +57 -53
- package/dist/bundled-context-windows.js +39 -0
- package/dist/context-window-cache.js +92 -0
- package/dist/context.js +338 -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 +113 -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 +4 -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 +406 -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 +118 -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 +412 -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 +275 -0
- package/dist/cursor-provider-turn-display-router.js +158 -0
- package/dist/cursor-provider-turn-emit.js +35 -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 +374 -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 +15 -14
- package/docs/cursor-model-ux-spec.md +29 -8
- 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 +7 -7
- package/docs/cursor-tool-surfaces.md +5 -5
- package/docs/platform-smoke.md +6 -6
- package/node_modules/fast-uri/index.js +37 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/security.test.js +136 -0
- package/node_modules/hono/dist/cjs/context.js +28 -13
- package/node_modules/hono/dist/cjs/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/cjs/helper/streaming/sse.js +1 -1
- package/node_modules/hono/dist/cjs/hono-base.js +3 -2
- package/node_modules/hono/dist/cjs/jsx/base.js +27 -23
- package/node_modules/hono/dist/cjs/jsx/hooks/index.js +16 -13
- package/node_modules/hono/dist/cjs/middleware/cache/index.js +103 -8
- package/node_modules/hono/dist/cjs/middleware/compress/index.js +5 -0
- package/node_modules/hono/dist/cjs/middleware/cors/index.js +2 -2
- package/node_modules/hono/dist/cjs/middleware/etag/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +9 -4
- package/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +9 -4
- package/node_modules/hono/dist/cjs/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/cjs/middleware/method-not-allowed/index.js +90 -0
- package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/cjs/request.js +7 -9
- package/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +55 -56
- package/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +64 -85
- package/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +13 -5
- package/node_modules/hono/dist/cjs/router.js +1 -1
- package/node_modules/hono/dist/cjs/utils/accept.js +1 -1
- package/node_modules/hono/dist/cjs/utils/cookie.js +3 -2
- package/node_modules/hono/dist/cjs/utils/url.js +8 -8
- package/node_modules/hono/dist/context.js +28 -13
- package/node_modules/hono/dist/helper/proxy/index.js +4 -0
- package/node_modules/hono/dist/helper/streaming/sse.js +1 -1
- package/node_modules/hono/dist/hono-base.js +3 -2
- package/node_modules/hono/dist/jsx/base.js +27 -23
- package/node_modules/hono/dist/jsx/hooks/index.js +16 -13
- package/node_modules/hono/dist/middleware/cache/index.js +103 -8
- package/node_modules/hono/dist/middleware/compress/index.js +5 -0
- package/node_modules/hono/dist/middleware/cors/index.js +2 -2
- package/node_modules/hono/dist/middleware/etag/index.js +1 -1
- package/node_modules/hono/dist/middleware/jwk/jwk.js +9 -4
- package/node_modules/hono/dist/middleware/jwt/jwt.js +9 -4
- package/node_modules/hono/dist/middleware/language/language.js +10 -6
- package/node_modules/hono/dist/middleware/method-not-allowed/index.js +68 -0
- package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/request.js +8 -10
- package/node_modules/hono/dist/router/reg-exp-router/node.js +55 -56
- package/node_modules/hono/dist/router/reg-exp-router/router.js +64 -85
- package/node_modules/hono/dist/router/reg-exp-router/trie.js +13 -5
- package/node_modules/hono/dist/router.js +1 -1
- package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +9 -0
- package/node_modules/hono/dist/types/client/types.d.ts +1 -1
- package/node_modules/hono/dist/types/hono-base.d.ts +4 -3
- package/node_modules/hono/dist/types/jsx/base.d.ts +4 -2
- package/node_modules/hono/dist/types/jsx/dom/index.d.ts +5 -5
- package/node_modules/hono/dist/types/jsx/dom/intrinsic-element/components.d.ts +2 -2
- package/node_modules/hono/dist/types/jsx/dom/server.d.ts +5 -5
- package/node_modules/hono/dist/types/jsx/hooks/index.d.ts +8 -6
- package/node_modules/hono/dist/types/jsx/index.d.ts +5 -5
- package/node_modules/hono/dist/types/middleware/cache/index.d.ts +6 -4
- package/node_modules/hono/dist/types/middleware/cors/index.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +2 -2
- package/node_modules/hono/dist/types/middleware/jwk/jwk.d.ts +2 -0
- package/node_modules/hono/dist/types/middleware/jwt/jwt.d.ts +2 -0
- package/node_modules/hono/dist/types/middleware/method-not-allowed/index.d.ts +49 -0
- package/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +1 -1
- package/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +2 -1
- package/node_modules/hono/dist/types/router.d.ts +1 -1
- package/node_modules/hono/dist/types/utils/headers.d.ts +2 -2
- package/node_modules/hono/dist/types/utils/url.d.ts +1 -0
- package/node_modules/hono/dist/utils/accept.js +1 -1
- package/node_modules/hono/dist/utils/cookie.js +4 -3
- package/node_modules/hono/dist/utils/url.js +6 -7
- package/node_modules/hono/package.json +10 -3
- package/node_modules/ip-address/README.md +146 -126
- package/node_modules/ip-address/dist/common.d.ts +29 -0
- package/node_modules/ip-address/dist/common.js +44 -5
- package/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +8 -1
- package/node_modules/ip-address/dist/ipv4.js +24 -20
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +68 -3
- package/node_modules/ip-address/dist/ipv6.js +180 -53
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/dist/v4/constants.js +5 -1
- package/node_modules/ip-address/dist/v4/constants.js.map +1 -1
- package/node_modules/ip-address/dist/v6/constants.js +3 -2
- package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/ip-address/package.json +6 -4
- package/package.json +23 -11
- 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 +16 -40
- package/scripts/platform-smoke/platform-build-windows.ps1 +1 -1
- package/scripts/platform-smoke/render-ansi.mjs +1 -1
- package/scripts/platform-smoke/scenarios.mjs +1 -1
- package/scripts/platform-smoke/targets.mjs +2 -2
- package/scripts/platform-smoke.mjs +5 -5
- package/scripts/prepare.mjs +102 -0
- package/scripts/refresh-cursor-model-snapshots.mjs +16 -7
- 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/shared/cursor-model-selection-identities.d.mts +21 -0
- package/shared/cursor-model-selection-identities.mjs +95 -0
- package/src/bundled-context-windows.ts +21 -12
- package/src/context.ts +1 -1
- package/src/cursor-agents-context-registration.ts +2 -2
- package/src/cursor-agents-context.ts +0 -2
- package/src/cursor-api-key.ts +5 -4
- package/src/cursor-cloud-reporting.ts +23 -2
- package/src/cursor-context-tools.ts +1 -1
- package/src/cursor-display-only-trace.ts +1 -1
- package/src/cursor-fallback-models.generated.ts +1726 -824
- package/src/cursor-live-run-accounting.ts +1 -1
- package/src/cursor-live-run-coordinator.ts +2 -1
- package/src/cursor-native-replay-routing.ts +1 -1
- package/src/cursor-native-tool-display-registration.ts +10 -11
- package/src/cursor-partial-content-emitter.ts +1 -1
- package/src/cursor-pi-tool-bridge-mcp.ts +1 -1
- package/src/cursor-pi-tool-bridge-run.ts +1 -1
- package/src/cursor-pi-tool-bridge-types.ts +1 -1
- package/src/cursor-provider-errors.ts +1 -1
- package/src/cursor-provider-lazy.ts +6 -5
- package/src/cursor-provider-live-run-drain.ts +2 -1
- package/src/cursor-provider-overflow.ts +1 -1
- package/src/cursor-provider-run-finalizer.ts +2 -1
- package/src/cursor-provider-turn-coordinator.ts +1 -1
- package/src/cursor-provider-turn-finalize.ts +12 -0
- package/src/cursor-provider-turn-lifecycle-emitter.ts +1 -1
- package/src/cursor-provider-turn-prepare.ts +1 -1
- package/src/cursor-provider-turn-types.ts +3 -1
- package/src/cursor-provider.ts +1 -1
- package/src/cursor-run-final-text.ts +1 -1
- package/src/cursor-sdk-billed-usage.ts +107 -0
- package/src/cursor-sdk-event-debug.ts +1 -1
- 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-agent.ts +1 -1
- package/src/cursor-session-compaction-prep.ts +4 -0
- package/src/cursor-session-send-policy.ts +1 -1
- package/src/cursor-tool-manifest.ts +1 -1
- package/src/cursor-usage-accounting.ts +71 -10
- package/src/index.ts +1 -1
- package/src/model-discovery.ts +32 -89
- package/tsconfig.build.json +8 -0
- package/tsconfig.json +16 -0
- package/node_modules/cross-spawn/node_modules/which/CHANGELOG.md +0 -166
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Purpose: Produce the compiled runtime files that the Pi extension manifest loads.
|
|
4
|
+
* Responsibilities: Run TypeScript emit into a staging directory, then atomically swap it
|
|
5
|
+
* into dist/ so a failed TypeScript emit never destroys a previously working dist.
|
|
6
|
+
* Usage: `npm run build`; also invoked by scripts/prepare.mjs during install lifecycles.
|
|
7
|
+
* Invariants/Assumptions: `node_modules` provides `typescript`; deleting `dist/` is safe generated output.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execFile as execFileCallback } from "node:child_process";
|
|
11
|
+
import { existsSync } from "node:fs";
|
|
12
|
+
import { readdir, rename, rm } from "node:fs/promises";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import process from "node:process";
|
|
15
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
16
|
+
import { promisify } from "node:util";
|
|
17
|
+
|
|
18
|
+
const execFile = promisify(execFileCallback);
|
|
19
|
+
const RM_OPTIONS = { force: true, maxRetries: 5, recursive: true, retryDelay: 100 };
|
|
20
|
+
const RENAME_RETRY_LIMIT = 50;
|
|
21
|
+
const RENAME_RETRY_MS = 50;
|
|
22
|
+
// Run tsc's JS entrypoint directly through the current node binary: no .cmd shim,
|
|
23
|
+
// no shell, safe for install paths containing spaces on every platform.
|
|
24
|
+
const tscPath = join(process.cwd(), "node_modules", "typescript", "bin", "tsc");
|
|
25
|
+
|
|
26
|
+
async function discardStaging(path) {
|
|
27
|
+
try {
|
|
28
|
+
await rm(path, RM_OPTIONS);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
// Cleanup is always best-effort: it must not turn a successful race loss
|
|
31
|
+
// into failure or replace the compiler/publish error that matters.
|
|
32
|
+
console.warn(`could not remove staging ${path}: ${error?.message ?? error}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function isOwnerGone(pid) {
|
|
37
|
+
try {
|
|
38
|
+
process.kill(pid, 0);
|
|
39
|
+
return false;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
return error?.code === "ESRCH";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function hasPublishedDist(path) {
|
|
46
|
+
try {
|
|
47
|
+
return (await readdir(path)).length > 0;
|
|
48
|
+
} catch {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function reapStrandedStaging(cwd) {
|
|
54
|
+
// Signal 0 proves only that the owner was gone at probe time. Pid reuse
|
|
55
|
+
// between this probe and removal is inherent to pid-based reaping.
|
|
56
|
+
for (const entry of await readdir(cwd, { withFileTypes: true })) {
|
|
57
|
+
const match = /^dist\.staging\.(\d+)$/.exec(entry.name);
|
|
58
|
+
if (!match || !entry.isDirectory()) continue;
|
|
59
|
+
const ownerPid = Number(match[1]);
|
|
60
|
+
if (ownerPid === process.pid || !isOwnerGone(ownerPid)) continue;
|
|
61
|
+
await discardStaging(join(cwd, entry.name));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function compileToStaging(cwd, stagingDir) {
|
|
66
|
+
try {
|
|
67
|
+
const { stderr, stdout } = await execFile(
|
|
68
|
+
process.execPath,
|
|
69
|
+
[tscPath, "-p", "tsconfig.build.json", "--outDir", stagingDir],
|
|
70
|
+
{ cwd, maxBuffer: 10 * 1024 * 1024 },
|
|
71
|
+
);
|
|
72
|
+
if (stdout) process.stdout.write(stdout);
|
|
73
|
+
if (stderr) process.stderr.write(stderr);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
if (error?.stdout) process.stdout.write(error.stdout);
|
|
76
|
+
if (error?.stderr) process.stderr.write(error.stderr);
|
|
77
|
+
await discardStaging(stagingDir);
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function publishStaging(stagingDir, distDir) {
|
|
83
|
+
try {
|
|
84
|
+
// A failed dist removal must fail loudly; keep it outside the retry loop.
|
|
85
|
+
// Remove dist exactly once so retries never delete a concurrent winner.
|
|
86
|
+
await rm(distDir, RM_OPTIONS);
|
|
87
|
+
for (let retry = 0; ; retry++) {
|
|
88
|
+
try {
|
|
89
|
+
await rename(stagingDir, distDir);
|
|
90
|
+
return;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
// A completed staged build is non-empty; a bare directory is not proof
|
|
93
|
+
// that a concurrent publisher won the race.
|
|
94
|
+
if (await hasPublishedDist(distDir)) {
|
|
95
|
+
console.warn("dist/ was published by a concurrent build; discarding this build's staging tree.");
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// At most 50 retries (~2.5s) keep persistent filesystem errors bounded.
|
|
99
|
+
if (existsSync(stagingDir) && retry < RENAME_RETRY_LIMIT) {
|
|
100
|
+
await delay(RENAME_RETRY_MS);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
} finally {
|
|
107
|
+
// Safe after success too: rename moved stagingDir, so force makes this a no-op.
|
|
108
|
+
await discardStaging(stagingDir);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function main() {
|
|
113
|
+
const cwd = process.cwd();
|
|
114
|
+
if (!existsSync(tscPath)) throw new Error(`typescript is not installed at ${tscPath}; run npm install first.`);
|
|
115
|
+
await reapStrandedStaging(cwd);
|
|
116
|
+
// Pid-scoped staging isolates concurrent emits; only a complete tree publishes.
|
|
117
|
+
const stagingDir = join(cwd, `dist.staging.${process.pid}`);
|
|
118
|
+
await rm(stagingDir, RM_OPTIONS);
|
|
119
|
+
await compileToStaging(cwd, stagingDir);
|
|
120
|
+
await publishStaging(stagingDir, join(cwd, "dist"));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
main().catch((error) => {
|
|
124
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
125
|
+
process.exitCode = 1;
|
|
126
|
+
});
|
|
@@ -10,6 +10,7 @@ import { tmpdir } from "node:os";
|
|
|
10
10
|
import { dirname, join, resolve } from "node:path";
|
|
11
11
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
12
12
|
import { terminateChild } from "./lib/cursor-child-process.mjs";
|
|
13
|
+
import { ensureBuilt } from "./lib/ensure-built.mjs";
|
|
13
14
|
import { buildCursorSmokeEnv } from "./lib/cursor-smoke-env.mjs";
|
|
14
15
|
import {
|
|
15
16
|
checkpointCloudSmokeShutdown,
|
|
@@ -50,7 +51,7 @@ import { scrubSensitiveText } from "../shared/cursor-sensitive-text.mjs";
|
|
|
50
51
|
|
|
51
52
|
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
52
53
|
const EVIDENCE_PATH = join(root, "docs", "evidence", "cursor-cloud-smoke-matrix-latest.json");
|
|
53
|
-
const MODEL = "cursor/
|
|
54
|
+
const MODEL = "cursor/grok-4.6";
|
|
54
55
|
const CLOUD_RUN_ID_PATTERN = /^run-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
55
56
|
const cloudSmokeShutdown = createCloudSmokeShutdownController((child) => terminateChild(child, { graceMs: 15_000 }));
|
|
56
57
|
const argv = process.argv.slice(2);
|
|
@@ -614,6 +615,7 @@ async function main() {
|
|
|
614
615
|
}
|
|
615
616
|
|
|
616
617
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
618
|
+
ensureBuilt();
|
|
617
619
|
main().catch((error) => {
|
|
618
620
|
reportFailure(error);
|
|
619
621
|
process.exit(1);
|
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
} from "./lib/cursor-child-process.mjs";
|
|
24
24
|
import { scrubSensitiveText } from "../shared/cursor-sensitive-text.mjs";
|
|
25
25
|
import { createScriptFail } from "./lib/cursor-script-fail.mjs";
|
|
26
|
+
import { ensureBuilt } from "./lib/ensure-built.mjs";
|
|
26
27
|
import { serializeCursorSettingSources } from "../shared/cursor-setting-sources.mjs";
|
|
27
28
|
|
|
28
29
|
function isMainModule() {
|
|
@@ -35,7 +36,7 @@ function isMainModule() {
|
|
|
35
36
|
const require = createRequire(import.meta.url);
|
|
36
37
|
const root = fileURLToPath(new URL("..", import.meta.url));
|
|
37
38
|
const packageJson = require("../package.json");
|
|
38
|
-
const DEFAULT_MODEL = "cursor/
|
|
39
|
+
const DEFAULT_MODEL = "cursor/grok-4.6";
|
|
39
40
|
const DEFAULT_OUT_BASE = ".debug/cursor-sdk-events";
|
|
40
41
|
const SDK_EVENT_DEBUG_LOG_PREFIX = "[pi-cursor-sdk:sdk-events]";
|
|
41
42
|
const PI_SESSION_SNAPSHOT_ARTIFACT = "pi-session-snapshot.jsonl";
|
|
@@ -301,6 +302,7 @@ async function main(argv = process.argv.slice(2), env = process.env) {
|
|
|
301
302
|
printHelp();
|
|
302
303
|
return;
|
|
303
304
|
}
|
|
305
|
+
ensureBuilt();
|
|
304
306
|
console.log(JSON.stringify(await runDebugProviderEvents(args, env)));
|
|
305
307
|
}
|
|
306
308
|
|
|
@@ -39,7 +39,7 @@ const ARTIFACTS = {
|
|
|
39
39
|
summary: "summary.json",
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const DEFAULT_MODEL = "
|
|
42
|
+
const DEFAULT_MODEL = "grok-4.6";
|
|
43
43
|
const RAW_ARTIFACT_WARNING =
|
|
44
44
|
"Raw artifact files may contain local paths, project text, tool args/results, or secrets from the workspace. Do not commit or share them.";
|
|
45
45
|
|
|
@@ -134,7 +134,7 @@ run_self_test() {
|
|
|
134
134
|
env_capture="$temp_dir/fake-pi.env"
|
|
135
135
|
cat >"$fake_pi" <<EOF_SELFTEST_PI
|
|
136
136
|
#!/usr/bin/env node
|
|
137
|
-
|
|
137
|
+
import { writeFileSync } from "node:fs";
|
|
138
138
|
writeFileSync("$env_capture", Object.entries(process.env).map(([key, value]) => key + "=" + (value ?? "")).join("\\n") + "\\n", "utf8");
|
|
139
139
|
EOF_SELFTEST_PI
|
|
140
140
|
cat >"$fake_node" <<EOF_SELFTEST_NODE
|
|
@@ -359,13 +359,14 @@ log "check: list-models"
|
|
|
359
359
|
LIST_OUT="$ISOLATED/list-models.txt"
|
|
360
360
|
run_in_dir_capture_combined "list-models" 30 "$PROJECT_DIR" "$LIST_OUT" "${PI_CURSOR_ENV[@]}" \
|
|
361
361
|
"$PI_BIN" --approve --cursor-no-fast --list-models cursor
|
|
362
|
+
"$RG_BIN" -q "grok-4\\.6" "$LIST_OUT" || fail "grok-4.6 not listed (see $LIST_OUT)"
|
|
362
363
|
"$RG_BIN" -q "composer-2\\.5|composer-2-5" "$LIST_OUT" || fail "composer-2-5 not listed (see $LIST_OUT)"
|
|
363
364
|
|
|
364
365
|
log "check: basic provider prompt"
|
|
365
366
|
BASIC_DIR="$SESSION_ROOT/basic"
|
|
366
367
|
mkdir -p "$BASIC_DIR"
|
|
367
368
|
run_in_dir_capture_split "basic prompt" "$PI_LIVE_TIMEOUT" "$PROJECT_DIR" "$ISOLATED/basic.stdout.txt" "$ISOLATED/basic.stderr.txt" "${PI_CURSOR_ENV[@]}" \
|
|
368
|
-
"$PI_BIN" --approve --cursor-no-fast --model cursor/
|
|
369
|
+
"$PI_BIN" --approve --cursor-no-fast --model cursor/grok-4.6 --session-dir "$BASIC_DIR" --no-tools -p 'Reply exactly: PI_CURSOR_ISOLATED_OK'
|
|
369
370
|
"$RG_BIN" -q "PI_CURSOR_ISOLATED_OK" "$ISOLATED/basic.stdout.txt" || fail "basic prompt missing PI_CURSOR_ISOLATED_OK"
|
|
370
371
|
validate_replay_jsonl "$BASIC_DIR"
|
|
371
372
|
|
|
@@ -373,14 +374,14 @@ log "check: native replay"
|
|
|
373
374
|
REPLAY_DIR="$SESSION_ROOT/native-replay"
|
|
374
375
|
mkdir -p "$REPLAY_DIR"
|
|
375
376
|
run_in_dir_capture_split "native replay" "$PI_LIVE_TIMEOUT" "$PROJECT_DIR" "$ISOLATED/replay.stdout.txt" "$ISOLATED/replay.stderr.txt" "${PI_CURSOR_ENV[@]}" PI_CURSOR_NATIVE_TOOL_DISPLAY=1 \
|
|
376
|
-
"$PI_BIN" --approve --cursor-no-fast --model cursor/
|
|
377
|
+
"$PI_BIN" --approve --cursor-no-fast --model cursor/grok-4.6 --session-dir "$REPLAY_DIR" -p 'Read ./README.md briefly, then answer README_SEEN=yes if it mentions pi-cursor-sdk.'
|
|
377
378
|
validate_replay_jsonl "$REPLAY_DIR"
|
|
378
379
|
|
|
379
380
|
log "check: plan-strip shim (plan-mode execute reset)"
|
|
380
381
|
PLAN_DIR="$SESSION_ROOT/plan-strip"
|
|
381
382
|
mkdir -p "$PLAN_DIR"
|
|
382
383
|
run_in_dir_capture_split "plan-strip replay" "$PI_LIVE_TIMEOUT" "$PROJECT_DIR" "$ISOLATED/plan.stdout.txt" "$ISOLATED/plan.stderr.txt" "${PI_CURSOR_ENV[@]}" PI_CURSOR_NATIVE_TOOL_DISPLAY=1 \
|
|
383
|
-
"$PI_BIN" --approve -e "$SHIM_DIR" --cursor-no-fast --model cursor/
|
|
384
|
+
"$PI_BIN" --approve -e "$SHIM_DIR" --cursor-no-fast --model cursor/grok-4.6 --session-dir "$PLAN_DIR" -p 'After reset, read README.md and answer PLAN_STRIP_OK=yes.'
|
|
384
385
|
validate_replay_jsonl "$PLAN_DIR"
|
|
385
386
|
|
|
386
387
|
log "PASS isolated install smoke: $ISOLATED"
|
|
@@ -360,7 +360,7 @@ function buildCloudSmokeMatrixEvidence(input, laneProjector, allowDefaultTimesta
|
|
|
360
360
|
} = data;
|
|
361
361
|
const timestamp = data.timestamp ?? (allowDefaultTimestamp ? new Date().toISOString() : undefined);
|
|
362
362
|
if (schemaVersion !== 1) fail("cloud smoke evidence schemaVersion must be 1");
|
|
363
|
-
if (model !== "cursor/
|
|
363
|
+
if (model !== "cursor/grok-4.6") fail("cloud smoke evidence model must be cursor/grok-4.6");
|
|
364
364
|
if (!Array.isArray(lanes) || lanes.length !== LANE_NAMES.length) fail("cloud smoke evidence lanes must contain the complete required matrix");
|
|
365
365
|
if (!Array.isArray(cleanup) || cleanup.length === 0) fail("cloud smoke evidence cleanup must be a non-empty array");
|
|
366
366
|
const projectedLanes = lanes.map((lane, index) => laneProjector(lane, index));
|
|
@@ -66,7 +66,7 @@ header code { color: #d8dee9; }
|
|
|
66
66
|
<header>
|
|
67
67
|
<div><strong>pi-cursor-sdk visual smoke</strong> <code>${escapeHtml(options.label)}</code></div>
|
|
68
68
|
<div>model <code>${escapeHtml(options.model)}</code> · mode <code>${escapeHtml(options.mode)}</code> · cwd <code>${escapeHtml(options.cwd)}</code></div>
|
|
69
|
-
<div>session <code>${escapeHtml(options.sessionId)}</code> · captured ${new Date().toISOString()}</div>
|
|
69
|
+
<div>session <code>${escapeHtml(options.sessionId ?? "pi-assigned")}</code> · captured ${new Date().toISOString()}</div>
|
|
70
70
|
</header>
|
|
71
71
|
<div id="terminal"></div>
|
|
72
72
|
<noscript><pre class="fallback">${escapeHtml(plain)}</pre></noscript>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rebuild dist/ before a launcher loads the repo-root extension, so direct
|
|
3
|
+
* `node scripts/<launcher>.mjs` invocations can never exercise stale code.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
export function ensureBuilt() {
|
|
10
|
+
execFileSync(process.execPath, [fileURLToPath(new URL("../build.mjs", import.meta.url))], {
|
|
11
|
+
// build.mjs anchors tsc/dist/staging to its cwd; pin it to the repo root so
|
|
12
|
+
// direct launcher invocations work from any directory.
|
|
13
|
+
cwd: fileURLToPath(new URL("../..", import.meta.url)),
|
|
14
|
+
stdio: "inherit",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
@@ -152,7 +152,7 @@ export function startRpc({
|
|
|
152
152
|
baseEnv = process.env,
|
|
153
153
|
}) {
|
|
154
154
|
const model =
|
|
155
|
-
process.env.CURSOR_LOCAL_RESUME_SMOKE_MODEL || "cursor/
|
|
155
|
+
process.env.CURSOR_LOCAL_RESUME_SMOKE_MODEL || "cursor/grok-4.6:slow";
|
|
156
156
|
const workspaceDir = join(artifactDir, "workspace");
|
|
157
157
|
mkdirSync(workspaceDir, { recursive: true });
|
|
158
158
|
const pi = findPiCommand();
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
withRpc,
|
|
27
27
|
writeTreeCommandExtension,
|
|
28
28
|
} from "./lib/local-resume-smoke-harness.mjs";
|
|
29
|
+
import { ensureBuilt } from "./lib/ensure-built.mjs";
|
|
29
30
|
import { runCleanupSmoke } from "./local-resume-cleanup-smoke.mjs";
|
|
30
31
|
import { writePlatformArtifactBundle } from "./platform-smoke/artifacts.mjs";
|
|
31
32
|
import { LOCAL_RESUME_SUITES } from "./platform-smoke/local-resume-suites.mjs";
|
|
@@ -45,7 +46,7 @@ ${npmUsage}
|
|
|
45
46
|
${nodeUsage}
|
|
46
47
|
|
|
47
48
|
Environment:
|
|
48
|
-
CURSOR_LOCAL_RESUME_SMOKE_MODEL Cursor model id (default: cursor/
|
|
49
|
+
CURSOR_LOCAL_RESUME_SMOKE_MODEL Cursor model id (default: cursor/grok-4.6:slow).
|
|
49
50
|
CURSOR_LOCAL_RESUME_SMOKE_TIMEOUT_MS Timeout in ms per model turn (default: 300000).
|
|
50
51
|
CURSOR_LOCAL_RESUME_SMOKE_KEEP_ARTIFACTS Keep temp artifacts when set to 1.
|
|
51
52
|
CURSOR_LOCAL_RESUME_SMOKE_EXTENSION_PATH Packed extension path override (platform runner only).
|
|
@@ -627,6 +628,7 @@ function selectedRun() {
|
|
|
627
628
|
}
|
|
628
629
|
|
|
629
630
|
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
631
|
+
ensureBuilt();
|
|
630
632
|
const run = selectedRun();
|
|
631
633
|
run()
|
|
632
634
|
.catch((error) => {
|
|
@@ -31,7 +31,7 @@ const CARD_PATTERNS = [
|
|
|
31
31
|
{ id: "bridge-read-failure", pattern: /^\s*(?:read \.\/definitely-missing-platform-smoke-file\.txt|ENOENT: no such file)\s*/i },
|
|
32
32
|
{ id: "bridge-shell-success", pattern: /^\s*bridge visual smoke\s*$/i },
|
|
33
33
|
{ id: "http1-status", pattern: /\bcursor:local\b.*\bhttp1\b/i },
|
|
34
|
-
{ id: "footer-status", pattern: /\bcomposer-2-5\b|\bcomposer-2\.5\b/i },
|
|
34
|
+
{ id: "footer-status", pattern: /\bgrok-4\.6\b|\bcomposer-2-5\b|\bcomposer-2\.5\b/i },
|
|
35
35
|
];
|
|
36
36
|
|
|
37
37
|
function cleanLine(line) {
|
|
@@ -17,9 +17,8 @@ import { redactSecrets, writePlatformArtifactBundle } from "./artifacts.mjs";
|
|
|
17
17
|
import { extractContentText, jsonlHasAssistantFinalTextMarker } from "./jsonl-text.mjs";
|
|
18
18
|
import { getScenario, renderPrompt } from "./scenarios.mjs";
|
|
19
19
|
|
|
20
|
-
const DEFAULT_MODEL = "cursor/
|
|
20
|
+
const DEFAULT_MODEL = "cursor/grok-4.6";
|
|
21
21
|
const DEFAULT_WAIT_MS = 240_000;
|
|
22
|
-
const READY_WAIT_MS = 45_000;
|
|
23
22
|
const SESSION_JSONL_WAIT_MS = 60_000;
|
|
24
23
|
const COLS = 150;
|
|
25
24
|
const ROWS = 45;
|
|
@@ -242,25 +241,10 @@ function stripANSI(text) {
|
|
|
242
241
|
return text.replace(/\x1b\[[0-9;?]*[ -/]*[@-~]/g, "").replace(/\x1b\][^\x07]*(?:\x07|\x1b\\)/g, "");
|
|
243
242
|
}
|
|
244
243
|
|
|
245
|
-
function
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function shellQuote(value) {
|
|
250
|
-
return `'${String(value).replace(/'/g, `'\\''`)}'`;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function ptySpawnCommand(piCli, args) {
|
|
254
|
-
if (process.platform !== "win32") {
|
|
255
|
-
return {
|
|
256
|
-
file: "/bin/bash",
|
|
257
|
-
args: ["-lc", ["exec", shellQuote(piCli), ...args.map(shellQuote)].join(" ")],
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
return {
|
|
261
|
-
file: "powershell.exe",
|
|
262
|
-
args: ["-NoLogo", "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", ["&", psQuote(piCli), ...args.map(psQuote)].join(" ")],
|
|
263
|
-
};
|
|
244
|
+
function ptySpawnCommand(args) {
|
|
245
|
+
const cliEntry = resolve(process.cwd(), "node_modules", "@earendil-works", "pi-coding-agent", "dist", "cli.js");
|
|
246
|
+
if (!existsSync(cliEntry)) throw new Error(`Pi CLI entry not found: ${cliEntry}`);
|
|
247
|
+
return { file: process.execPath, args: [cliEntry, ...args] };
|
|
264
248
|
}
|
|
265
249
|
|
|
266
250
|
async function waitForSessionJsonl(sessionDir, finalMarker, startedAt, events) {
|
|
@@ -285,7 +269,7 @@ async function waitForSessionJsonl(sessionDir, finalMarker, startedAt, events) {
|
|
|
285
269
|
return files;
|
|
286
270
|
}
|
|
287
271
|
|
|
288
|
-
async function runPtyPi({ artifactDir,
|
|
272
|
+
async function runPtyPi({ artifactDir, ptyCommand, env, cwd, sessionDir, finalMarker, waitMs, abortMode, scenario }) {
|
|
289
273
|
let pty;
|
|
290
274
|
try {
|
|
291
275
|
pty = await import("node-pty");
|
|
@@ -297,8 +281,7 @@ async function runPtyPi({ artifactDir, piCli, piArgs, env, cwd, sessionDir, prom
|
|
|
297
281
|
let plain = "";
|
|
298
282
|
const events = [];
|
|
299
283
|
const startedAt = Date.now();
|
|
300
|
-
const { file, args } =
|
|
301
|
-
writeFileSync(join(artifactDir, "pty-spawn-command.json"), JSON.stringify({ file, args, cwd, fileExists: existsSync(file), cwdExists: existsSync(cwd) }, null, 2));
|
|
284
|
+
const { file, args } = ptyCommand;
|
|
302
285
|
let child;
|
|
303
286
|
try {
|
|
304
287
|
child = pty.spawn(file, args, {
|
|
@@ -322,15 +305,7 @@ async function runPtyPi({ artifactDir, piCli, piArgs, env, cwd, sessionDir, prom
|
|
|
322
305
|
events.push({ type: "exit", elapsedMs: Date.now() - startedAt, code: event.exitCode, signal: event.signal });
|
|
323
306
|
});
|
|
324
307
|
|
|
325
|
-
const
|
|
326
|
-
while (!/(?:composer-2-5|escape interrupt|ctrl\+c\/ctrl\+d)/i.test(plain) && Date.now() - readyStartedAt < READY_WAIT_MS) {
|
|
327
|
-
await delay(500);
|
|
328
|
-
}
|
|
329
|
-
events.push({ type: "ready_wait_finished", elapsedMs: Date.now() - startedAt, ready: /(?:composer-2-5|escape interrupt|ctrl\+c\/ctrl\+d)/i.test(plain) });
|
|
330
|
-
child.write(`\x1b[200~${prompt}\x1b[201~\r`);
|
|
331
|
-
events.push({ type: "prompt_sent", elapsedMs: Date.now() - startedAt, bytes: prompt.length });
|
|
332
|
-
await delay(1_000);
|
|
333
|
-
const responseStartOffset = plain.length;
|
|
308
|
+
const responseStartOffset = 0;
|
|
334
309
|
events.push({ type: "response_watch_started", elapsedMs: Date.now() - startedAt, offset: responseStartOffset });
|
|
335
310
|
|
|
336
311
|
let observed = false;
|
|
@@ -572,6 +547,7 @@ async function main() {
|
|
|
572
547
|
const suiteEnv = {
|
|
573
548
|
...process.env,
|
|
574
549
|
...scenario.env,
|
|
550
|
+
PI_OFFLINE: "1",
|
|
575
551
|
...(args.suite === "cursor-abort-cleanup" ? { PLATFORM_ABORT_MARKER: "SHOULD_NOT_PRINT" } : {}),
|
|
576
552
|
PI_CODING_AGENT_DIR: agentDir,
|
|
577
553
|
PI_CURSOR_SDK_EVENT_DEBUG_DIR: debugDir,
|
|
@@ -581,21 +557,21 @@ async function main() {
|
|
|
581
557
|
if (args.suite === "cursor-abort-cleanup") writeProcessSnapshot(logDir, "process-before", platform);
|
|
582
558
|
const prompt = renderPrompt(scenario, platform);
|
|
583
559
|
writeFileSync(join(artifactDir, "prompt.txt"), prompt);
|
|
584
|
-
const piArgs = ["--approve", "--cursor-no-fast", "--cursor-mode", "agent", "--model", args.model, "--session-dir", sessionDir, "--session-id", `platform-${args.suite}-${Date.now()}
|
|
560
|
+
const piArgs = ["--approve", "--cursor-no-fast", "--cursor-mode", "agent", "--model", args.model, "--session-dir", sessionDir, "--session-id", `platform-${args.suite}-${Date.now()}`, prompt];
|
|
561
|
+
const ptyCommand = ptySpawnCommand(piArgs);
|
|
585
562
|
writeFileSync(join(artifactDir, "pi-command.json"), JSON.stringify({
|
|
586
|
-
|
|
587
|
-
args: piArgs,
|
|
563
|
+
...ptyCommand,
|
|
588
564
|
cwd: workspaceDir,
|
|
589
|
-
|
|
565
|
+
fileExists: existsSync(ptyCommand.file),
|
|
566
|
+
cwdExists: existsSync(workspaceDir),
|
|
567
|
+
env: Object.fromEntries(Object.entries(suiteEnv).filter(([key]) => key.startsWith("PI_CURSOR_") || key === "PI_CODING_AGENT_DIR" || key === "PI_OFFLINE" || key === "TERM")),
|
|
590
568
|
}, null, 2));
|
|
591
569
|
const ptyResult = await runPtyPi({
|
|
592
570
|
artifactDir,
|
|
593
|
-
|
|
594
|
-
piArgs,
|
|
571
|
+
ptyCommand,
|
|
595
572
|
env: suiteEnv,
|
|
596
573
|
cwd: workspaceDir,
|
|
597
574
|
sessionDir,
|
|
598
|
-
prompt,
|
|
599
575
|
finalMarker: scenario.finalMarker,
|
|
600
576
|
waitMs: args.waitMs,
|
|
601
577
|
abortMode: args.suite === "cursor-abort-cleanup",
|
|
@@ -62,7 +62,7 @@ Write-SectionFile "NPM_CI_STDOUT" $NpmCiOut
|
|
|
62
62
|
Write-SectionFile "NPM_CI_STDERR" $NpmCiErr
|
|
63
63
|
|
|
64
64
|
Write-Output "=== check:platform-smoke ==="
|
|
65
|
-
& npm.cmd run check:platform-smoke 1> $CheckPlatformSmokeOut 2> $CheckPlatformSmokeErr
|
|
65
|
+
& npm.cmd run check:platform-smoke -- --testTimeout=15000 1> $CheckPlatformSmokeOut 2> $CheckPlatformSmokeErr
|
|
66
66
|
$CHECK_PLATFORM_SMOKE_EXIT = Exit-CodeFromLastCommand
|
|
67
67
|
Write-Output "PLATFORM_CHECK_PLATFORM_SMOKE_EXIT=$CHECK_PLATFORM_SMOKE_EXIT"
|
|
68
68
|
Write-SectionFile "CHECK_PLATFORM_SMOKE_STDOUT" $CheckPlatformSmokeOut
|
|
@@ -27,7 +27,7 @@ export async function renderHTML(ansiPath, htmlPath, options = {}) {
|
|
|
27
27
|
plain,
|
|
28
28
|
options: {
|
|
29
29
|
label: options.label ?? "platform-smoke",
|
|
30
|
-
model: options.model ?? "cursor/
|
|
30
|
+
model: options.model ?? "cursor/grok-4.6",
|
|
31
31
|
mode: options.mode ?? "agent",
|
|
32
32
|
cwd: options.cwd ?? process.cwd(),
|
|
33
33
|
sessionId: options.sessionId ?? "platform-smoke",
|
|
@@ -108,7 +108,7 @@ NATIVE_MATRIX_OK package=<name> grep=<yes/no> find=<yes/no> list=<yes/no> shell=
|
|
|
108
108
|
PI_CURSOR_EXPOSE_BUILTIN_TOOLS: "0",
|
|
109
109
|
PI_CURSOR_SDK_EVENT_DEBUG: "1",
|
|
110
110
|
},
|
|
111
|
-
promptTemplate: "
|
|
111
|
+
promptTemplate: "Join HTTP1, LIVE, and OK with underscores and reply with only the result.",
|
|
112
112
|
finalMarker: "HTTP1_LIVE_OK",
|
|
113
113
|
requiredCards: ["http1-status"],
|
|
114
114
|
},
|
|
@@ -413,7 +413,7 @@ export function buildPlatformBuildCommand(targetName, packageName = "pi-cursor-s
|
|
|
413
413
|
lines.push(...posixSection("CHECK_PLATFORM_SMOKE_STDERR", 'cat "$PACK_DIR/check-platform-smoke.stderr.txt" 2>/dev/null || true'));
|
|
414
414
|
lines.push("");
|
|
415
415
|
lines.push('echo "=== npm test ==="');
|
|
416
|
-
lines.push('npm test >"$PACK_DIR/npm-test.stdout.txt" 2>"$PACK_DIR/npm-test.stderr.txt"');
|
|
416
|
+
lines.push('npm test -- --testTimeout=15000 >"$PACK_DIR/npm-test.stdout.txt" 2>"$PACK_DIR/npm-test.stderr.txt"');
|
|
417
417
|
lines.push("TEST_EXIT=$?");
|
|
418
418
|
lines.push('echo "PLATFORM_NPM_TEST_EXIT=$TEST_EXIT"');
|
|
419
419
|
lines.push(...posixSection("NPM_TEST_STDOUT", 'cat "$PACK_DIR/npm-test.stdout.txt" 2>/dev/null || true'));
|
|
@@ -662,7 +662,7 @@ async function executeLiveSuite(config, targetName, suiteName, suiteDir, slug, l
|
|
|
662
662
|
}
|
|
663
663
|
|
|
664
664
|
function buildLiveSuiteCommand(config, targetName, suiteName, prepDir) {
|
|
665
|
-
const model = config.cursorModel ?? "cursor/
|
|
665
|
+
const model = config.cursorModel ?? "cursor/grok-4.6";
|
|
666
666
|
const packageName = config.packageName ?? "pi-cursor-sdk";
|
|
667
667
|
const prepArgs = prepDir ? ` --prep-dir ${platformFor(targetName) === "powershell" ? prepDir : shellQuote(prepDir)}` : "";
|
|
668
668
|
if (platformFor(targetName) === "powershell") {
|
|
@@ -28,7 +28,7 @@ function printHelp() {
|
|
|
28
28
|
|
|
29
29
|
Commands:
|
|
30
30
|
doctor Run all preflight checks (no Cursor tokens)
|
|
31
|
-
run --target <names> Run one or more comma-separated targets
|
|
31
|
+
run --target <names> Run one or more comma-separated targets sequentially
|
|
32
32
|
run --suite <name> Run one suite on all or specified targets
|
|
33
33
|
run --target <n> --suite <n>
|
|
34
34
|
|
|
@@ -242,14 +242,14 @@ async function main() {
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
const startedAt = new Date().toISOString();
|
|
245
|
-
const
|
|
245
|
+
const results = [];
|
|
246
|
+
for (const targetName of targets) {
|
|
246
247
|
console.log(`\n=== Target: ${targetName} ===`);
|
|
247
248
|
const result = args.suite
|
|
248
249
|
? await runSuite(targetName, suites[0])
|
|
249
250
|
: await runTarget(targetName, suites);
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
const results = await Promise.all(targetRuns);
|
|
251
|
+
results.push({ targetName, result });
|
|
252
|
+
}
|
|
253
253
|
const finishedAt = new Date().toISOString();
|
|
254
254
|
const latest = writeLatestPlatformSmokeIndex(config, results, {
|
|
255
255
|
startedAt,
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Purpose: Build generated dist output for GitHub/source installs even when Pi invokes npm install --omit=dev.
|
|
4
|
+
* Responsibilities: Detect missing source-build dependencies via the local node_modules tree, install dev
|
|
5
|
+
* dependencies with lifecycle scripts disabled, run the canonical build, then prune the dev tree so installs
|
|
6
|
+
* keep a runtime-only footprint.
|
|
7
|
+
* Scope: Package install lifecycle only; runtime behavior remains owned by scripts/build.mjs.
|
|
8
|
+
* Usage: package.json prepare script.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { execFile as execFileCallback } from "node:child_process";
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { join } from "node:path";
|
|
14
|
+
import process from "node:process";
|
|
15
|
+
import { promisify } from "node:util";
|
|
16
|
+
|
|
17
|
+
const execFile = promisify(execFileCallback);
|
|
18
|
+
|
|
19
|
+
// Checked as literal node_modules paths: require.resolve() is unusable here because
|
|
20
|
+
// several @earendil-works packages expose import-only "exports" maps and throw
|
|
21
|
+
// ERR_PACKAGE_PATH_NOT_EXPORTED even when installed.
|
|
22
|
+
const REQUIRED_SOURCE_BUILD_MODULES = [
|
|
23
|
+
"typescript",
|
|
24
|
+
"typebox",
|
|
25
|
+
"@earendil-works/pi-ai",
|
|
26
|
+
"@earendil-works/pi-coding-agent",
|
|
27
|
+
"@earendil-works/pi-tui",
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
function hasBuildDependencies() {
|
|
31
|
+
return REQUIRED_SOURCE_BUILD_MODULES.every((moduleName) =>
|
|
32
|
+
existsSync(join(process.cwd(), "node_modules", ...moduleName.split("/"), "package.json")),
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function runNpm(args) {
|
|
37
|
+
const npmExecPath = process.env.npm_execpath;
|
|
38
|
+
if (!npmExecPath) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`npm_execpath is not set; run "npm ${args.join(" ")}" manually in ${process.cwd()} and retry.`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
// No shell: process.execPath runs npm's cli.js directly, which is safe for paths
|
|
44
|
+
// containing spaces on every platform (shell:true concatenates args unescaped).
|
|
45
|
+
await execFile(process.execPath, [npmExecPath, ...args], {
|
|
46
|
+
cwd: process.cwd(),
|
|
47
|
+
maxBuffer: 20 * 1024 * 1024,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function runBuild() {
|
|
52
|
+
const { stderr, stdout } = await execFile(process.execPath, [join(process.cwd(), "scripts", "build.mjs")], {
|
|
53
|
+
cwd: process.cwd(),
|
|
54
|
+
maxBuffer: 20 * 1024 * 1024,
|
|
55
|
+
});
|
|
56
|
+
// Forward build output on success too: install-time diagnostics such as the
|
|
57
|
+
// concurrent-swap race-loss warning are otherwise swallowed.
|
|
58
|
+
if (stdout) process.stdout.write(stdout);
|
|
59
|
+
if (stderr) process.stderr.write(stderr);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function pruneDevDependencies() {
|
|
63
|
+
await runNpm(["prune", "--omit=dev", "--ignore-scripts"]);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function pruneQuietly() {
|
|
67
|
+
try {
|
|
68
|
+
await pruneDevDependencies();
|
|
69
|
+
} catch (error) {
|
|
70
|
+
console.warn(`npm prune failed after a failed build: ${error?.message ?? error}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function reportError(error) {
|
|
75
|
+
if (error?.stdout) process.stdout.write(error.stdout);
|
|
76
|
+
if (error?.stderr) process.stderr.write(error.stderr);
|
|
77
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function main() {
|
|
81
|
+
if (hasBuildDependencies()) {
|
|
82
|
+
await runBuild();
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
await runNpm(["install", "--include=dev", "--ignore-scripts"]);
|
|
86
|
+
try {
|
|
87
|
+
await runBuild();
|
|
88
|
+
} catch (buildError) {
|
|
89
|
+
// Report the build first; cleanup can warn afterward but never mask it.
|
|
90
|
+
reportError(buildError);
|
|
91
|
+
await pruneQuietly();
|
|
92
|
+
process.exitCode = 1;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// A prune failure after a successful build still fails the install.
|
|
96
|
+
await pruneDevDependencies();
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
main().catch((error) => {
|
|
100
|
+
reportError(error);
|
|
101
|
+
process.exitCode = 1;
|
|
102
|
+
});
|