pi-oracle 0.7.5 → 0.7.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 CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.7.6 - 2026-06-04
6
+
7
+ ### Changed
8
+ - updated the local pi development baseline to `@earendil-works/pi-coding-agent` / `@earendil-works/pi-ai` `0.78.1` and regenerated the npm lockfile
9
+ - documented `pi` `0.78.1+` as the suggested tested floor while keeping pi runtime packages as optional wildcard peers so newer pi releases are not blocked by npm peer ranges
10
+ - added Ant Ling, NVIDIA NIM, and MiniMax China provider env mappings to the oracle real-smoke/platform-smoke provider metadata
11
+
12
+ ### Fixed
13
+ - made startup poller and wake-up routing mode-aware with Pi 0.78.1 `ctx.mode`, so print and JSON one-shot runs do not start background pollers or publish oracle UI status
14
+ - guarded oracle startup status and warning notifications with `ctx.hasUI` for non-UI modes
15
+
16
+ ### Compatibility
17
+ - reviewed the pi `0.78.1` changelog, extension docs, package docs, prompt-template docs, and matching examples; the oracle extension remains compatible with current extension lifecycle and package install/update behavior
18
+
5
19
  ## 0.7.5 - 2026-06-02
6
20
 
7
21
  ### Added
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  `pi-oracle` lets a `pi` agent send hard, long-running work to ChatGPT.com or Grok through the web app, with repo archives, background execution, saved results, and a best-effort wake-up back into `pi` when the answer is ready.
4
4
 
5
- > Status: experimental public beta. Validated on macOS, Linux, and Windows native with Chromium-family browsers and the current pi package baseline. Pi-bundled runtime packages are optional wildcard peers so npm peer ranges do not block users from trying newer pi releases, though runtime behavior is only verified against the tested baseline until a follow-up package release confirms it. Normal oracle jobs run in an isolated browser profile, not your active browser window.
5
+ > Status: experimental public beta. Validated on macOS, Linux, and Windows native with Chromium-family browsers and pi `0.78.1`. Pi `0.78.1+` is the suggested tested floor for mode-aware background polling, but pi-bundled runtime packages remain optional wildcard peers so npm peer ranges do not block users from trying newer pi releases. Normal oracle jobs run in an isolated browser profile, not your active browser window.
6
6
 
7
7
  ## What a successful run looks like
8
8
 
@@ -77,7 +77,7 @@ You need:
77
77
 
78
78
  - macOS, Linux, or Windows native
79
79
  - Node.js 22 or newer
80
- - `pi` 0.65.0 or newer
80
+ - Suggested tested floor: `pi` 0.78.1 or newer; older pi versions are not blocked by package metadata but are outside the current validation baseline
81
81
  - Google Chrome/Chromium or another Chromium-family browser
82
82
  - ChatGPT or Grok already signed in to the configured local browser profile for the provider you plan to use
83
83
  - `agent-browser`, `tar`, and `zstd` available on the machine
@@ -383,12 +383,13 @@ Use the narrowest validation workflow that proves the change:
383
383
  | --- | --- |
384
384
  | Everyday local iteration | `npm run verify:oracle` |
385
385
  | Platform-sensitive changes | `npm run smoke:platform:doctor`, then a focused `node scripts/platform-smoke.mjs run --target <target> --suite <suite>` |
386
- | Publish/release proof | `npm run smoke:platform:all` |
386
+ | Platform matrix proof | `npm run smoke:platform:all` |
387
+ | Publish/release gate | `npm run release:check` |
387
388
 
388
- For macOS, Ubuntu, and Windows native package/build plus packed runtime validation, use [`docs/platform-smoke.md`](docs/platform-smoke.md). The full release proof is:
389
+ For macOS, Ubuntu, and Windows native package/build plus packed runtime validation, use [`docs/platform-smoke.md`](docs/platform-smoke.md). The full release gate is:
389
390
 
390
391
  ```bash
391
- npm run smoke:platform:all
392
+ npm run release:check
392
393
  ```
