pi-oracle 0.7.21 → 0.7.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +49 -385
  3. package/docs/ORACLE_DESIGN.md +1 -1
  4. package/docs/development.md +99 -0
  5. package/docs/platform-smoke.md +18 -7
  6. package/docs/reference.md +338 -0
  7. package/extensions/oracle/index.ts +1 -0
  8. package/extensions/oracle/lib/poller.ts +3 -8
  9. package/extensions/oracle/lib/queue.ts +2 -4
  10. package/extensions/oracle/shared/browser-profile-helpers.d.mts +1 -0
  11. package/extensions/oracle/shared/browser-profile-helpers.mjs +32 -0
  12. package/extensions/oracle/worker/auth-bootstrap.mjs +35 -6
  13. package/extensions/oracle/worker/chatgpt-ui-helpers.d.mts +1 -0
  14. package/extensions/oracle/worker/chatgpt-ui-helpers.mjs +18 -13
  15. package/extensions/oracle/worker/chromium-cookie-source.mjs +50 -6
  16. package/extensions/oracle/worker/linux-chromium-cookie-source.d.mts +6 -0
  17. package/extensions/oracle/worker/linux-chromium-cookie-source.mjs +98 -0
  18. package/extensions/oracle/worker/run-job.mjs +34 -34
  19. package/package.json +12 -11
  20. package/platform-smoke.config.mjs +1 -22
  21. package/scripts/oracle-auth.test.mjs +35 -0
  22. package/scripts/oracle-chatgpt-preset-proof.mjs +50 -21
  23. package/scripts/oracle-cookie-import.test.mjs +204 -0
  24. package/scripts/oracle-model.test.mjs +24 -17
  25. package/scripts/oracle-real-smoke.mjs +30 -9
  26. package/scripts/platform-smoke/Dockerfile.ubuntu +3 -2
  27. package/scripts/platform-smoke/crabbox-runner.mjs +18 -6
  28. package/scripts/platform-smoke/doctor.mjs +58 -41
  29. package/scripts/platform-smoke/invariants.mjs +254 -26
  30. package/scripts/platform-smoke/platform-build-windows.ps1 +21 -17
  31. package/scripts/platform-smoke/targets.mjs +59 -30
  32. package/scripts/platform-smoke.mjs +47 -14
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
+ import { createHash } from "node:crypto";
4
+ import { copyFileSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
3
5
  import { createRequire } from "node:module";
4
- import { dirname, resolve } from "node:path";
6
+ import { dirname, relative, resolve, sep } from "node:path";
5
7
  import { fileURLToPath } from "node:url";
6
8
 
7
9
  const __filename = fileURLToPath(import.meta.url);
@@ -21,7 +23,7 @@ function printHelp() {
21
23
  console.log(`Usage: node scripts/platform-smoke.mjs <command> [options]
22
24
 
23
25
  Commands:
24
- doctor Run mandatory Crabbox, host, target-tool, auth, and package preflight checks
26
+ doctor [--target <names>] Run preflight checks for required or selected targets
25
27
  run --target <names> Run one or more comma-separated targets concurrently
26
28
  run --suite <name> Run one suite on the configured target(s)
27
29
 
@@ -48,14 +50,19 @@ Environment:
48
50
  PLATFORM_SMOKE_CRABBOX Reusable Crabbox binary override (defaults to PATH)
49
51
  PI_ORACLE_SMOKE_CRABBOX Project-specific Crabbox binary override (wins over PLATFORM_SMOKE_CRABBOX)
50
52
  PLATFORM_SMOKE_MAC_HOST macOS SSH host (default: localhost)
53
+ PLATFORM_SMOKE_MAC_PORT macOS SSH port (default: 22)
51
54
  PLATFORM_SMOKE_MAC_USER macOS SSH user (default: $USER)
52
55
  PLATFORM_SMOKE_MAC_WORK_ROOT macOS Crabbox work root
53
56
  PLATFORM_SMOKE_UBUNTU_IMAGE Optional local-container image override
54
57
  PLATFORM_SMOKE_WINDOWS_VM Parallels source VM (default from config)
55
58
  PLATFORM_SMOKE_WINDOWS_SNAPSHOT Parallels snapshot (default from config)
59
+ PLATFORM_SMOKE_WINDOWS_HOST Use a native Windows SSH target instead of Parallels
60
+ PLATFORM_SMOKE_WINDOWS_PORT Windows SSH port (default: 22)
56
61
  PLATFORM_SMOKE_WINDOWS_USER Windows SSH user (default: $USER)
57
62
  PLATFORM_SMOKE_WINDOWS_WORK_ROOT Windows work root
58
63
  PI_ORACLE_SMOKE_* Project-specific aliases for the PLATFORM_SMOKE_* knobs above
64
+ PI_ORACLE_RELEASE_TARBALL Use this retained tarball for the packed platform suites
65
+ PI_ORACLE_RELEASE_SHA256 Expected SHA-256 of the retained tarball, when supplied
59
66
  PI_ORACLE_REAL_TEST_PROVIDER Real smoke provider (default: zai)
60
67
  PI_ORACLE_REAL_TEST_MODEL Real smoke model (default: glm-5.2)
61
68
  ZAI_API_KEY Default real-smoke provider API key for optional model-agent debugging
@@ -104,9 +111,9 @@ function validateSelection(targets, suites) {
104
111
  }
105
112
  }
106
113
 
107
- async function runDoctor() {
114
+ async function runDoctor(targets) {
108
115
  const { runDoctor } = await import("./platform-smoke/doctor.mjs");
109
- await runDoctor(config);
116
+ await runDoctor({ ...config, requiredTargets: targets });
110
117
  }
111
118
 
112
119
  async function runTarget(targetName, suites, singleSuite) {
@@ -124,26 +131,52 @@ async function main() {
124
131
  if (!config) throw new Error("platform-smoke.config.mjs not found or failed to load");
125
132
 
126
133
  if (args.command === "doctor") {
127
- await runDoctor();
134
+ const targets = args.target ? splitCsv(args.target) : config.requiredTargets;
135
+ if (targets.length === 0) throw new Error("--target did not resolve to any targets");
136
+ validateSelection(targets, config.requiredSuites);
137
+ await runDoctor(targets);
128
138
  return;
129
139
  }
130
140
 
131
141
  if (args.command === "run") {
132
142
  const targets = args.target ? splitCsv(args.target) : config.requiredTargets;
133
143
  const suites = args.suite ? [args.suite] : config.requiredSuites;
144
+ if (targets.length === 0) throw new Error("--target did not resolve to any targets");
145
+ if (suites.length === 0) throw new Error("--suite did not resolve to any suites");
134
146
  validateSelection(targets, suites);
135
- const results = await Promise.all(targets.map(async (target) => {
136
- console.log(`\n=== Target: ${target} ===`);
137
- return { target, result: await runTarget(target, suites, Boolean(args.suite)) };
138
- }));
139
- if (results.some(({ result }) => !result.ok)) {
140
- console.log("\nOne or more platform smoke suites failed. Check .artifacts/platform-smoke/ for details.");
141
- process.exit(1);
147
+ let inputDir;
148
+ try {
149
+ if (process.env.PI_ORACLE_RELEASE_TARBALL) {
150
+ // Crabbox syncs nonignored files, but this repository ignores *.tgz.
151
+ inputDir = mkdtempSync(resolve(repoRoot, ".oracle-release-input-"));
152
+ const candidate = resolve(inputDir, "candidate");
153
+ copyFileSync(resolve(process.env.PI_ORACLE_RELEASE_TARBALL), candidate);
154
+ const sha256 = createHash("sha256").update(readFileSync(candidate)).digest("hex");
155
+ if (process.env.PI_ORACLE_RELEASE_SHA256 && sha256 !== process.env.PI_ORACLE_RELEASE_SHA256) {
156
+ throw new Error("Retained release candidate checksum changed");
157
+ }
158
+ config.releaseCandidate = {
159
+ path: relative(repoRoot, candidate).split(sep).join("/"),
160
+ sha256,
161
+ };
162
+ console.log(`Retained release candidate SHA-256: ${config.releaseCandidate.sha256}`);
163
+ }
164
+ const outcomes = await Promise.allSettled(targets.map(async (target) => {
165
+ console.log(`\n=== Target: ${target} ===`);
166
+ return { target, result: await runTarget(target, suites, Boolean(args.suite)) };
167
+ }));
168
+ const failure = outcomes.find((outcome) => outcome.status === "rejected");
169
+ if (failure) throw failure.reason;
170
+ const results = outcomes.map((outcome) => outcome.value);
171
+ if (results.some(({ result }) => !result.ok)) {
172
+ console.log("\nOne or more platform smoke suites failed. Check .artifacts/platform-smoke/ for details.");
173
+ process.exitCode = 1;
174
+ }
175
+ } finally {
176
+ if (inputDir) rmSync(inputDir, { recursive: true, force: true });
142
177
  }
143
178
  return;
144
179
  }
145
-
146
- throw new Error(`unknown command: ${args.command}`);
147
180
  }
148
181
 
149
182
  main().catch((error) => {