pi-oracle 0.7.6 → 0.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/README.md +4 -2
- package/docs/ORACLE_DESIGN.md +6 -4
- package/docs/ORACLE_ISOLATED_PI_VALIDATION.md +7 -7
- package/docs/platform-smoke.md +5 -5
- package/extensions/oracle/lib/config.ts +63 -9
- package/extensions/oracle/lib/tools.ts +2 -2
- package/package.json +3 -3
- package/scripts/oracle-real-smoke.mjs +4 -3
- package/scripts/platform-smoke/platform-build-windows.ps1 +2 -2
- package/scripts/platform-smoke/targets.mjs +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.7.7 - 2026-06-08
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- updated the local pi development baseline to `@earendil-works/pi-coding-agent` / `@earendil-works/pi-ai` `0.79.0` and regenerated the npm lockfile
|
|
9
|
+
- documented `pi` `0.79.0+` as the suggested tested floor while keeping pi runtime packages as optional wildcard peers so npm peer ranges do not block users from trying newer pi releases
|
|
10
|
+
- updated isolated local-extension and packed package validation workflows to pass explicit `--approve` when they intentionally trust their temporary project fixtures under Pi 0.79.0 project-trust rules
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- made project-local `.pi/extensions/oracle.json` overrides honor explicit Pi project-trust opt-outs (`--no-approve` or a saved “do not trust” decision) while preserving the historical default of loading safe project overrides for existing oracle users
|
|
14
|
+
|
|
15
|
+
### Compatibility
|
|
16
|
+
- reviewed the pi `0.79.0` changelog, project-trust docs, extension docs, package docs, prompt-template docs, SDK/RPC exports, and matching examples; the oracle extension remains compatible with current extension lifecycle and package install/update behavior
|
|
17
|
+
|
|
5
18
|
## 0.7.6 - 2026-06-04
|
|
6
19
|
|
|
7
20
|
### Changed
|
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 pi `0.
|
|
5
|
+
> Status: experimental public beta. Validated on macOS, Linux, and Windows native with Chromium-family browsers and pi `0.79.0`. Pi `0.79.0+` is the suggested tested floor for project-trust-aware package/runtime validation, 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
|
-
- Suggested tested floor: `pi` 0.
|
|
80
|
+
- Suggested tested floor: `pi` 0.79.0 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
|
|
@@ -179,6 +179,8 @@ Agent-facing tools:
|
|
|
179
179
|
|
|
180
180
|
Most users can start with defaults. Set an agent-level config only when you need a non-default provider, mode, preset, or browser profile.
|
|
181
181
|
|
|
182
|
+
Pi 0.79.0 gates project-local inputs behind project trust. `pi-oracle` preserves its historical risk-on extension behavior for existing users: project-local `.pi/extensions/oracle.json` safe overrides still load by default for compatibility. They are ignored when you explicitly opt out of project-local inputs with `--no-approve` or save a “do not trust” decision for the project. Privileged browser/auth settings still come only from the agent-level config.
|
|
183
|
+
|
|
182
184
|
`~/.pi/agent/extensions/oracle.json`
|
|
183
185
|
|
|
184
186
|
```json
|
package/docs/ORACLE_DESIGN.md
CHANGED
|
@@ -7,7 +7,7 @@ Companion doc:
|
|
|
7
7
|
- `docs/ORACLE_RECOVERY_DRILL.md` — safe expired-auth recovery validation drill
|
|
8
8
|
|
|
9
9
|
Compatibility target:
|
|
10
|
-
- `pi` 0.
|
|
10
|
+
- `pi` 0.79.0+ is the suggested tested floor for current project-trust-aware package/runtime validation
|
|
11
11
|
- package metadata keeps pi runtime packages as optional wildcard peers, so this suggested floor is not enforced as a hard npm install requirement
|
|
12
12
|
- current extension lifecycle only; no backward-compatibility shims for removed `session_switch` / `session_fork` events
|
|
13
13
|
|
|
@@ -229,9 +229,7 @@ Merged config locations:
|
|
|
229
229
|
- global: `~/.pi/agent/extensions/oracle.json`
|
|
230
230
|
- project: `.pi/extensions/oracle.json`
|
|
231
231
|
|
|
232
|
-
Project config remains restricted to safe overrides only.
|
|
233
|
-
|
|
234
|
-
Browser/auth settings are global-only because they control local privileged browser state.
|
|
232
|
+
Project config remains restricted to safe overrides only. On Pi 0.79.0+, pi itself gates project-local inputs behind project trust, but `pi-oracle` keeps its historical risk-on extension behavior for this package-specific safe override file: `.pi/extensions/oracle.json` loads by default for compatibility, and is ignored only when the run passes `--no-approve` or the project has a saved “do not trust” decision. This preserves the existing extension experience while still honoring explicit opt-out/distrust decisions. Browser/auth settings remain global-only because they control local privileged browser state.
|
|
235
233
|
|
|
236
234
|
### Current config shape
|
|
237
235
|
|
|
@@ -633,6 +631,10 @@ Remaining non-blocking hardening work:
|
|
|
633
631
|
- keep hardening model-selection verification against future ChatGPT UI variation
|
|
634
632
|
|
|
635
633
|
Recent proof points:
|
|
634
|
+
- Pi 0.79.0 release gate: `npm run release:check` passed on 2026-06-08, including `verify:oracle` plus Crabbox macOS, Ubuntu, and Windows native `platform-build` and `real-extension` suites
|
|
635
|
+
- Pi 0.79.0 platform artifacts: `.artifacts/platform-smoke/run-1780938522145-50q2f2` (macOS platform-build), `.artifacts/platform-smoke/run-1780938572090-bi87g5` (macOS real-extension), `.artifacts/platform-smoke/run-1780938542847-quridb` (Ubuntu platform-build), `.artifacts/platform-smoke/run-1780938587248-c8uo4c` (Ubuntu real-extension), `.artifacts/platform-smoke/run-1780938585007-l0xapp` (Windows native platform-build), `.artifacts/platform-smoke/run-1780938820527-c1j8tt` (Windows native real-extension)
|
|
636
|
+
- Pi 0.79.0 isolated local-extension model-agent smoke: `.artifacts/real-smoke/run-1780935835596-pfbn5o` passed with `PI_ORACLE_REAL_TEST_MODEL_AGENT=1 npm run smoke:real:source`
|
|
637
|
+
- Pi 0.79.0 packed-install smoke: `.artifacts/real-smoke/run-1780935825537-pmna07` passed with `npm run smoke:real:packed`
|
|
636
638
|
- expired-auth drill fail path: `a2460bc1-7d89-4041-b67d-39680d310325`
|
|
637
639
|
- `/oracle-auth` repair evidence: the per-run `/tmp/pi-oracle-auth-*/oracle-auth.log` bundle path printed by `/oracle-auth`
|
|
638
640
|
- expired-auth drill post-repair success: `fa26a2a7-0057-4a21-b3e0-71c1d020facf`
|
|
@@ -24,15 +24,15 @@ That keeps the validation run from reusing your normal `pi` agent state.
|
|
|
24
24
|
The extension is loaded from the local checkout with:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
pi --no-extensions -e "$REPO/extensions/oracle/index.ts"
|
|
27
|
+
pi --approve --no-extensions -e "$REPO/extensions/oracle/index.ts"
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
That ensures the session is exercising the in-repo code, not a globally installed package.
|
|
30
|
+
That ensures the session is exercising the in-repo code, not a globally installed package. `--approve` is intentional for this isolated workflow on Pi 0.79.0+: the test fixture is this trusted checkout, and non-interactive/scripted validation must not block on the project-trust prompt.
|
|
31
31
|
|
|
32
32
|
If you also need the in-repo `/oracle` prompt template, load it explicitly instead of installing this repository as a project-local package:
|
|
33
33
|
|
|
34
34
|
```bash
|
|
35
|
-
pi --no-extensions -e "$REPO/extensions/oracle/index.ts" \
|
|
35
|
+
pi --approve --no-extensions -e "$REPO/extensions/oracle/index.ts" \
|
|
36
36
|
--no-prompt-templates --prompt-template "$REPO/prompts/oracle.md"
|
|
37
37
|
```
|
|
38
38
|
|
|
@@ -96,7 +96,7 @@ cleanup() {
|
|
|
96
96
|
trap cleanup EXIT
|
|
97
97
|
cleanup
|
|
98
98
|
|
|
99
|
-
TMUX_CMD1="cd '$REPO' && env PI_CODING_AGENT_DIR='$TEST1_AGENT' PI_ORACLE_JOBS_DIR='$TEST1_JOBS' PATH='$PATH' pi --session-dir '$TEST1_SESSIONS' --no-extensions -e '$REPO/extensions/oracle/index.ts'"
|
|
99
|
+
TMUX_CMD1="cd '$REPO' && env PI_CODING_AGENT_DIR='$TEST1_AGENT' PI_ORACLE_JOBS_DIR='$TEST1_JOBS' PATH='$PATH' pi --approve --session-dir '$TEST1_SESSIONS' --no-extensions -e '$REPO/extensions/oracle/index.ts'"
|
|
100
100
|
tmux new-session -d -s "$SESSION1" "$TMUX_CMD1"
|
|
101
101
|
sleep 8
|
|
102
102
|
tmux send-keys -t "$SESSION1":0.0 "$PROMPT1" Enter
|
|
@@ -129,7 +129,7 @@ PY
|
|
|
129
129
|
rm -f "$LIST"
|
|
130
130
|
fi
|
|
131
131
|
|
|
132
|
-
TMUX_CMD2="cd '$FIXTURE' && env PI_CODING_AGENT_DIR='$TEST2_AGENT' PI_ORACLE_JOBS_DIR='$TEST2_JOBS' PATH='$PATH' pi --session-dir '$TEST2_SESSIONS' --no-extensions -e '$REPO/extensions/oracle/index.ts'"
|
|
132
|
+
TMUX_CMD2="cd '$FIXTURE' && env PI_CODING_AGENT_DIR='$TEST2_AGENT' PI_ORACLE_JOBS_DIR='$TEST2_JOBS' PATH='$PATH' pi --approve --session-dir '$TEST2_SESSIONS' --no-extensions -e '$REPO/extensions/oracle/index.ts'"
|
|
133
133
|
tmux new-session -d -s "$SESSION2" "$TMUX_CMD2"
|
|
134
134
|
sleep 8
|
|
135
135
|
tmux send-keys -t "$SESSION2":0.0 "$PROMPT2" Enter
|
|
@@ -178,7 +178,7 @@ Expected behavior:
|
|
|
178
178
|
The main smoke test above calls `oracle_submit` directly, so it only needs the local extension entrypoint. If you also changed `prompts/oracle.md`, start the isolated session with the local prompt template explicitly loaded:
|
|
179
179
|
|
|
180
180
|
```bash
|
|
181
|
-
LOCAL_ORACLE_PI_CMD="pi --session-dir '$TEST1_SESSIONS' --no-extensions -e '$REPO/extensions/oracle/index.ts' --no-prompt-templates --prompt-template '$REPO/prompts/oracle.md'"
|
|
181
|
+
LOCAL_ORACLE_PI_CMD="pi --approve --session-dir '$TEST1_SESSIONS' --no-extensions -e '$REPO/extensions/oracle/index.ts' --no-prompt-templates --prompt-template '$REPO/prompts/oracle.md'"
|
|
182
182
|
TMUX_CMD1="cd '$REPO' && env PI_CODING_AGENT_DIR='$TEST1_AGENT' PI_ORACLE_JOBS_DIR='$TEST1_JOBS' PATH='$PATH' $LOCAL_ORACLE_PI_CMD"
|
|
183
183
|
```
|
|
184
184
|
|
|
@@ -226,7 +226,7 @@ cleanup() {
|
|
|
226
226
|
trap 'cleanup; rm -rf "$TEST_ROOT"' EXIT
|
|
227
227
|
cleanup
|
|
228
228
|
|
|
229
|
-
TMUX_CMD="cd '$REPO' && env PI_CODING_AGENT_DIR='$AGENT_DIR' PI_ORACLE_JOBS_DIR='$JOBS_DIR' AGENT_BROWSER_PATH='$FAKE_BROWSER' PI_ORACLE_AUTH_AGENT_BROWSER_TIMEOUT_MS='250' PI_ORACLE_AUTH_CLOSE_TIMEOUT_MS='250' PI_ORACLE_AUTH_KILL_GRACE_MS='100' PATH='$PATH' pi --session-dir '$SESSION_DIR' --no-extensions -e '$REPO/extensions/oracle/index.ts'"
|
|
229
|
+
TMUX_CMD="cd '$REPO' && env PI_CODING_AGENT_DIR='$AGENT_DIR' PI_ORACLE_JOBS_DIR='$JOBS_DIR' AGENT_BROWSER_PATH='$FAKE_BROWSER' PI_ORACLE_AUTH_AGENT_BROWSER_TIMEOUT_MS='250' PI_ORACLE_AUTH_CLOSE_TIMEOUT_MS='250' PI_ORACLE_AUTH_KILL_GRACE_MS='100' PATH='$PATH' pi --approve --session-dir '$SESSION_DIR' --no-extensions -e '$REPO/extensions/oracle/index.ts'"
|
|
230
230
|
|
|
231
231
|
tmux new-session -d -s "$SESSION_NAME" "$TMUX_CMD"
|
|
232
232
|
sleep 8
|
package/docs/platform-smoke.md
CHANGED
|
@@ -90,8 +90,8 @@ On each required target, `platform-build`:
|
|
|
90
90
|
5. runs `npm pack`;
|
|
91
91
|
6. creates a fresh target-local pi project;
|
|
92
92
|
7. runs `npm install --no-save <packed tarball>`;
|
|
93
|
-
8. runs `pi install -l ./node_modules/pi-oracle
|
|
94
|
-
9. runs `pi list`;
|
|
93
|
+
8. runs `pi install -l ./node_modules/pi-oracle --approve` so Pi 0.79.0 project-trust gating intentionally trusts the temporary fixture;
|
|
94
|
+
9. runs `pi list --approve`;
|
|
95
95
|
10. asserts the installed package came from `node_modules/pi-oracle` and did not use `pi -e` / source-extension shortcuts.
|
|
96
96
|
|
|
97
97
|
## What `real-extension` proves
|
|
@@ -100,8 +100,8 @@ On each required target, `platform-build`:
|
|
|
100
100
|
|
|
101
101
|
1. packs this checkout with `npm pack`;
|
|
102
102
|
2. installs the tarball into a clean pi project;
|
|
103
|
-
3. runs `pi install -l ./node_modules/pi-oracle`;
|
|
104
|
-
4. asserts `pi list` shows the packed install path;
|
|
103
|
+
3. runs `pi install -l ./node_modules/pi-oracle --approve`;
|
|
104
|
+
4. asserts `pi list --approve` shows the packed install path;
|
|
105
105
|
5. executes `oracle_submit` from the installed package path, not source `pi -e`;
|
|
106
106
|
6. asserts whole-project archive creation and default exclusions.
|
|
107
107
|
|
|
@@ -113,7 +113,7 @@ For inner-loop/debug only, use:
|
|
|
113
113
|
npm run smoke:real:source
|
|
114
114
|
```
|
|
115
115
|
|
|
116
|
-
That source-mode smoke loads `extensions/oracle/index.ts` with `pi --no-extensions -e`; it is useful while developing but is not release proof.
|
|
116
|
+
That source-mode smoke loads `extensions/oracle/index.ts` with `pi --approve --no-extensions -e`; it is useful while developing but is not release proof.
|
|
117
117
|
|
|
118
118
|
## Artifacts
|
|
119
119
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { execFileSync } from "node:child_process";
|
|
7
7
|
import { existsSync, readFileSync } from "node:fs";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
|
-
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
9
|
+
import { getAgentDir, hasProjectTrustInputs, ProjectTrustStore } from "@earendil-works/pi-coding-agent";
|
|
10
10
|
import { isAbsolute, join, normalize } from "node:path";
|
|
11
11
|
import {
|
|
12
12
|
assertNotKnownBrowserUserDataPath,
|
|
@@ -313,27 +313,76 @@ const detectedChromeUserAgent = detectDefaultChromeUserAgent(detectedChromeExecu
|
|
|
313
313
|
const agentExtensionsDir = join(getAgentDir(), "extensions");
|
|
314
314
|
const detectedChromeProfileName = detectDefaultBrowserProfileSource(process.platform);
|
|
315
315
|
|
|
316
|
+
export interface OracleConfigLoadOptions {
|
|
317
|
+
/**
|
|
318
|
+
* Whether project-local oracle config may be loaded. Omit for the runtime
|
|
319
|
+
* policy that preserves oracle's historical project-config behavior while
|
|
320
|
+
* respecting explicit --no-approve and saved distrust decisions.
|
|
321
|
+
*/
|
|
322
|
+
projectConfigTrusted?: boolean;
|
|
323
|
+
/** Session cwd used for Pi's saved project-trust decision when config lookup is anchored to a derived project root. */
|
|
324
|
+
projectConfigTrustCwd?: string;
|
|
325
|
+
}
|
|
326
|
+
|
|
316
327
|
export interface OracleConfigLoadDetails {
|
|
317
328
|
agentDir: string;
|
|
318
329
|
agentConfigPath: string;
|
|
319
330
|
agentConfigExists: boolean;
|
|
320
331
|
projectConfigPath: string;
|
|
321
332
|
projectConfigExists: boolean;
|
|
333
|
+
projectConfigTrusted: boolean;
|
|
334
|
+
projectConfigLoaded: boolean;
|
|
335
|
+
projectConfigSkippedReason?: string;
|
|
322
336
|
effectiveAuthConfigPath: string;
|
|
323
337
|
effectiveAuthScope: "agent";
|
|
324
338
|
}
|
|
325
339
|
|
|
326
|
-
|
|
340
|
+
function getProjectTrustCliOverride(argv = process.argv): boolean | undefined {
|
|
341
|
+
let trusted: boolean | undefined;
|
|
342
|
+
for (const arg of argv.slice(2)) {
|
|
343
|
+
if (arg === "--approve" || arg === "-a") trusted = true;
|
|
344
|
+
if (arg === "--no-approve" || arg === "-na") trusted = false;
|
|
345
|
+
}
|
|
346
|
+
return trusted;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
function isProjectConfigTrusted(cwd: string, agentDir: string, projectConfigExists: boolean, options?: OracleConfigLoadOptions): boolean {
|
|
350
|
+
if (options?.projectConfigTrusted !== undefined) return options.projectConfigTrusted;
|
|
351
|
+
const trustCwd = options?.projectConfigTrustCwd ?? cwd;
|
|
352
|
+
const cliOverride = getProjectTrustCliOverride();
|
|
353
|
+
if (cliOverride !== undefined) return cliOverride;
|
|
354
|
+
if (!projectConfigExists && !hasProjectTrustInputs(trustCwd)) return true;
|
|
355
|
+
try {
|
|
356
|
+
const trustStore = new ProjectTrustStore(agentDir);
|
|
357
|
+
const trustDecision = trustStore.get(trustCwd);
|
|
358
|
+
const rootDecision = trustCwd !== cwd ? trustStore.get(cwd) : null;
|
|
359
|
+
if (trustDecision !== null) return trustDecision;
|
|
360
|
+
if (rootDecision !== null) return rootDecision;
|
|
361
|
+
} catch {
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
export function getOracleConfigLoadDetails(cwd: string, options?: OracleConfigLoadOptions): OracleConfigLoadDetails {
|
|
327
368
|
const agentDir = getAgentDir();
|
|
328
369
|
const projectRoot = getProjectId(cwd);
|
|
329
370
|
const agentConfigPath = join(agentDir, "extensions", "oracle.json");
|
|
330
371
|
const projectConfigPath = join(projectRoot, ".pi", "extensions", "oracle.json");
|
|
372
|
+
const projectConfigExists = existsSync(projectConfigPath);
|
|
373
|
+
const projectConfigTrusted = isProjectConfigTrusted(projectRoot, agentDir, projectConfigExists, options);
|
|
374
|
+
const projectConfigLoaded = projectConfigExists && projectConfigTrusted;
|
|
331
375
|
return {
|
|
332
376
|
agentDir,
|
|
333
377
|
agentConfigPath,
|
|
334
378
|
agentConfigExists: existsSync(agentConfigPath),
|
|
335
379
|
projectConfigPath,
|
|
336
|
-
projectConfigExists
|
|
380
|
+
projectConfigExists,
|
|
381
|
+
projectConfigTrusted,
|
|
382
|
+
projectConfigLoaded,
|
|
383
|
+
projectConfigSkippedReason: projectConfigExists && !projectConfigTrusted
|
|
384
|
+
? "Project oracle config is ignored because this run used --no-approve or the project has a saved untrusted decision."
|
|
385
|
+
: undefined,
|
|
337
386
|
effectiveAuthConfigPath: agentConfigPath,
|
|
338
387
|
effectiveAuthScope: "agent",
|
|
339
388
|
};
|
|
@@ -341,8 +390,11 @@ export function getOracleConfigLoadDetails(cwd: string): OracleConfigLoadDetails
|
|
|
341
390
|
|
|
342
391
|
export function formatOracleAuthConfigRemediation(details: OracleConfigLoadDetails): string {
|
|
343
392
|
const authFields = "auth.chromeProfile / auth.chromeCookiePath / auth.chromiumKeychain";
|
|
344
|
-
if (!details.
|
|
345
|
-
|
|
393
|
+
if (!details.projectConfigLoaded) {
|
|
394
|
+
const projectNote = details.projectConfigSkippedReason
|
|
395
|
+
? ` Project config at ${details.projectConfigPath} is present but not loaded because this run explicitly does not trust project-local inputs.`
|
|
396
|
+
: "";
|
|
397
|
+
return `Set ${authFields} in ${details.effectiveAuthConfigPath}.${projectNote}`;
|
|
346
398
|
}
|
|
347
399
|
return (
|
|
348
400
|
`Set ${authFields} in ${details.effectiveAuthConfigPath}. ` +
|
|
@@ -354,11 +406,13 @@ export function formatOracleAuthConfigSummary(details: OracleConfigLoadDetails):
|
|
|
354
406
|
const lines = [
|
|
355
407
|
`Effective oracle auth config: ${details.effectiveAuthConfigPath} (agent dir: ${details.agentDir}${details.agentConfigExists ? "" : "; create this file to override auth.*"})`,
|
|
356
408
|
];
|
|
357
|
-
if (details.
|
|
409
|
+
if (details.projectConfigLoaded) {
|
|
358
410
|
lines.push(
|
|
359
411
|
`Project oracle config also loaded: ${details.projectConfigPath} ` +
|
|
360
412
|
`(project scope can override ${[...PROJECT_OVERRIDE_KEYS].join("/")} only; auth.* still comes from ${details.effectiveAuthConfigPath}).`,
|
|
361
413
|
);
|
|
414
|
+
} else if (details.projectConfigSkippedReason) {
|
|
415
|
+
lines.push(`Project oracle config present but not loaded: ${details.projectConfigPath}. ${details.projectConfigSkippedReason}`);
|
|
362
416
|
}
|
|
363
417
|
return lines.join("\n");
|
|
364
418
|
}
|
|
@@ -665,9 +719,9 @@ function validateOracleConfig(value: unknown): OracleConfig {
|
|
|
665
719
|
};
|
|
666
720
|
}
|
|
667
721
|
|
|
668
|
-
export function loadOracleConfig(cwd: string): OracleConfig {
|
|
669
|
-
const details = getOracleConfigLoadDetails(cwd);
|
|
722
|
+
export function loadOracleConfig(cwd: string, options?: OracleConfigLoadOptions): OracleConfig {
|
|
723
|
+
const details = getOracleConfigLoadDetails(cwd, options);
|
|
670
724
|
const globalConfig = readJson(details.agentConfigPath);
|
|
671
|
-
const projectConfig = filterProjectConfig(readJson(details.projectConfigPath));
|
|
725
|
+
const projectConfig = details.projectConfigLoaded ? filterProjectConfig(readJson(details.projectConfigPath)) : undefined;
|
|
672
726
|
return validateOracleConfig(deepMerge(deepMerge(DEFAULT_CONFIG, globalConfig), projectConfig));
|
|
673
727
|
}
|
|
@@ -1264,7 +1264,7 @@ export function registerOracleTools(pi: ExtensionAPI, workerPath: string, authWo
|
|
|
1264
1264
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
1265
1265
|
try {
|
|
1266
1266
|
const projectCwd = getProjectId(ctx.cwd);
|
|
1267
|
-
const baseConfig = loadOracleConfig(projectCwd);
|
|
1267
|
+
const baseConfig = loadOracleConfig(projectCwd, { projectConfigTrustCwd: ctx.cwd });
|
|
1268
1268
|
const provider = normalizeOracleProvider(params.provider, baseConfig.defaults.provider, "oracle_auth");
|
|
1269
1269
|
const message = await runOracleAuthBootstrap(authWorkerPath, projectCwd, provider);
|
|
1270
1270
|
return {
|
|
@@ -1311,7 +1311,7 @@ export function registerOracleTools(pi: ExtensionAPI, workerPath: string, authWo
|
|
|
1311
1311
|
async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
|
|
1312
1312
|
try {
|
|
1313
1313
|
const projectCwd = getProjectId(ctx.cwd);
|
|
1314
|
-
const baseConfig = loadOracleConfig(projectCwd);
|
|
1314
|
+
const baseConfig = loadOracleConfig(projectCwd, { projectConfigTrustCwd: ctx.cwd });
|
|
1315
1315
|
const originSessionFile = requirePersistedSessionFile(getSessionFile(ctx), "submit oracle jobs");
|
|
1316
1316
|
const projectId = getProjectId(projectCwd);
|
|
1317
1317
|
const sessionId = getSessionId(originSessionFile, projectId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-oracle",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.7",
|
|
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",
|
|
@@ -83,8 +83,8 @@
|
|
|
83
83
|
"protobufjs": "7.6.1"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
|
-
"@earendil-works/pi-ai": "^0.
|
|
87
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
86
|
+
"@earendil-works/pi-ai": "^0.79.0",
|
|
87
|
+
"@earendil-works/pi-coding-agent": "^0.79.0",
|
|
88
88
|
"@types/node": "^22.19.19",
|
|
89
89
|
"esbuild": "^0.28.0",
|
|
90
90
|
"tsx": "^4.22.3",
|
|
@@ -22,7 +22,7 @@ function usage() {
|
|
|
22
22
|
console.log(`Usage: node scripts/oracle-real-smoke.mjs <doctor|run> [--mode packed|source]
|
|
23
23
|
|
|
24
24
|
Modes:
|
|
25
|
-
packed Release proof. npm pack -> clean pi project -> npm install tarball -> pi install -l -> run through installed package. Default.
|
|
25
|
+
packed Release proof. npm pack -> clean pi project -> npm install tarball -> pi install -l --approve -> run through installed package. Default.
|
|
26
26
|
source Inner-loop/debug only. Loads this checkout with pi --no-extensions -e extensions/oracle/index.ts.
|
|
27
27
|
|
|
28
28
|
Environment:
|
|
@@ -257,12 +257,12 @@ async function preparePackedProject({ runDir, provider, model, timeoutMs }) {
|
|
|
257
257
|
|
|
258
258
|
await mustRun(installDir, "npm-init", npm, ["init", "-y"], { cwd: piProject, env: process.env, timeoutMs: 60_000 });
|
|
259
259
|
await mustRun(installDir, "packed-node-install", npm, ["install", "--no-save", tarballPath], { cwd: piProject, env: process.env, timeoutMs: 120_000 });
|
|
260
|
-
await mustRun(installDir, "pi-install", piCommand(), ["install", "-l", `./node_modules/${PACKAGE_NAME}
|
|
260
|
+
await mustRun(installDir, "pi-install", piCommand(), ["install", "-l", `./node_modules/${PACKAGE_NAME}`, "--approve"], {
|
|
261
261
|
cwd: piProject,
|
|
262
262
|
env: { ...process.env, PI_OFFLINE: "1" },
|
|
263
263
|
timeoutMs: 120_000,
|
|
264
264
|
});
|
|
265
|
-
const piList = await mustRun(installDir, "pi-list", piCommand(), ["list"], {
|
|
265
|
+
const piList = await mustRun(installDir, "pi-list", piCommand(), ["list", "--approve"], {
|
|
266
266
|
cwd: piProject,
|
|
267
267
|
env: { ...process.env, PI_OFFLINE: "1" },
|
|
268
268
|
timeoutMs: 60_000,
|
|
@@ -342,6 +342,7 @@ console.log(JSON.stringify(result, null, 2));
|
|
|
342
342
|
async function runPiAgent({ prepared, agentDir, sessionDir, jobsDir, prompt, outDir, label, timeoutMs, stopAfterJobArchive = false }) {
|
|
343
343
|
mkdirSync(outDir, { recursive: true });
|
|
344
344
|
const args = [
|
|
345
|
+
"--approve",
|
|
345
346
|
"--print",
|
|
346
347
|
"--provider", prepared.provider,
|
|
347
348
|
"--model", prepared.model,
|
|
@@ -122,7 +122,7 @@ if ($PackTarball -and $PiCli -and (Test-Path -LiteralPath $TarballPath)) {
|
|
|
122
122
|
if ($PACKED_NODE_INSTALL_EXIT -eq 0) {
|
|
123
123
|
$PreviousPiOffline = $env:PI_OFFLINE
|
|
124
124
|
$env:PI_OFFLINE = "1"
|
|
125
|
-
& $PiCli install -l (Join-Path ".\node_modules" $PackageName) 1> $PiInstallOut 2> $PiInstallErr
|
|
125
|
+
& $PiCli install -l (Join-Path ".\node_modules" $PackageName) --approve 1> $PiInstallOut 2> $PiInstallErr
|
|
126
126
|
$PI_INSTALL_EXIT = Exit-CodeFromLastCommand
|
|
127
127
|
if ($null -eq $PreviousPiOffline) { Remove-Item Env:\PI_OFFLINE -ErrorAction SilentlyContinue } else { $env:PI_OFFLINE = $PreviousPiOffline }
|
|
128
128
|
} else {
|
|
@@ -148,7 +148,7 @@ if ($PiCli) {
|
|
|
148
148
|
Push-Location $PiProject
|
|
149
149
|
$PreviousPiOffline = $env:PI_OFFLINE
|
|
150
150
|
$env:PI_OFFLINE = "1"
|
|
151
|
-
& $PiCli list 1> $PiListOut 2> $PiListErr
|
|
151
|
+
& $PiCli list --approve 1> $PiListOut 2> $PiListErr
|
|
152
152
|
$PI_LIST_EXIT = Exit-CodeFromLastCommand
|
|
153
153
|
if ($null -eq $PreviousPiOffline) { Remove-Item Env:\PI_OFFLINE -ErrorAction SilentlyContinue } else { $env:PI_OFFLINE = $PreviousPiOffline }
|
|
154
154
|
Pop-Location
|
|
@@ -194,13 +194,13 @@ export function buildPlatformBuildCommand(targetName = "ubuntu", packageName = "
|
|
|
194
194
|
lines.push('echo "PLATFORM_PACKED_NODE_INSTALL_EXIT=$PACKED_NODE_INSTALL_EXIT"');
|
|
195
195
|
lines.push(...posixSection("PACKED_NODE_INSTALL_STDOUT", 'cat "$PACK_DIR/packed-node-install.stdout.txt" 2>/dev/null || true'));
|
|
196
196
|
lines.push(...posixSection("PACKED_NODE_INSTALL_STDERR", 'cat "$PACK_DIR/packed-node-install.stderr.txt" 2>/dev/null || true'));
|
|
197
|
-
lines.push(`if [ "$PACKED_NODE_INSTALL_EXIT" -eq 0 ] && [ -n "$PI_CLI" ]; then (cd "$PI_PROJECT" && PI_OFFLINE=1 "$PI_CLI" install -l ./node_modules/${packageName} >"$PACK_DIR/pi-install.stdout.txt" 2>"$PACK_DIR/pi-install.stderr.txt"); PI_INSTALL_EXIT=$?; else echo "packed npm install failed or missing pi cli" >"$PACK_DIR/pi-install.stderr.txt"; PI_INSTALL_EXIT=1; fi`);
|
|
197
|
+
lines.push(`if [ "$PACKED_NODE_INSTALL_EXIT" -eq 0 ] && [ -n "$PI_CLI" ]; then (cd "$PI_PROJECT" && PI_OFFLINE=1 "$PI_CLI" install -l ./node_modules/${packageName} --approve >"$PACK_DIR/pi-install.stdout.txt" 2>"$PACK_DIR/pi-install.stderr.txt"); PI_INSTALL_EXIT=$?; else echo "packed npm install failed or missing pi cli" >"$PACK_DIR/pi-install.stderr.txt"; PI_INSTALL_EXIT=1; fi`);
|
|
198
198
|
lines.push('echo "PLATFORM_PI_INSTALL_EXIT=$PI_INSTALL_EXIT"');
|
|
199
199
|
lines.push(...posixSection("PI_INSTALL_STDOUT", 'cat "$PACK_DIR/pi-install.stdout.txt" 2>/dev/null || true'));
|
|
200
200
|
lines.push(...posixSection("PI_INSTALL_STDERR", 'cat "$PACK_DIR/pi-install.stderr.txt" 2>/dev/null || true'));
|
|
201
201
|
lines.push("");
|
|
202
202
|
lines.push('echo "=== pi list ==="');
|
|
203
|
-
lines.push('if [ -n "$PI_CLI" ]; then (cd "$PI_PROJECT" && PI_OFFLINE=1 "$PI_CLI" list >"$PACK_DIR/pi-list.stdout.txt" 2>"$PACK_DIR/pi-list.stderr.txt"); PI_LIST_EXIT=$?; else echo "missing pi cli" >"$PACK_DIR/pi-list.stderr.txt"; PI_LIST_EXIT=1; fi');
|
|
203
|
+
lines.push('if [ -n "$PI_CLI" ]; then (cd "$PI_PROJECT" && PI_OFFLINE=1 "$PI_CLI" list --approve >"$PACK_DIR/pi-list.stdout.txt" 2>"$PACK_DIR/pi-list.stderr.txt"); PI_LIST_EXIT=$?; else echo "missing pi cli" >"$PACK_DIR/pi-list.stderr.txt"; PI_LIST_EXIT=1; fi');
|
|
204
204
|
lines.push('echo "PLATFORM_PI_LIST_EXIT=$PI_LIST_EXIT"');
|
|
205
205
|
lines.push(...posixSection("PI_LIST_STDOUT", 'cat "$PACK_DIR/pi-list.stdout.txt" 2>/dev/null || true'));
|
|
206
206
|
lines.push(...posixSection("PI_LIST_STDERR", 'cat "$PACK_DIR/pi-list.stderr.txt" 2>/dev/null || true'));
|