393
394
 
394
395
  The real runtime suite defaults to deterministic installed-tool execution so platform proof stays bounded. Provider/model defaults remain `zai/glm-5.1` for doctor/config and for optional model-agent debugging; override with `PI_ORACLE_REAL_TEST_PROVIDER` and `PI_ORACLE_REAL_TEST_MODEL` when needed. For inner-loop source loading only, use `npm run smoke:real:source`; it is not release proof. Set `PI_ORACLE_REAL_TEST_MODEL_AGENT=1` only when debugging the slower model-agent path. The optional second real-agent negative symlink check is opt-in via `PI_ORACLE_REAL_TEST_NEGATIVE_SYMLINK=1`; `npm run sanity:oracle` covers archive/symlink rejection by default without adding another model-agent turn to the platform release gate.
@@ -1,13 +1,14 @@
1
1
  # pi-oracle design
2
2
 
3
- Status: isolated-profile concurrency architecture implemented in code; major live validation now passes, but a few non-blocking hardening items remain.
4
- Date: 2026-04-03
3
+ Status: isolated-profile concurrency architecture implemented in code and validated against the current pi baseline.
4
+ Date: 2026-06-04
5
5
 
6
6
  Companion doc:
7
7
  - `docs/ORACLE_RECOVERY_DRILL.md` — safe expired-auth recovery validation drill
8
8
 
9
9
  Compatibility target:
10
- - `pi` 0.65.0+
10
+ - `pi` 0.78.1+ is the suggested tested floor for current mode-aware poller behavior
11
+ - package metadata keeps pi runtime packages as optional wildcard peers, so this suggested floor is not enforced as a hard npm install requirement
11
12
  - current extension lifecycle only; no backward-compatibility shims for removed `session_switch` / `session_fork` events
12
13
 
13
14
  ## Goal
@@ -638,5 +639,5 @@ Recent proof points:
638
639
  - successful multi-artifact completion: `b6b3599c-6b91-4315-adfa-8a83aa5eda9b`
639
640
  - repo-owned sanity harness: `npm run sanity:oracle`
640
641
  - real installed-extension smoke source of truth: `scripts/oracle-real-smoke.mjs`; required release proof runs packed-install mode (`npm run smoke:real:packed`) and executes installed-package `oracle_submit` deterministically, with optional slower model-agent debugging via `PI_ORACLE_REAL_TEST_MODEL_AGENT=1`; source mode (`npm run smoke:real:source`) is inner-loop/debug only
641
- - macOS, Ubuntu, and Windows native package/build/runtime smoke source of truth: `docs/platform-smoke.md`; use `npm run verify:oracle` for everyday local iteration, `npm run smoke:platform:doctor` plus a focused target/suite run for platform-sensitive changes, and `npm run smoke:platform:all` for doctor-first packed-install Crabbox release evidence
642
+ - macOS, Ubuntu, and Windows native package/build/runtime smoke source of truth: `docs/platform-smoke.md`; use `npm run verify:oracle` for everyday local iteration, `npm run smoke:platform:doctor` plus a focused target/suite run for platform-sensitive changes, `npm run smoke:platform:all` for doctor-first platform matrix evidence, and `npm run release:check` for the full local-plus-platform release gate
642
643
  - release gate: `npm run release:check`, also used by `prepublishOnly`, combines static verification and all required Crabbox platform smokes
@@ -13,7 +13,7 @@
13
13
 
14
14
  Required targets: `macos`, `ubuntu`, `windows-native`.
15
15
  Required suites: `platform-build`, `real-extension`.
16
- Crabbox baseline: `0.24.0` or newer.
16
+ Crabbox baseline: `0.26.0` or newer.
17
17
 
18
18
  ## Required local setup
19
19
 
@@ -25,7 +25,7 @@ crabbox --version
25
25
  crabbox providers
26
26
  ```
27
27
 
28
- `PI_ORACLE_SMOKE_CRABBOX` is optional and only needed to override the binary path.
28
+ `PLATFORM_SMOKE_CRABBOX` is the reusable binary override. `PI_ORACLE_SMOKE_CRABBOX` is a project-specific alias and wins when both are set.
29
29
 
30
30
  Target setup:
31
31
 
@@ -48,13 +48,14 @@ Use the narrowest workflow that proves the change. Do not run the full platform
48
48
  | --- | --- | --- |
49
49
  | Everyday local iteration | `npm run verify:oracle` | Syntax, bundle, platform-smoke invariants, type checks, oracle sanity, and package dry-run pass locally. |
50
50
  | Platform-sensitive change | `npm run smoke:platform:doctor`, then `node scripts/platform-smoke.mjs run --target <target> --suite <suite>` | Target setup is ready and the affected platform/suite works without paying for unrelated targets. |
51
- | Publish/release proof | `npm run smoke:platform:all` | Doctor-first packed-install proof passes on every required target and suite. |
51
+ | Platform matrix proof | `npm run smoke:platform:all` | Doctor-first packed-install proof passes on every required target and suite. |
52
+ | Publish/release gate | `npm run release:check` | Local verification (`verify:oracle`) passes, then the doctor-first platform matrix passes. |
52
53
 
53
54
  Platform-sensitive changes include archive behavior, process cleanup, runtime/browser profile handling, package metadata, Crabbox harness code, or anything that may differ across macOS/Linux/Windows.
54
55
 
55
56
  ## Commands
56
57
 
57
- Doctor is mandatory before the full release matrix. The canonical all-target release command enforces that:
58
+ Doctor is mandatory before the full platform matrix. The canonical all-target platform command enforces that:
58
59
 
59
60
  ```bash
60
61
  npm run smoke:platform:all
@@ -70,13 +71,13 @@ npm run smoke:platform:windows-native
70
71
  node scripts/platform-smoke.mjs run --target windows-native --suite real-extension
71
72
  ```
72
73
 
73
- Release check:
74
+ Full release gate:
74
75
 
75
76
  ```bash
76
77
  npm run release:check
77
78
  ```
78
79
 
79
- `prepublishOnly` runs `npm run release:check`.
80
+ `release:check` runs `verify:oracle` before `smoke:platform:all`, matching the Crabbox doctor-first release order: cheap harness checks, doctor, full matrix, then artifact review. `prepublishOnly` runs `npm run release:check`.
80
81
 
81
82
  ## What `platform-build` proves
82
83
 
@@ -142,12 +143,14 @@ Artifacts are local evidence only. Do not commit or share them without redaction
142
143
 
143
144
  ## Windows template maintenance
144
145
 
145
- When Windows lacks a reusable tool such as `zstd` or `agent-browser`, update `pi-extension-windows-template` rather than adding a per-run installer:
146
-
147
- 1. boot `pi-extension-windows-template`;
148
- 2. install/update the tool globally without secrets;
149
- 3. verify from a fresh SSH session: `node --version`, `npm --version`, `git --version`, `tar --version`, `zstd --version`, `agent-browser --version`;
150
- 4. remove downloads, caches, checkouts, `.pi`, `.artifacts`, `.debug`, and secrets;
151
- 5. shut down cleanly;
152
- 6. create/promote the configured power-off snapshot;
153
- 7. clean stale clones/leases.
146
+ When Windows lacks a reusable tool such as `zstd` or `agent-browser`, update the shared `pi-extension-windows-template` infrastructure rather than adding a per-run installer:
147
+
148
+ 1. revert/switch `pi-extension-windows-template` to the current canonical `crabbox-ready` snapshot;
149
+ 2. boot the template;
150
+ 3. install/update the reusable tool globally without secrets;
151
+ 4. verify from a fresh SSH session: `node --version`, `npm --version`, `git --version`, `tar --version`, `zstd --version`, `agent-browser --version`, and `agent-browser install`;
152
+ 5. remove downloads, caches, checkouts, `.pi`, `.artifacts`, `.debug`, browser auth/session state, and secrets;
153
+ 6. shut down cleanly;
154
+ 7. create/promote the configured power-off `crabbox-ready` snapshot;
155
+ 8. run `npm run smoke:platform:doctor` and `npm run smoke:platform:windows-native` against the promoted snapshot;
156
+ 9. clean stale clones/leases.
@@ -39,9 +39,13 @@ export default function oracleExtension(pi: ExtensionAPI) {
39
39
  function startPollerForContext(ctx: ExtensionContext) {
40
40
  try {
41
41
  const sessionFile = getSessionFile(ctx);
42
+ if (ctx.mode === "print" || ctx.mode === "json") {
43
+ stopPoller(ctx);
44
+ return;
45
+ }
42
46
  if (!hasPersistedSessionFile(sessionFile)) {
43
47
  stopPoller(ctx);
44
- ctx.ui.setStatus("oracle", ctx.ui.theme.fg("accent", "oracle: unavailable"));
48
+ if (ctx.hasUI) ctx.ui.setStatus("oracle", ctx.ui.theme.fg("accent", "oracle: unavailable"));
45
49
  return;
46
50
  }
47
51
 
@@ -49,15 +53,17 @@ export default function oracleExtension(pi: ExtensionAPI) {
49
53
  void runStartupMaintenance(ctx).catch((error) => {
50
54
  const message = `Oracle startup maintenance failed: ${error instanceof Error ? error.message : String(error)}`;
51
55
  console.error(message);
52
- ctx.ui.notify(message, "warning");
56
+ if (ctx.hasUI) ctx.ui.notify(message, "warning");
53
57
  });
54
58
  startPoller(pi, ctx, config.poller.intervalMs, workerPath);
55
59
  refreshOracleStatus(ctx);
56
60
  } catch (error) {
57
61
  const message = error instanceof Error ? error.message : String(error);
58
62
  stopPoller(ctx);
59
- ctx.ui.setStatus("oracle", ctx.ui.theme.fg("error", "oracle: config error"));
60
- ctx.ui.notify(message, "warning");
63
+ if (ctx.hasUI) {
64
+ ctx.ui.setStatus("oracle", ctx.ui.theme.fg("error", "oracle: config error"));
65
+ ctx.ui.notify(message, "warning");
66
+ }
61
67
  }
62
68
  }
63
69
 
@@ -165,6 +165,7 @@ function getJobCountsForSession(sessionFile: string | undefined, cwd: string): {
165
165
  }
166
166
 
167
167
  function refreshOracleStatusSnapshot(snapshot: OraclePollerContextSnapshot): void {
168
+ if (!snapshot.hasUI) return;
168
169
  if (!snapshot.sessionFile) {
169
170
  snapshot.ui.setStatus("oracle", snapshot.ui.theme.fg("accent", "oracle: unavailable"));
170
171
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-oracle",
3
- "version": "0.7.5",
3
+ "version": "0.7.6",
4
4
  "description": "ChatGPT and Grok web-oracle extension for pi with isolated browser auth, async jobs, and project-context archives.",
5
5
  "private": false,
6
6
  "license": "MIT",
@@ -47,7 +47,7 @@
47
47
  ]
48
48
  },
49
49
  "scripts": {
50
- "check:oracle-extension": "node --check extensions/oracle/shared/browser-profile-helpers.mjs && node --check extensions/oracle/shared/process-helpers.mjs && node --check extensions/oracle/shared/state-coordination-helpers.mjs && node --check extensions/oracle/shared/job-coordination-helpers.mjs && node --check extensions/oracle/shared/job-lifecycle-helpers.mjs && node --check extensions/oracle/shared/job-observability-helpers.mjs && node --check extensions/oracle/worker/run-job.mjs && node --check extensions/oracle/worker/state-locks.mjs && node --check extensions/oracle/worker/artifact-heuristics.mjs && node --check extensions/oracle/worker/chatgpt-ui-helpers.mjs && node --check extensions/oracle/worker/chatgpt-flow-helpers.mjs && node --check extensions/oracle/worker/auth-flow-helpers.mjs && node --check extensions/oracle/worker/auth-cookie-policy.mjs && node --check extensions/oracle/worker/chromium-cookie-source.mjs && node --check extensions/oracle/worker/auth-bootstrap.mjs && esbuild extensions/oracle/index.ts --bundle --platform=node --format=esm --external:@earendil-works/pi-coding-agent --external:@earendil-works/pi-ai --external:typebox --outfile=/tmp/pi-oracle-extension-check.js",
50
+ "check:oracle-extension": "node --check extensions/oracle/shared/browser-profile-helpers.mjs && node --check extensions/oracle/shared/process-helpers.mjs && node --check extensions/oracle/shared/state-coordination-helpers.mjs && node --check extensions/oracle/shared/job-coordination-helpers.mjs && node --check extensions/oracle/shared/job-lifecycle-helpers.mjs && node --check extensions/oracle/shared/job-observability-helpers.mjs && node --check extensions/oracle/worker/run-job.mjs && node --check extensions/oracle/worker/state-locks.mjs && node --check extensions/oracle/worker/artifact-heuristics.mjs && node --check extensions/oracle/worker/chatgpt-ui-helpers.mjs && node --check extensions/oracle/worker/chatgpt-flow-helpers.mjs && node --check extensions/oracle/worker/auth-flow-helpers.mjs && node --check extensions/oracle/worker/auth-cookie-policy.mjs && node --check extensions/oracle/worker/chromium-cookie-source.mjs && node --check extensions/oracle/worker/auth-bootstrap.mjs && esbuild extensions/oracle/index.ts --bundle --platform=node --format=esm --external:@earendil-works/pi-coding-agent --external:typebox --outfile=/tmp/pi-oracle-extension-check.js",
51
51
  "typecheck": "tsc --noEmit -p tsconfig.json",
52
52
  "typecheck:worker-helpers": "tsc --noEmit -p tsconfig.worker-helpers.json",
53
53
  "sanity:oracle": "node scripts/oracle-sanity-runner.mjs",
@@ -83,9 +83,9 @@
83
83
  "protobufjs": "7.6.1"
84
84
  },
85
85
  "devDependencies": {
86
- "@earendil-works/pi-ai": "^0.77.0",
87
- "@earendil-works/pi-coding-agent": "^0.77.0",
88
- "@types/node": "^25.9.1",
86
+ "@earendil-works/pi-ai": "^0.78.1",
87
+ "@earendil-works/pi-coding-agent": "^0.78.1",
88
+ "@types/node": "^22.19.19",
89
89
  "esbuild": "^0.28.0",
90
90
  "tsx": "^4.22.3",
91
91
  "typebox": "^1.1.39",
@@ -18,14 +18,18 @@ export default {
18
18
  "node scripts/platform-smoke.mjs run --target <target> --suite <suite>",
19
19
  ],
20
20
  },
21
- release: {
22
- description: "Doctor-first packed-install macOS/Ubuntu/Windows release proof.",
21
+ platformMatrix: {
22
+ description: "Doctor-first packed-install macOS/Ubuntu/Windows platform proof.",
23
23
  commands: ["npm run smoke:platform:all"],
24
24
  },
25
+ release: {
26
+ description: "Full release gate: local verification plus the doctor-first platform matrix.",
27
+ commands: ["npm run release:check"],
28
+ },
25
29
  },
26
30
  requiredCrabbox: {
27
31
  source: "https://github.com/openclaw/crabbox",
28
- minVersion: "0.24.0",
32
+ minVersion: "0.26.0",
29
33
  },
30
34
  ubuntuContainerImage: "pi-oracle-platform-smoke:node24",
31
35
  ubuntuContainerBaseImage: "cimg/node:24.16",
@@ -52,6 +56,9 @@ export default {
52
56
  ai_gateway: ["AI_GATEWAY_API_KEY"],
53
57
  mistral: ["MISTRAL_API_KEY"],
54
58
  minimax: ["MINIMAX_API_KEY"],
59
+ "minimax-cn": ["MINIMAX_CN_API_KEY"],
60
+ "ant-ling": ["ANT_LING_API_KEY"],
61
+ nvidia: ["NVIDIA_API_KEY"],
55
62
  moonshot: ["MOONSHOT_API_KEY"],
56
63
  kimi: ["KIMI_API_KEY"],
57
64
  },
@@ -85,6 +85,9 @@ function apiKeyNameForProvider(provider) {
85
85
  ai_gateway: "AI_GATEWAY_API_KEY",
86
86
  mistral: "MISTRAL_API_KEY",
87
87
  minimax: "MINIMAX_API_KEY",
88
+ "minimax-cn": "MINIMAX_CN_API_KEY",
89
+ "ant-ling": "ANT_LING_API_KEY",
90
+ nvidia: "NVIDIA_API_KEY",
88
91
  moonshot: "MOONSHOT_API_KEY",
89
92
  opencode: "OPENCODE_API_KEY",
90
93
  kimi: "KIMI_API_KEY",
@@ -1,10 +1,10 @@
1
1
  /**
2
- * Thin Crabbox CLI wrapper for pi-oracle's Ubuntu platform smoke target.
2
+ * Thin Crabbox CLI wrapper for pi-oracle's local platform smoke targets.
3
3
  */
4
4
 
5
5
  import { spawn } from "node:child_process";
6
6
 
7
- const CRABBOX_BIN = process.env.PI_ORACLE_SMOKE_CRABBOX || "crabbox";
7
+ const CRABBOX_BIN = process.env.PI_ORACLE_SMOKE_CRABBOX || process.env.PLATFORM_SMOKE_CRABBOX || "crabbox";
8
8
 
9
9
  function env(name) {
10
10
  return process.env[name] ?? "";
@@ -58,9 +58,9 @@ export function execCrabbox(args, opts = {}) {
58
58
  export function buildTargetBaseArgs(targetName, config = {}) {
59
59
  switch (targetName) {
60
60
  case "macos": {
61
- const host = env("PI_ORACLE_SMOKE_MAC_HOST") || "localhost";
62
- const user = env("PI_ORACLE_SMOKE_MAC_USER") || env("USER");
63
- const workRoot = env("PI_ORACLE_SMOKE_MAC_WORK_ROOT") || `/Users/${env("USER")}/crabbox/pi-oracle`;
61
+ const host = env("PI_ORACLE_SMOKE_MAC_HOST") || env("PLATFORM_SMOKE_MAC_HOST") || "localhost";
62
+ const user = env("PI_ORACLE_SMOKE_MAC_USER") || env("PLATFORM_SMOKE_MAC_USER") || env("USER");
63
+ const workRoot = env("PI_ORACLE_SMOKE_MAC_WORK_ROOT") || env("PLATFORM_SMOKE_MAC_WORK_ROOT") || `/Users/${env("USER")}/crabbox/${config.packageName ?? "pi-oracle"}`;
64
64
  return [
65
65
  "--provider", "ssh",
66
66
  "--target", "macos",
@@ -81,7 +81,7 @@ export function buildTargetBaseArgs(targetName, config = {}) {
81
81
  case "windows-native": {
82
82
  const vm = env("PI_ORACLE_SMOKE_WINDOWS_VM") || env("PLATFORM_SMOKE_WINDOWS_VM") || config.windowsParallels?.sourceVm || "pi-extension-windows-template";
83
83
  const snapshot = env("PI_ORACLE_SMOKE_WINDOWS_SNAPSHOT") || env("PLATFORM_SMOKE_WINDOWS_SNAPSHOT") || config.windowsParallels?.snapshot || "crabbox-ready";
84
- const user = env("PI_ORACLE_SMOKE_WINDOWS_USER") || env("USER");
84
+ const user = env("PI_ORACLE_SMOKE_WINDOWS_USER") || env("PLATFORM_SMOKE_WINDOWS_USER") || env("USER");
85
85
  const workRoot = env("PI_ORACLE_SMOKE_WINDOWS_NATIVE_WORK_ROOT") || env("PLATFORM_SMOKE_WINDOWS_WORK_ROOT") || `C:\\crabbox\\${config.packageName ?? "pi-oracle"}`;
86
86
  return [
87
87
  "--provider", "parallels",
@@ -17,6 +17,15 @@ function runNode(args) {
17
17
  return spawnSync(process.execPath, args, { cwd: repoRoot, encoding: "utf8" });
18
18
  }
19
19
 
20
+ function testHelpTextIncludesTargetsAndExamples() {
21
+ const result = runNode(["scripts/platform-smoke.mjs", "--help"]);
22
+ assert.equal(result.status, 0, `help should exit cleanly: ${result.stderr}`);
23
+ assert.match(result.stdout, /Supported: macos,ubuntu,windows-native/, "help should list supported targets");
24
+ assert.match(result.stdout, /--suite\s+Suite name\. Supported: platform-build,real-extension/, "help should list supported suites");
25
+ assert.match(result.stdout, /npm run release:check/, "help should name the full release gate");
26
+ assert.match(result.stdout, /PLATFORM_SMOKE_CRABBOX/, "help should document reusable platform-smoke env knobs");
27
+ }
28
+
20
29
  function testTargetSelection() {
21
30
  const result = runNode(["scripts/platform-smoke.mjs", "run", "--target", "not-a-target", "--suite", "platform-build"]);
22
31
  assert.notEqual(result.status, 0, "unsupported targets should fail before Crabbox runs");
@@ -79,9 +88,15 @@ function testCanonicalWorkflowConfig() {
79
88
  assert.deepEqual(config.workflows?.everyday?.commands, ["npm run verify:oracle"], "everyday workflow should use the local verification gate");
80
89
  assert(config.workflows?.platformSensitive?.commands?.includes("npm run smoke:platform:doctor"), "platform-sensitive workflow should start with doctor");
81
90
  assert(config.workflows?.platformSensitive?.commands?.some((command) => command.includes("--target <target> --suite <suite>")), "platform-sensitive workflow should document focused target/suite runs");
82
- assert.deepEqual(config.workflows?.release?.commands, ["npm run smoke:platform:all"], "release workflow should use the full platform matrix");
91
+ assert.deepEqual(config.workflows?.platformMatrix?.commands, ["npm run smoke:platform:all"], "platform matrix workflow should use the full target matrix");
92
+ assert.deepEqual(config.workflows?.release?.commands, ["npm run release:check"], "release workflow should use the full local-plus-platform release gate");
93
+ assert.equal(config.requiredCrabbox?.minVersion, "0.26.0", "Crabbox baseline should match the documented provider contract");
83
94
  assert.equal(pkg.scripts["smoke:platform:all"], "npm run smoke:platform:doctor && node scripts/platform-smoke.mjs run --target macos,ubuntu,windows-native", "full platform smoke should remain doctor-first and cover all required targets");
84
95
  assert.match(pkg.scripts["release:check"], /npm run verify:oracle && npm run smoke:platform:all/, "release check should combine local verification and full platform smoke");
96
+ const runnerSource = readFileSync(new URL("./crabbox-runner.mjs", import.meta.url), "utf8");
97
+ assert.match(runnerSource, /PLATFORM_SMOKE_CRABBOX/, "runner should honor reusable Crabbox binary override");
98
+ assert.match(runnerSource, /PLATFORM_SMOKE_MAC_WORK_ROOT/, "runner should honor reusable macOS work-root override");
99
+ assert.match(runnerSource, /PLATFORM_SMOKE_WINDOWS_WORK_ROOT/, "runner should honor reusable Windows work-root override");
85
100
  }
86
101
 
87
102
  function testRealSmokeExpensiveAgentPathsAreOptIn() {
@@ -96,6 +111,7 @@ function testRealSmokeExpensiveAgentPathsAreOptIn() {
96
111
  assert.match(source, /truthy\(env\("PI_ORACLE_REAL_TEST_NEGATIVE_SYMLINK"\)\)/, "negative symlink real-agent check should be opt-in");
97
112
  }
98
113
 
114
+ testHelpTextIncludesTargetsAndExamples();
99
115
  testTargetSelection();
100
116
  testPackedInstallCommandRendering();
101
117
  testRealExtensionPackedInstallRendering();
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Ubuntu platform-build suite for pi-oracle.
3
- * The suite proves the PR's package builds/tests on Linux and installs through pi's package path.
2
+ * Cross-platform smoke suites for pi-oracle.
3
+ * The suites prove the package builds, packs, installs, loads, and runs through pi's package path.
4
4
  */
5
5
 
6
6
  import { readFileSync, writeFileSync } from "node:fs";
@@ -41,21 +41,24 @@ Examples:
41
41
  Canonical workflows:
42
42
  Everyday local iteration: npm run verify:oracle
43
43
  Platform-sensitive changes: npm run smoke:platform:doctor, then focused run --target <target> --suite <suite>
44
- Publish/release proof: npm run smoke:platform:all
44
+ Platform matrix proof: npm run smoke:platform:all
45
+ Full release gate: npm run release:check
45
46
 
46
47
  Environment:
47
- PI_ORACLE_SMOKE_CRABBOX Optional Crabbox binary override (defaults to PATH)
48
- PI_ORACLE_SMOKE_MAC_HOST macOS SSH host (default: localhost)
49
- PI_ORACLE_SMOKE_MAC_USER macOS SSH user (default: $USER)
50
- PI_ORACLE_SMOKE_MAC_WORK_ROOT macOS Crabbox work root
51
- PI_ORACLE_SMOKE_UBUNTU_IMAGE Optional local-container image override
52
- PI_ORACLE_SMOKE_WINDOWS_VM Parallels source VM (default from config)
53
- PI_ORACLE_SMOKE_WINDOWS_SNAPSHOT Parallels snapshot (default from config)
54
- PI_ORACLE_SMOKE_WINDOWS_USER Windows SSH user (default: $USER)
55
- PI_ORACLE_SMOKE_WINDOWS_NATIVE_WORK_ROOT Windows work root
48
+ PLATFORM_SMOKE_CRABBOX Reusable Crabbox binary override (defaults to PATH)
49
+ PI_ORACLE_SMOKE_CRABBOX Project-specific Crabbox binary override (wins over PLATFORM_SMOKE_CRABBOX)
50
+ PLATFORM_SMOKE_MAC_HOST macOS SSH host (default: localhost)
51
+ PLATFORM_SMOKE_MAC_USER macOS SSH user (default: $USER)
52
+ PLATFORM_SMOKE_MAC_WORK_ROOT macOS Crabbox work root
53
+ PLATFORM_SMOKE_UBUNTU_IMAGE Optional local-container image override
54
+ PLATFORM_SMOKE_WINDOWS_VM Parallels source VM (default from config)
55
+ PLATFORM_SMOKE_WINDOWS_SNAPSHOT Parallels snapshot (default from config)
56
+ PLATFORM_SMOKE_WINDOWS_USER Windows SSH user (default: $USER)
57
+ PLATFORM_SMOKE_WINDOWS_WORK_ROOT Windows work root
58
+ PI_ORACLE_SMOKE_* Project-specific aliases for the PLATFORM_SMOKE_* knobs above
56
59
  PI_ORACLE_REAL_TEST_PROVIDER Real smoke provider (default: zai)
57
60
  PI_ORACLE_REAL_TEST_MODEL Real smoke model (default: glm-5.1)
58
- ZAI_API_KEY Default real-smoke provider API key
61
+ ZAI_API_KEY Default real-smoke provider API key for optional model-agent debugging
59
62
  `);
60
63
  }
61
64