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.
- package/CHANGELOG.md +40 -0
- package/README.md +49 -385
- package/docs/ORACLE_DESIGN.md +1 -1
- package/docs/development.md +99 -0
- package/docs/platform-smoke.md +18 -7
- package/docs/reference.md +338 -0
- package/extensions/oracle/index.ts +1 -0
- package/extensions/oracle/lib/poller.ts +3 -8
- package/extensions/oracle/lib/queue.ts +2 -4
- package/extensions/oracle/shared/browser-profile-helpers.d.mts +1 -0
- package/extensions/oracle/shared/browser-profile-helpers.mjs +32 -0
- package/extensions/oracle/worker/auth-bootstrap.mjs +35 -6
- package/extensions/oracle/worker/chatgpt-ui-helpers.d.mts +1 -0
- package/extensions/oracle/worker/chatgpt-ui-helpers.mjs +18 -13
- package/extensions/oracle/worker/chromium-cookie-source.mjs +50 -6
- package/extensions/oracle/worker/linux-chromium-cookie-source.d.mts +6 -0
- package/extensions/oracle/worker/linux-chromium-cookie-source.mjs +98 -0
- package/extensions/oracle/worker/run-job.mjs +34 -34
- package/package.json +12 -11
- package/platform-smoke.config.mjs +1 -22
- package/scripts/oracle-auth.test.mjs +35 -0
- package/scripts/oracle-chatgpt-preset-proof.mjs +50 -21
- package/scripts/oracle-cookie-import.test.mjs +204 -0
- package/scripts/oracle-model.test.mjs +24 -17
- package/scripts/oracle-real-smoke.mjs +30 -9
- package/scripts/platform-smoke/Dockerfile.ubuntu +3 -2
- package/scripts/platform-smoke/crabbox-runner.mjs +18 -6
- package/scripts/platform-smoke/doctor.mjs +58 -41
- package/scripts/platform-smoke/invariants.mjs +254 -26
- package/scripts/platform-smoke/platform-build-windows.ps1 +21 -17
- package/scripts/platform-smoke/targets.mjs +59 -30
- package/scripts/platform-smoke.mjs +47 -14
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Development and release reference
|
|
2
|
+
|
|
3
|
+
The [README](../README.md) is the user entry point. Architecture and lifecycle details live in [ORACLE_DESIGN.md](ORACLE_DESIGN.md).
|
|
4
|
+
|
|
5
|
+
## Host qualification
|
|
6
|
+
|
|
7
|
+
Required offline qualification targets are the latest stable official Pi and latest maintained fork `main`, resolving version/commit once per workflow run and retaining exact SDK/CLI evidence. Locked development dependencies are reproducible snapshots, not validation targets; the platform-smoke harness covers macOS, Linux, and Windows native with Chromium-family browsers. Pi `0.80.9+` 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.
|
|
8
|
+
|
|
9
|
+
Package install/use requires Node.js 22.19.0 or newer; platform smoke/release validation expects Node 24+ per `platform-smoke.config.mjs`.
|
|
10
|
+
|
|
11
|
+
Production hardening should keep focusing on UI drift detection, auth recovery, artifact capture, platform compatibility, and environment diagnostics.
|
|
12
|
+
|
|
13
|
+
## Automatic npm releases (maintainers)
|
|
14
|
+
|
|
15
|
+
The [shared release procedure](https://github.com/fitchmultz/.github#automatic-npm-releases) creates a reviewed patch-version PR after changes merge to `main`, then qualifies one retained candidate tarball across compatibility checks and hosted macOS, Ubuntu, and native Windows Crabbox suites before publishing the same version on npm and GitHub.
|
|
16
|
+
|
|
17
|
+
Before releasing runtime or prompt changes, verify [the `release:check` requirements](#verification) and [packed platform proof](platform-smoke.md). Fresh all-preset ChatGPT proof must match `HEAD` or an ancestor commit whose `extensions/` and `prompts/` trees are byte-identical to `HEAD`, satisfy the proof checker's 72-hour timing and saved-response requirements, and accompany the required doctor-first macOS/Ubuntu/native-Windows evidence. Authenticated and paid checks remain outside CI. Automated publication disables npm hooks to publish the checked bytes; manual `npm publish` still runs its existing `prepublishOnly` gate.
|
|
18
|
+
|
|
19
|
+
Set repository variable `NPM_RELEASE_ENABLED` to anything other than `true` to stop new version and release plans; cancel pending runs separately when needed. Follow the shared procedure to retry an unpublished candidate. Workflow validation is not evidence of a completed real OIDC publication.
|
|
20
|
+
|
|
21
|
+
## Verification
|
|
22
|
+
|
|
23
|
+
For credential-free latest-host qualification, use the shared qualifier with `--host official --target latest` and separately with the packed latest maintained fork revision. It selects a consistent host graph before running `npm run check:compat` with an empty HOME/agent profile. A plain `npm ci --ignore-scripts` uses only the locked development snapshot, not latest qualification. It runs the existing syntax, type, isolated sanity, and pack checks plus native Pi `/oracle-status` dispatch, asserting that no browser job is created. Sanity uses fixture browser/keychain commands and private job/state directories; it needs local archive utilities (`tar` and `zstd`), not browser credentials. This is source/host proof, not authenticated ChatGPT/Grok or packed cross-platform release proof. The older suggested floor is historical support guidance, not requalified by a current-host run.
|
|
24
|
+
|
|
25
|
+
Useful local checks:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm run check:oracle-extension
|
|
29
|
+
npm run check:platform-smoke
|
|
30
|
+
npm run typecheck
|
|
31
|
+
npm run typecheck:worker-helpers
|
|
32
|
+
npm run sanity:oracle
|
|
33
|
+
npm run pack:check
|
|
34
|
+
npm test
|
|
35
|
+
npm run verify:oracle
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`npm test` runs `npm run verify:oracle`, so it is not a separate gate from the final line above.
|
|
39
|
+
|
|
40
|
+
Known development dependency warning: the official Pi 1.0.0 npm package's `npm-shrinkwrap.json` still pins `brace-expansion` `5.0.9`, which has brace-expansion denial-of-service advisories. npm 11 preserves that vendor-pinned subtree even with a root override; dropping the shrinkwrap to obtain a clean audit is not a fix. The warning predates the Pi 1.0 baseline upgrade and needs an upstream host dependency fix. Dependencies embedded in a prebuilt Pi CLI bundle likewise require a fixed host distribution.
|
|
41
|
+
|
|
42
|
+
`npm publish` is guarded by `prepublishOnly`, which runs `npm run release:check`. That release gate now blocks unless fresh live ChatGPT preset proof exists for every canonical preset, then requires doctor-first macOS, Ubuntu, and Windows native Crabbox evidence. The required Crabbox runtime suite uses packed-install proof, not source-tree `pi -e` loading.
|
|
43
|
+
|
|
44
|
+
Use the narrowest validation workflow that proves the change:
|
|
45
|
+
|
|
46
|
+
| Situation | Command(s) |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| Everyday local iteration | `npm run verify:oracle` |
|
|
49
|
+
| Platform-focused syntax/invariant sanity | `npm run check:platform-smoke`, `npm run sanity:oracle:platform` |
|
|
50
|
+
| Platform-sensitive runtime changes | `npm run smoke:platform:doctor`, then a focused `node scripts/platform-smoke.mjs run --target <target> --suite <suite>` |
|
|
51
|
+
| Platform matrix proof | `npm run smoke:platform:all` |
|
|
52
|
+
| ChatGPT preset release proof | `npm run release:proof:chatgpt-presets` |
|
|
53
|
+
| Publish/release gate | `npm run release:check` |
|
|
54
|
+
|
|
55
|
+
For macOS, Ubuntu, and Windows native package/build plus packed runtime validation, use [`docs/platform-smoke.md`](platform-smoke.md). The full release gate is:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm run release:check
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Before a release, run live jobs through the loaded extension for every ChatGPT preset in `ORACLE_SUBMIT_PRESETS`. Each prompt must make the saved response contain exact markers `PRESET <preset> OK` and `PACKAGE pi-oracle`. After every job has completed, save the job ids/job directories in `.artifacts/chatgpt-preset-proof/latest.json`; `validatedAt` must be later than the completed jobs. Start from the checked, intentionally non-valid template:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
mkdir -p .artifacts/chatgpt-preset-proof
|
|
65
|
+
node scripts/oracle-chatgpt-preset-proof.mjs template > .artifacts/chatgpt-preset-proof/latest.json
|
|
66
|
+
npm run release:proof:chatgpt-presets
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The proof checker is intentionally part of `release:check`; it fails if the proof is missing, stale, tied to a commit whose `extensions/` or `prompts/` differ from `HEAD`, references jobs that completed before the proven commit, or lacks actual persisted ChatGPT `.tar.zst` job state and response text for any canonical preset.
|
|
70
|
+
|
|
71
|
+
The real runtime suite defaults to deterministic installed-tool execution so platform proof stays bounded. Provider/model defaults remain `zai/glm-5.2` 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.
|
|
72
|
+
|
|
73
|
+
For manual end-to-end local-extension smoke testing, use [`docs/ORACLE_ISOLATED_PI_VALIDATION.md`](ORACLE_ISOLATED_PI_VALIDATION.md). Ordinary pre-commit smoke runs can still use `instant` or `thinking_light`, but release proof must cover every canonical ChatGPT preset through the loaded extension.
|
|
74
|
+
|
|
75
|
+
## Implementation entry points
|
|
76
|
+
|
|
77
|
+
| Problem | Capability | Proof in this repo |
|
|
78
|
+
| --- | --- | --- |
|
|
79
|
+
| Hard tasks need more context than a quick turn should gather. | `/oracle` prompts the agent to preflight, choose a context-rich archive, and submit it to the selected provider web app. | [`prompts/oracle.md`](../prompts/oracle.md), `oracle_submit`, archive tests in `scripts/oracle-sanity-*` |
|
|
80
|
+
| Browser automation should not steal focus or mutate your active profile. | Jobs clone an authenticated seed profile into per-job isolated runtime profiles. | [`docs/ORACLE_DESIGN.md`](ORACLE_DESIGN.md), [`extensions/oracle/lib/runtime.ts`](../extensions/oracle/lib/runtime.ts) |
|
|
81
|
+
| Long jobs need durability. | Job state, responses, logs, and artifacts persist under `${PI_ORACLE_JOBS_DIR:-/tmp}/oracle-<job-id>/`. | [`extensions/oracle/lib/jobs.ts`](../extensions/oracle/lib/jobs.ts), `/oracle-read`, `/oracle-status` |
|
|
82
|
+
| Provider auth can expire or drift. | `/oracle-auth [chatgpt|grok]` refreshes the isolated auth seed from a configured local Chromium profile, with recovery guidance. | [`extensions/oracle/lib/auth.ts`](../extensions/oracle/lib/auth.ts), [`docs/ORACLE_RECOVERY_DRILL.md`](ORACLE_RECOVERY_DRILL.md) |
|
|
83
|
+
| Agents need a simple API, not UI-driving instructions. | The package exposes agent-facing tools: `oracle_preflight`, `oracle_submit`, `oracle_read`, `oracle_auth`, and `oracle_cancel`. | [`extensions/oracle/lib/tools.ts`](../extensions/oracle/lib/tools.ts) |
|
|
84
|
+
|
|
85
|
+
## Project map
|
|
86
|
+
|
|
87
|
+
| Path | Purpose |
|
|
88
|
+
| --- | --- |
|
|
89
|
+
| [`extensions/oracle/index.ts`](../extensions/oracle/index.ts) | Extension entrypoint |
|
|
90
|
+
| `extensions/oracle/lib/` | Commands, tools, config, jobs, queueing, runtime, poller |
|
|
91
|
+
| `extensions/oracle/worker/` | Detached provider web worker and UI/auth helpers |
|
|
92
|
+
| `extensions/oracle/shared/` | Shared process, state, job, and observability helpers |
|
|
93
|
+
| [`prompts/oracle.md`](../prompts/oracle.md) | Hidden `/oracle` command-dispatch workflow |
|
|
94
|
+
| [`prompts/oracle-followup.md`](../prompts/oracle-followup.md) | Hidden `/oracle-followup` command-dispatch workflow |
|
|
95
|
+
| `scripts/oracle-sanity-*` | Local sanity and archive-safety checks |
|
|
96
|
+
| `scripts/platform-smoke*` | Crabbox macOS, Ubuntu, and Windows release smoke gate |
|
|
97
|
+
| [`docs/ORACLE_DESIGN.md`](ORACLE_DESIGN.md) | Architecture, lifecycle, queueing, persistence, recovery behavior |
|
|
98
|
+
| [`docs/ORACLE_ISOLATED_PI_VALIDATION.md`](ORACLE_ISOLATED_PI_VALIDATION.md) | Repeatable isolated `pi` validation workflow |
|
|
99
|
+
| [`docs/ORACLE_RECOVERY_DRILL.md`](ORACLE_RECOVERY_DRILL.md) | Safe expired-auth recovery drill |
|
package/docs/platform-smoke.md
CHANGED
|
@@ -29,9 +29,10 @@ crabbox providers
|
|
|
29
29
|
|
|
30
30
|
Target setup:
|
|
31
31
|
|
|
32
|
-
- macOS: Remote Login enabled; noninteractive `ssh $USER@localhost` works; `node`, `npm`, `git`, `tar`, `rsync`, `zstd`, and `agent-browser` are on the SSH PATH.
|
|
32
|
+
- macOS: Remote Login enabled; noninteractive `ssh $USER@localhost` works; `node`, `npm`, `git`, `tar`, `rsync`, `zstd`, and `agent-browser` are on the SSH PATH. Use `PI_ORACLE_SMOKE_MAC_PORT` or `PLATFORM_SMOKE_MAC_PORT` for a non-default SSH port.
|
|
33
33
|
- Ubuntu: Docker is running and the configured image (`PI_ORACLE_SMOKE_UBUNTU_IMAGE`, default `pi-oracle-platform-smoke:node24`) has `node`, `npm`, `git`, `tar`, `rsync`, `zstd`, and `agent-browser` on PATH. Build the local image when needed with `docker build -t pi-oracle-platform-smoke:node24 -f scripts/platform-smoke/Dockerfile.ubuntu .`.
|
|
34
|
-
- Windows native: Parallels has stopped source VM `pi-extension-windows-template` and the configured power-off snapshot (`crabbox-ready` by default for this repo). The template must have OpenSSH, PowerShell, Git, Node/npm, `tar`, `zstd`, and `agent-browser` on PATH. Do not bake API keys, browser sessions, project checkouts, `.pi` state, artifacts, or secrets into the template.
|
|
34
|
+
- Windows native: by default, Parallels has stopped source VM `pi-extension-windows-template` and the configured power-off snapshot (`crabbox-ready` by default for this repo). The template must have OpenSSH, PowerShell, Git, Node/npm, `tar`, `zstd`, and `agent-browser` on PATH. Do not bake API keys, browser sessions, project checkouts, `.pi` state, artifacts, or secrets into the template.
|
|
35
|
+
- Alternatively, set `PI_ORACLE_SMOKE_WINDOWS_HOST` to a native Windows SSH host, and set `PI_ORACLE_SMOKE_WINDOWS_USER`, `PI_ORACLE_SMOKE_WINDOWS_PORT` (default 22), and `PI_ORACLE_SMOKE_WINDOWS_NATIVE_WORK_ROOT` for that target as needed. Crabbox uses its SSH provider instead of Parallels; the target needs the same tools on its SSH PATH. The `PLATFORM_SMOKE_WINDOWS_*` aliases also work.
|
|
35
36
|
|
|
36
37
|
Real runtime suite auth:
|
|
37
38
|
|
|
@@ -47,7 +48,7 @@ Use the narrowest workflow that proves the change. Do not run the full platform
|
|
|
47
48
|
| Situation | Canonical command(s) | What it proves |
|
|
48
49
|
| --- | --- | --- |
|
|
49
50
|
| Everyday local iteration | `npm run verify:oracle` | Syntax, bundle, platform-smoke invariants, type checks, oracle sanity, and package dry-run pass locally. |
|
|
50
|
-
| Platform-sensitive change | `
|
|
51
|
+
| Platform-sensitive change | `node scripts/platform-smoke.mjs doctor --target <target>`, 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
52
|
| Platform matrix proof | `npm run smoke:platform:all` | Doctor-first packed-install proof passes on every required target and suite. |
|
|
52
53
|
| ChatGPT preset release proof | `npm run release:proof:chatgpt-presets` | Fresh loaded-extension proof exists for every canonical ChatGPT preset. |
|
|
53
54
|
| Publish/release gate | `npm run release:check` | Local verification (`verify:oracle`) passes, fresh ChatGPT preset proof exists, then the doctor-first platform matrix passes. |
|
|
@@ -65,13 +66,19 @@ npm run smoke:platform:all
|
|
|
65
66
|
Focused commands:
|
|
66
67
|
|
|
67
68
|
```bash
|
|
68
|
-
|
|
69
|
+
node scripts/platform-smoke.mjs doctor --target macos
|
|
69
70
|
npm run smoke:platform:macos
|
|
71
|
+
node scripts/platform-smoke.mjs doctor --target ubuntu
|
|
70
72
|
npm run smoke:platform:ubuntu
|
|
73
|
+
node scripts/platform-smoke.mjs doctor --target windows-native
|
|
71
74
|
npm run smoke:platform:windows-native
|
|
72
75
|
node scripts/platform-smoke.mjs run --target windows-native --suite real-extension
|
|
73
76
|
```
|
|
74
77
|
|
|
78
|
+
`doctor --target` checks the selected targets' providers and tools; without it,
|
|
79
|
+
doctor still checks every required target. In split hosted jobs, run a scoped
|
|
80
|
+
doctor on each target before its suites.
|
|
81
|
+
|
|
75
82
|
Full release gate:
|
|
76
83
|
|
|
77
84
|
```bash
|
|
@@ -80,6 +87,10 @@ npm run release:check
|
|
|
80
87
|
|
|
81
88
|
`release:check` runs `verify:oracle`, then `release:proof:chatgpt-presets`, then `smoke:platform:all`, matching the release order: cheap harness checks, fresh live ChatGPT preset proof, doctor, full matrix, then artifact review. `prepublishOnly` runs `npm run release:check`.
|
|
82
89
|
|
|
90
|
+
For an already prepared release candidate, set `PI_ORACLE_RELEASE_TARBALL` to its local tarball before running the matrix. Set `PI_ORACLE_RELEASE_SHA256` to the prepared candidate's SHA-256 when one is available; the runner checks it before transfer. Each suite still checks that the source packs, but installs the retained candidate. Crabbox transfers a temporary copy and each target verifies its SHA-256 before use; the suite evidence records the verified hash.
|
|
91
|
+
|
|
92
|
+
The reusable [hosted platform qualification](../.github/workflows/release-platform.yml) runs each target on its native GitHub-hosted OS. It verifies the shared candidate receipt and source before and after both suites, and retains the per-target evidence. This is the platform portion of release qualification; the live ChatGPT preset proof is a separate required gate.
|
|
93
|
+
|
|
83
94
|
## What `platform-build` proves
|
|
84
95
|
|
|
85
96
|
On each required target, `platform-build`:
|
|
@@ -103,10 +114,10 @@ On each required target, `platform-build`:
|
|
|
103
114
|
2. installs the tarball into a clean pi project;
|
|
104
115
|
3. runs `pi install -l ./node_modules/pi-oracle --approve`;
|
|
105
116
|
4. asserts `pi list --approve` shows the packed install path;
|
|
106
|
-
5. executes `
|
|
107
|
-
6. asserts
|
|
117
|
+
5. executes the deterministic `/oracle-status` command through the installed extension's Pi loader;
|
|
118
|
+
6. asserts the command output came from the loaded packed extension and that the safe default path created no oracle job.
|
|
108
119
|
|
|
109
|
-
The default runtime suite executes the installed
|
|
120
|
+
The default runtime suite executes a deterministic command through the installed extension's Pi loader so platform proof is bounded instead of waiting on a model turn. Set `PI_ORACLE_REAL_TEST_MODEL_AGENT=1` only when you specifically need to debug the slower model-agent path. Symlink escape rejection and other negative archive cases are covered by `npm run sanity:oracle`; the optional second-agent negative check is available with `PI_ORACLE_REAL_TEST_NEGATIVE_SYMLINK=1` when debugging that path.
|
|
110
121
|
|
|
111
122
|
For inner-loop/debug only, use:
|
|
112
123
|
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
# Oracle reference
|
|
2
|
+
|
|
3
|
+
Start with the [README](../README.md) for installation and your first job. This page covers command details, browser configuration, provider controls, and troubleshooting.
|
|
4
|
+
|
|
5
|
+
## Installation options
|
|
6
|
+
|
|
7
|
+
Install from GitHub:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pi install https://github.com/fitchmultz/pi-oracle
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
To update the package later, use `pi update --extensions`, `pi update --all`, or `pi update npm:pi-oracle`. Bare `pi update` updates Pi itself only.
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
You need:
|
|
18
|
+
|
|
19
|
+
- macOS, Linux, or Windows native
|
|
20
|
+
- Node.js 22.19.0 or newer for package install/use; platform smoke/release validation currently expects Node 24+ per `platform-smoke.config.mjs`
|
|
21
|
+
- Suggested tested floor: `pi` 0.80.9 or newer; older pi versions are not blocked by package metadata but are outside the current validation baseline
|
|
22
|
+
- Google Chrome/Chromium or another Chromium-family browser
|
|
23
|
+
- ChatGPT or Grok already signed in to the configured local browser profile for the provider you plan to use
|
|
24
|
+
- `agent-browser` and `tar` available on the machine; `zstd` is also required when submitting ChatGPT `.tar.zst` archives
|
|
25
|
+
- on macOS APFS clone mode, `cp` available on PATH or via `PI_ORACLE_CP_PATH`; Linux/Windows runtime profile copies use Node's recursive copy
|
|
26
|
+
- a normal persisted `pi` session, not `pi --no-session`
|
|
27
|
+
- on Linux, encrypted Chromium cookies may also require `secret-tool` (GNOME/libsecret) or `kwallet-query` + `dbus-send` (KDE), unless a Chrome/Brave safe-storage password override is set for the auth run
|
|
28
|
+
|
|
29
|
+
`agent-browser` has its own Node.js requirements, which may be newer than Oracle's package minimum.
|
|
30
|
+
If npm blocks `agent-browser`'s install script, allow it when installing the global package:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install -g --allow-scripts=agent-browser agent-browser
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## What a successful run looks like
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
You: /oracle Review the pending changes. Include the whole repo unless a narrower archive is clearly better.
|
|
40
|
+
|
|
41
|
+
pi-oracle:
|
|
42
|
+
1. preflights local session/auth readiness
|
|
43
|
+
2. builds a context-rich provider archive (`.tar.zst` for ChatGPT, `.tar.gz` for Grok)
|
|
44
|
+
3. starts an isolated provider web runtime in the background
|
|
45
|
+
4. uploads the archive and prompt to the selected provider
|
|
46
|
+
5. saves the response/artifacts under /tmp/oracle-<job-id>/
|
|
47
|
+
6. sends a best-effort wake-up back to the matching pi session
|
|
48
|
+
|
|
49
|
+
Later: /oracle-read <job-id>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
What you are seeing: the local `pi` agent keeps control of context selection and safety checks, while the selected web provider handles the expensive second-opinion work asynchronously. If the wake-up is missed, the result still lives on disk and can be read by job id.
|
|
53
|
+
|
|
54
|
+
## Dispatch details
|
|
55
|
+
|
|
56
|
+
After you submit an `/oracle` request:
|
|
57
|
+
|
|
58
|
+
- The `/oracle` prompt now runs an early oracle preflight before expensive repo reading or archive creation.
|
|
59
|
+
- The agent chooses a context-rich relevant archive up to the selected provider's upload ceiling, not the smallest possible one-file slice when nearby context helps.
|
|
60
|
+
- `oracle_submit` creates or queues a job.
|
|
61
|
+
- If local packing is too large, the prompt treats that as a retryable archive-selection failure and narrows automatically before surfacing the problem.
|
|
62
|
+
- The job uploads a repo archive to the selected provider, capped at 250 MiB for ChatGPT or 200 MiB for Grok after default exclusions/pruning.
|
|
63
|
+
- The response is saved under `/tmp/oracle-<job-id>/response.md` by default.
|
|
64
|
+
- The matching `pi` session gets one best-effort wake-up when the job finishes.
|
|
65
|
+
|
|
66
|
+
If the wake-up does not arrive, run:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
/oracle-status
|
|
70
|
+
/oracle-read <job-id>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Example requests
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
/oracle Review the current pending changes. Include the whole repo unless a narrower archive is clearly better. Give me a prioritized code review with concrete fixes.
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
/oracle Read the codebase and explain the highest-risk auth/session failure modes, including what to test before shipping.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
/oracle Explain the Oracle reference guidance for /oracle-clean retention grace. Archive docs/reference.md plus any nearby docs or implementation files that help answer accurately.
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
/oracle-followup <job-id> Tighten the migration plan around rollback risk, and include the most relevant surrounding files/docs as long as the archive stays comfortably within the 250 MiB limit.
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
/oracle Continue existing ChatGPT conversation 6a28ab5c-e4d4-83e8-b8be-dd39f38a26d6. Review the current auth code and include enough surrounding context to propose concrete fixes.
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## How it works
|
|
96
|
+
|
|
97
|
+
```mermaid
|
|
98
|
+
flowchart LR
|
|
99
|
+
A["/oracle request"] --> B["Agent preflights, then gathers a context-rich relevant repo slice"]
|
|
100
|
+
B --> C["Agent chooses context-rich archive inputs"]
|
|
101
|
+
C --> D["oracle_submit builds provider-specific archive"]
|
|
102
|
+
D --> E["Detached worker clones isolated auth seed profile"]
|
|
103
|
+
E --> F["Selected provider receives archive + prompt"]
|
|
104
|
+
F --> G["Response/artifacts saved under oracle job dir"]
|
|
105
|
+
G --> H["Best-effort wake-up to matching pi session"]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Key design choices:
|
|
109
|
+
|
|
110
|
+
- **Extension-managed dispatch owns context gathering.** In the TUI, `/oracle` and `/oracle-followup` are intercepted before prompt-template expansion, re-added as compact user messages for prompt-history/up-arrow recall, and paired with detailed dispatch instructions as hidden context. The visible transcript stays compact while the agent still preflights, gathers context, chooses archive inputs, and stops after dispatch.
|
|
111
|
+
- **Tools own execution.** `oracle_submit` builds the archive, admits or queues the job, starts the worker, and returns immediately.
|
|
112
|
+
- **Auth uses a seed profile.** `/oracle-auth` imports cookies into an isolated seed profile; each job clones that seed into its own temporary runtime profile.
|
|
113
|
+
- **Follow-ups preserve provider thread state.** `/oracle-followup <job-id> ...` resolves the prior job's saved provider URL and submits the next prompt with `followUpJobId`.
|
|
114
|
+
- **Existing ChatGPT browser threads are opt-in.** Normal `/oracle` jobs still start a fresh provider thread. When the user explicitly provides a ChatGPT conversation id or `https://chatgpt.com/c/...` URL, the agent passes `chatGptConversationId` so `oracle_submit` opens that existing thread in the isolated runtime.
|
|
115
|
+
- **Wake-up is best effort, storage is durable.** A missed wake-up does not lose the result.
|
|
116
|
+
|
|
117
|
+
## Commands and tools
|
|
118
|
+
|
|
119
|
+
User-facing commands:
|
|
120
|
+
|
|
121
|
+
- `/oracle <request>` — prepare context and dispatch a ChatGPT or Grok web oracle job. If the request explicitly includes an existing ChatGPT conversation id/URL, the agent can continue that browser-created thread; otherwise `/oracle` starts a fresh thread as before.
|
|
122
|
+
- `/oracle-followup <job-id> <request>` — continue an earlier oracle job in the same provider thread
|
|
123
|
+
- `/oracle-auth [chatgpt|grok]` — sync provider cookies into the isolated oracle auth seed profile
|
|
124
|
+
- `/oracle-read [job-id]` — inspect job status and saved response preview
|
|
125
|
+
- `/oracle-status [job-id]` — inspect a job or list recent job ids when no explicit id is given
|
|
126
|
+
- `/oracle-cancel <job-id>` — cancel a queued or active job
|
|
127
|
+
- `/oracle-clean <job-id|all>` — remove temp files for terminal jobs; recently woken terminal jobs may stay retained briefly, and a blocked cleanup returns the next eligible cleanup time
|
|
128
|
+
|
|
129
|
+
Agent-facing tools:
|
|
130
|
+
|
|
131
|
+
- `oracle_preflight`
|
|
132
|
+
- `oracle_auth`
|
|
133
|
+
- `oracle_submit` (`chatGptConversationId` is optional and only for explicitly continuing an existing ChatGPT browser conversation id/URL; omit it for the default fresh thread)
|
|
134
|
+
- `oracle_read`
|
|
135
|
+
- `oracle_cancel`
|
|
136
|
+
|
|
137
|
+
## Configuration
|
|
138
|
+
|
|
139
|
+
Most users can start with defaults. Set an agent-level config only when you need a non-default provider, mode, preset, or browser profile.
|
|
140
|
+
|
|
141
|
+
Pi 0.79+ 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.
|
|
142
|
+
|
|
143
|
+
`~/.pi/agent/extensions/oracle.json`
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"defaults": {
|
|
148
|
+
"provider": "chatgpt",
|
|
149
|
+
"preset": "pro_extended",
|
|
150
|
+
"grokMode": "heavy"
|
|
151
|
+
},
|
|
152
|
+
"auth": {
|
|
153
|
+
"chromeProfile": "Default"
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Notes:
|
|
159
|
+
|
|
160
|
+
- `defaults.provider` is the default web provider: `chatgpt` or `grok`.
|
|
161
|
+
- `defaults.preset` is the default ChatGPT model preset for oracle jobs.
|
|
162
|
+
- `defaults.grokMode` is the default Grok mode. Only `heavy` is supported today.
|
|
163
|
+
- The canonical preset ids and provider modes live in [`extensions/oracle/lib/config.ts`](../extensions/oracle/lib/config.ts).
|
|
164
|
+
- If the packaged default is fine, omit `defaults`.
|
|
165
|
+
- When an agent is unsure which oracle preset fits, it should omit `preset` and use the configured default model instead of asking by default. If the prompt says to use Grok, it should pass `provider: "grok"` to `oracle_submit`.
|
|
166
|
+
- You usually do not need browser paths unless auto-detection fails.
|
|
167
|
+
|
|
168
|
+
### Linux cookie import notes
|
|
169
|
+
|
|
170
|
+
`/oracle-auth` uses `@steipete/sweet-cookie`'s public Chrome backend to parse and decrypt Linux cookies. The packaged default auto-detects existing Google Chrome, Chromium, Chromium Browser, or Brave profile roots under `${XDG_CONFIG_HOME:-~/.config}` and passes non-Google roots as absolute profile paths. For native `chromium` and `chromium-browser` profiles or `Cookies` DBs under those roots, Oracle selects **Chromium Safe Storage** rather than Chrome's key, including GNOME application lookup fallback and KDE KWallet. The Linux key-selection module loads only when needed and reuses the worker's existing public cookie getter; ordinary calibrated Chrome-password paths bypass it. Set `auth.chromeProfile` to another profile name, a profile directory, or a `Cookies` DB path when needed, and leave `auth.chromiumKeychain` unset on Linux. Profile names alone still select Google Chrome; relocated, Snap, and Flatpak Chromium sources are outside this automatic key-selection boundary.
|
|
171
|
+
|
|
172
|
+
Linux encrypted-cookie handling is controlled outside pi-oracle:
|
|
173
|
+
|
|
174
|
+
- `SWEET_COOKIE_LINUX_KEYRING=gnome|kwallet|basic` selects GNOME/libsecret, KDE KWallet, or no keyring probing.
|
|
175
|
+
- GNOME probing shells out to `secret-tool`; KDE probing shells out to `kwallet-query` and `dbus-send`.
|
|
176
|
+
- `SWEET_COOKIE_CHROME_SAFE_STORAGE_PASSWORD` (also for a selected Chromium source) and `SWEET_COOKIE_BRAVE_SAFE_STORAGE_PASSWORD` bypass keyring probing when you already know the browser safe-storage password.
|
|
177
|
+
|
|
178
|
+
Do not put safe-storage passwords in project config or persistent shell startup files. Prefer keyring helpers when possible. Oracle's native Chromium adapter scrubs password overrides from keyring subprocesses, uses the obtained password only around the public cookie read in the short-lived auth worker, and restores its prior environment in `finally`. Browser/helper subprocesses launched by Oracle receive a scrubbed environment; this guarantee does not cover upstream fallback helpers for unqualified sources. The parent Pi environment and persistent config are not changed.
|
|
179
|
+
|
|
180
|
+
### Custom Chromium cookie sources
|
|
181
|
+
|
|
182
|
+
Chrome-compatible browsers can use Sweet Cookie's default Chrome backend when `auth.chromeProfile` points at the right profile or cookie DB and the matching safe-storage key is available. On Linux, automatic Chromium-specific key selection is limited to the native roots described above; for relocated Chromium profiles use the matching Chrome or Brave password override for that auth run. Outside the confirmed native roots, Sweet Cookie 0.3 still selects Brave when the resolved cookie DB path contains `bravesoftware`, `brave-browser`, or `brave browser` (case-insensitive), even in an ancestor directory; such paths may require the Brave override. pi-oracle does not currently select Sweet Cookie's Edge or Firefox backends. The `auth.chromiumKeychain` alternate path is macOS-only and is intended for a Chromium-family browser that is not one of Sweet Cookie's built-in Chrome/Brave/Arc/Chromium targets or otherwise cannot import cookies without dependency patching.
|
|
183
|
+
|
|
184
|
+
Before running `/oracle-auth` with this macOS path:
|
|
185
|
+
|
|
186
|
+
1. Log into ChatGPT or Grok in the target browser profile, depending on `defaults.provider`.
|
|
187
|
+
2. Fully quit the browser so its `Cookies` database is stable.
|
|
188
|
+
3. Find the profile `Cookies` SQLite DB path.
|
|
189
|
+
4. Find the browser's macOS Keychain safe-storage item account and service name.
|
|
190
|
+
5. Configure all of `browser.executablePath`, `auth.chromeCookiePath`, and `auth.chromiumKeychain` in `~/.pi/agent/extensions/oracle.json`.
|
|
191
|
+
|
|
192
|
+
Example macOS Helium config:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"browser": {
|
|
197
|
+
"executablePath": "/Applications/Helium.app/Contents/MacOS/Helium"
|
|
198
|
+
},
|
|
199
|
+
"auth": {
|
|
200
|
+
"chromeProfile": "Default",
|
|
201
|
+
"chromeCookiePath": "/Users/you/Library/Application Support/net.imput.helium/Default/Cookies",
|
|
202
|
+
"chromiumKeychain": {
|
|
203
|
+
"account": "Helium",
|
|
204
|
+
"services": ["Helium Storage Key"],
|
|
205
|
+
"label": "Helium Storage Key"
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
`auth.chromeCookiePath` remains the cookie database path for backward compatibility. On macOS, `auth.chromiumKeychain` must be paired with `auth.chromeCookiePath`; partial config is rejected so oracle does not silently fall back to a different browser source. When both are present on macOS, `/oracle-auth` uses pi-oracle's repo-owned generic Chromium cookie reader instead of patching `@steipete/sweet-cookie` internals. On Linux, `auth.chromiumKeychain` is rejected; use Sweet Cookie's Linux keyring/password environment options instead.
|
|
212
|
+
|
|
213
|
+
If macOS prompts for Keychain access during `/oracle-auth`, allow access for the configured browser safe-storage item. If auth still fails after cookies are synced, the cookie DB may be stale, from the wrong profile, or for an account that is logged out; reopen the configured browser profile, confirm ChatGPT works there, quit the browser, and rerun `/oracle-auth`. On Linux, inspect `/oracle-auth` diagnostics for Sweet Cookie warnings about `secret-tool`, `kwallet-query`, or safe-storage password overrides.
|
|
214
|
+
|
|
215
|
+
## Available providers and presets
|
|
216
|
+
|
|
217
|
+
| Provider | Mode / preset | Archive format | Upload ceiling |
|
|
218
|
+
| --- | --- | --- | --- |
|
|
219
|
+
| ChatGPT | Presets below | `.tar.zst` | 250 MiB |
|
|
220
|
+
| Grok | `heavy` only | `.tar.gz` | 200 MiB |
|
|
221
|
+
|
|
222
|
+
Grok uploads now use `.tar.gz` archives. Grok may accept `.tar.zst` uploads, but its execution environment can lack `zstd` tooling to extract them; gzip-compressed tar keeps extraction on standard tools. Manual testing against `https://grok.com` found a 200 MiB upload is accepted and a 200 MiB + 1 byte upload is rejected, so pi-oracle caps Grok archives at 200 MiB.
|
|
223
|
+
|
|
224
|
+
## Available ChatGPT presets
|
|
225
|
+
|
|
226
|
+
| Preset id | Description |
|
|
227
|
+
| --- | --- |
|
|
228
|
+
| `pro_standard` | Pro - Standard |
|
|
229
|
+
| `pro_extended` | Pro - Extended |
|
|
230
|
+
| `thinking_light` | Thinking - Light |
|
|
231
|
+
| `thinking_standard` | Thinking - Standard |
|
|
232
|
+
| `thinking_extended` | Thinking - Extended |
|
|
233
|
+
| `thinking_heavy` | Thinking - Heavy |
|
|
234
|
+
| `instant` | Instant |
|
|
235
|
+
| `instant_auto_switch` | Instant - Auto-switch to Thinking Enabled |
|
|
236
|
+
|
|
237
|
+
For ChatGPT, `oracle_submit` accepts canonical preset ids or a matching human-readable preset label. Keep config values on canonical ids. For Grok, use `provider: "grok"`; only Heavy is supported today.
|
|
238
|
+
|
|
239
|
+
ChatGPT's compact picker and current **Power** slider expose fewer choices than the legacy settings dialog: both Instant presets use Instant when no auto-switch toggle exists; Thinking Light/Standard use Medium, Extended uses High, and Heavy uses Extra High. Both Pro presets use the single Pro tier when separate effort choices are unavailable. Oracle verifies the visible selection rather than assuming the saved preference.
|
|
240
|
+
|
|
241
|
+
## Outputs and cleanup
|
|
242
|
+
|
|
243
|
+
- Jobs persist response text, metadata, logs, and artifacts under `${PI_ORACLE_JOBS_DIR:-/tmp}/oracle-<job-id>/` by default.
|
|
244
|
+
- Jobs can queue automatically when runtime capacity is full.
|
|
245
|
+
- Completion delivery into `pi` is one-time best-effort wake-up based.
|
|
246
|
+
- `/oracle-read [job-id]` and `oracle_read({ jobId })` inspect saved output later.
|
|
247
|
+
- `/oracle-clean` removes terminal job temp files, but can briefly refuse cleanup after a wake-up so the follow-up turn can still read the saved paths.
|
|
248
|
+
|
|
249
|
+
### Job retention
|
|
250
|
+
|
|
251
|
+
Oracle automatically deletes completed and cancelled jobs after 14 days, and failed jobs after 30 days, by default. Retention starts at completion, or creation when no completion timestamp exists. Cleanup runs at session start, on submission, and during `/oracle-auth`; it can be delayed by active notification or cleanup guards.
|
|
252
|
+
|
|
253
|
+
Set these keys in `~/.pi/agent/extensions/oracle.json` to change retention for new jobs. Values use milliseconds. Each job keeps the settings from its submission.
|
|
254
|
+
|
|
255
|
+
| Key | Default |
|
|
256
|
+
| --- | --- |
|
|
257
|
+
| `cleanup.completeJobRetentionMs` | `1209600000` — 14 days, for completed and cancelled jobs |
|
|
258
|
+
| `cleanup.failedJobRetentionMs` | `2592000000` — 30 days, for failed jobs |
|
|
259
|
+
|
|
260
|
+
Copy answers and artifacts you need to keep. Temporary storage can be cleared before the retention period ends.
|
|
261
|
+
|
|
262
|
+
## Privacy and local data
|
|
263
|
+
|
|
264
|
+
This extension is local-first, but it handles sensitive local and project data:
|
|
265
|
+
|
|
266
|
+
- `/oracle-auth` reads provider cookies from the configured local browser profile. Use `/oracle-auth grok` for Grok when ChatGPT remains the default provider.
|
|
267
|
+
- `oracle_submit` uploads selected project archives to the selected provider web app.
|
|
268
|
+
- Responses, logs, and artifacts are written to the configured oracle jobs directory.
|
|
269
|
+
|
|
270
|
+
Review the code and design docs before using it with private or regulated material.
|
|
271
|
+
|
|
272
|
+
## Current limits
|
|
273
|
+
|
|
274
|
+
- Experimental public beta, validated on macOS, Linux, and Windows native with Chromium-family browsers.
|
|
275
|
+
- Provider UI, auth, model controls, and artifact download behavior can drift.
|
|
276
|
+
- Archive uploads are capped at 250 MiB for ChatGPT and 200 MiB for Grok after default exclusions and automatic whole-repo pruning.
|
|
277
|
+
- A real ChatGPT or Grok web session is required for the provider you use.
|
|
278
|
+
- Cookie replay uses domain-based browser commands and does not preserve host-only or partitioned-cookie isolation metadata.
|
|
279
|
+
|
|
280
|
+
## Troubleshooting
|
|
281
|
+
|
|
282
|
+
### `/oracle-auth` fails or says login is required
|
|
283
|
+
|
|
284
|
+
- Make sure the selected provider works in the same local browser profile you configured.
|
|
285
|
+
- For custom Chromium cookie sources, confirm `auth.chromeCookiePath` points at that profile's `Cookies` DB. On macOS, also confirm `auth.chromiumKeychain.services` names the browser's safe-storage Keychain service. On Linux, leave `auth.chromiumKeychain` unset and use Sweet Cookie's `SWEET_COOKIE_LINUX_KEYRING`, `SWEET_COOKIE_CHROME_SAFE_STORAGE_PASSWORD`, or `SWEET_COOKIE_BRAVE_SAFE_STORAGE_PASSWORD` options for encrypted Chrome/Chromium/Brave cookies.
|
|
286
|
+
- Re-run `/oracle-auth`.
|
|
287
|
+
- Agent callers can use `oracle_auth({})` once before retrying a stale-auth oracle submission.
|
|
288
|
+
- If ChatGPT reports an anonymous visitor session, sign in in the configured **source browser profile**, quit that browser fully, and rerun `/oracle-auth`. This command imports an existing login; the isolated verification window is not a manual-login setup flow.
|
|
289
|
+
- Navigation interruptions during verification are retried until the auth deadline. A closed browser or verification timeout does not by itself mean the source cookies are invalid; leave the isolated window open and inspect the printed diagnostics if retries fail.
|
|
290
|
+
- If the provider presents a challenge and Oracle explicitly leaves the headed auth browser open, complete the challenge there and retry.
|
|
291
|
+
|
|
292
|
+
### Custom Chromium auth says cookies synced but the session is rejected
|
|
293
|
+
|
|
294
|
+
This usually means the cookie import worked but the source cookies are not the active provider session you expected.
|
|
295
|
+
|
|
296
|
+
1. Open the configured browser profile.
|
|
297
|
+
2. Confirm the selected provider works there without logging in again.
|
|
298
|
+
3. Quit the browser fully so its `Cookies` DB is stable.
|
|
299
|
+
4. Confirm `auth.chromeCookiePath` points at that exact profile's `Cookies` DB.
|
|
300
|
+
5. On macOS, confirm `auth.chromiumKeychain.services` names the browser's safe-storage Keychain service for that DB. On Linux, confirm the relevant Sweet Cookie keyring helper or Chrome/Brave safe-storage password override is available.
|
|
301
|
+
6. Re-run `/oracle-auth`.
|
|
302
|
+
|
|
303
|
+
### You hit a challenge or verification page
|
|
304
|
+
|
|
305
|
+
- Solve it in the auth/bootstrap browser if prompted.
|
|
306
|
+
- Re-run `/oracle-auth` before submitting jobs again.
|
|
307
|
+
|
|
308
|
+
### You see "Oracle requires a persisted pi session"
|
|
309
|
+
|
|
310
|
+
- Do not run oracle from `pi --no-session`.
|
|
311
|
+
- Start a normal persisted `pi` session, then use `/oracle` again.
|
|
312
|
+
|
|
313
|
+
### A job finished but no wake-up arrived
|
|
314
|
+
|
|
315
|
+
- Use `/oracle-read [job-id]` to inspect the saved response preview.
|
|
316
|
+
- Use `/oracle-status` if you need help finding a recent job id.
|
|
317
|
+
- Agent callers can use `oracle_read({ jobId })`.
|
|
318
|
+
- Results are still saved on disk even if the reminder turn does not land.
|
|
319
|
+
|
|
320
|
+
### `/oracle-clean` refuses a terminal job right after completion
|
|
321
|
+
|
|
322
|
+
- This can happen during the short post-send retention grace window after a wake-up was sent.
|
|
323
|
+
- The command returns a `Retry after ...` timestamp when that guard is active.
|
|
324
|
+
- Wait until that time, then rerun `/oracle-clean <job-id|all>`.
|
|
325
|
+
|
|
326
|
+
### A local dependency like `agent-browser`, `tar`, or `zstd` is missing
|
|
327
|
+
|
|
328
|
+
Install the missing local dependency and rerun the command. `zstd` is only needed for ChatGPT `.tar.zst` archive submissions; Grok submissions use `.tar.gz`. On macOS APFS clone mode, `cp` must also be available on PATH or configured with `PI_ORACLE_CP_PATH`; Linux and Windows profile copies use Node's recursive copy.
|
|
329
|
+
|
|
330
|
+
### Auto-detection picked the wrong browser profile
|
|
331
|
+
|
|
332
|
+
- Set `auth.chromeProfile` in `~/.pi/agent/extensions/oracle.json`.
|
|
333
|
+
- For custom Chromium cookie sources, set `auth.chromeCookiePath` to the exact profile `Cookies` DB. Pair it with `auth.chromiumKeychain` only on macOS; on Linux, rely on Sweet Cookie's keyring/password environment options.
|
|
334
|
+
- Re-run `/oracle-auth`.
|
|
335
|
+
|
|
336
|
+
### You want more details about a failed run
|
|
337
|
+
|
|
338
|
+
Inspect the job directory under `${PI_ORACLE_JOBS_DIR:-/tmp}/oracle-<job-id>/`. The worker log and captured diagnostics are stored there.
|
|
@@ -118,6 +118,7 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
pi.on("before_agent_start", async (event) => {
|
|
121
|
+
if (!("prompt" in event)) return;
|
|
121
122
|
const parsed = parseOracleInput(event.prompt);
|
|
122
123
|
if (!parsed?.args || (parsed.command === "oracle-followup" && !/^\S+\s+\S/.test(parsed.args))) return;
|
|
123
124
|
const template = parsed.command === "oracle" ? oraclePrompt : oracleFollowupPrompt;
|
|
@@ -67,12 +67,9 @@ interface OracleWakeupTargetLeaseMetadata {
|
|
|
67
67
|
type OraclePollerJob = NonNullable<ReturnType<typeof readJob>>;
|
|
68
68
|
|
|
69
69
|
export interface OraclePollerHooks {
|
|
70
|
-
collectLiveWakeupTargets?: (now?: number) => Promise<Set<string>>;
|
|
71
70
|
beforeNotificationClaim?: (jobId: string) => Promise<void> | void;
|
|
72
71
|
afterNotificationClaim?: (job: OraclePollerJob) => Promise<void> | void;
|
|
73
72
|
beforeNotificationPersist?: (job: OraclePollerJob) => Promise<void> | void;
|
|
74
|
-
afterNotificationPersisted?: (job: OraclePollerJob) => Promise<void> | void;
|
|
75
|
-
beforeMarkJobNotified?: (job: OraclePollerJob) => Promise<void> | void;
|
|
76
73
|
}
|
|
77
74
|
|
|
78
75
|
export interface OraclePollerOptions {
|
|
@@ -228,7 +225,6 @@ async function scan(
|
|
|
228
225
|
const sessionId = getSessionId(currentSessionFile, projectId);
|
|
229
226
|
const processStartedAt = readProcessStartedAt(process.pid);
|
|
230
227
|
const wakeupTargetLeaseKey = getWakeupTargetLeaseKey(pollerKey, process.pid, processStartedAt || "unknown");
|
|
231
|
-
const resolveLiveWakeupTargets = hooks.collectLiveWakeupTargets ?? collectLiveWakeupTargets;
|
|
232
228
|
await writeLeaseMetadata(WAKEUP_TARGET_LEASE_KIND, wakeupTargetLeaseKey, {
|
|
233
229
|
leaseKey: wakeupTargetLeaseKey,
|
|
234
230
|
projectId,
|
|
@@ -239,7 +235,7 @@ async function scan(
|
|
|
239
235
|
}).catch(() => undefined);
|
|
240
236
|
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) return;
|
|
241
237
|
|
|
242
|
-
const liveWakeupTargets = await
|
|
238
|
+
const liveWakeupTargets = await collectLiveWakeupTargets();
|
|
243
239
|
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) return;
|
|
244
240
|
|
|
245
241
|
try {
|
|
@@ -294,7 +290,7 @@ async function scan(
|
|
|
294
290
|
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
295
291
|
return;
|
|
296
292
|
}
|
|
297
|
-
const preNotifyLiveWakeupTargets = await
|
|
293
|
+
const preNotifyLiveWakeupTargets = await collectLiveWakeupTargets();
|
|
298
294
|
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
299
295
|
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
300
296
|
return;
|
|
@@ -319,7 +315,7 @@ async function scan(
|
|
|
319
315
|
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
320
316
|
return;
|
|
321
317
|
}
|
|
322
|
-
const preWakeupLiveWakeupTargets = await
|
|
318
|
+
const preWakeupLiveWakeupTargets = await collectLiveWakeupTargets();
|
|
323
319
|
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
324
320
|
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
325
321
|
return;
|
|
@@ -347,7 +343,6 @@ async function scan(
|
|
|
347
343
|
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
348
344
|
return;
|
|
349
345
|
}
|
|
350
|
-
await hooks.beforeMarkJobNotified?.(deliverable);
|
|
351
346
|
await markJobNotified(jobId, notificationClaimant, {
|
|
352
347
|
notificationSessionKey: pollerKey,
|
|
353
348
|
notificationSessionFile: currentSessionFile,
|
|
@@ -27,7 +27,6 @@ export interface PromoteQueuedJobsOptions {
|
|
|
27
27
|
source: string;
|
|
28
28
|
lockTimeoutMs?: number;
|
|
29
29
|
spawnWorkerFn?: typeof spawnWorker;
|
|
30
|
-
loadConfigFn?: typeof loadOracleConfig;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
function isQueuedJob(job: OracleJob | undefined): job is OracleJob {
|
|
@@ -70,7 +69,6 @@ async function failQueuedPromotion(job: OracleJob, message: string, at: string):
|
|
|
70
69
|
|
|
71
70
|
export async function promoteQueuedJobsWithinAdmissionLock(options: PromoteQueuedJobsOptions): Promise<{ promotedJobIds: string[] }> {
|
|
72
71
|
const spawnWorkerFn = options.spawnWorkerFn ?? spawnWorker;
|
|
73
|
-
const loadConfigFn = options.loadConfigFn ?? loadOracleConfig;
|
|
74
72
|
|
|
75
73
|
return runQueuedJobPromotionPass<OracleJob, Awaited<ReturnType<typeof spawnWorkerFn>>>({
|
|
76
74
|
listQueuedJobs,
|
|
@@ -78,7 +76,7 @@ export async function promoteQueuedJobsWithinAdmissionLock(options: PromoteQueue
|
|
|
78
76
|
readLatestJob: (jobId) => readJob(jobId),
|
|
79
77
|
isQueuedJob,
|
|
80
78
|
acquireRuntimeLease: async (job, at) => {
|
|
81
|
-
const config = job.config ??
|
|
79
|
+
const config = job.config ?? loadOracleConfig(job.cwd);
|
|
82
80
|
const attempt = await tryAcquireRuntimeLease(config, buildRuntimeLeaseMetadata(job, at));
|
|
83
81
|
return attempt.acquired;
|
|
84
82
|
},
|
|
@@ -92,7 +90,7 @@ export async function promoteQueuedJobsWithinAdmissionLock(options: PromoteQueue
|
|
|
92
90
|
await releaseRuntimeLease(job.runtimeId);
|
|
93
91
|
},
|
|
94
92
|
markSubmitted: async (job, at) => {
|
|
95
|
-
const config = job.config ??
|
|
93
|
+
const config = job.config ?? loadOracleConfig(job.cwd);
|
|
96
94
|
await updateJob(job.id, (latest) => {
|
|
97
95
|
if (latest.status !== "queued") {
|
|
98
96
|
throw new Error(`Queued job ${latest.id} changed state during promotion (${latest.status})`);
|
|
@@ -26,6 +26,7 @@ export function expandHomePath(value: string, homeDir?: string): string;
|
|
|
26
26
|
export function normalizedAbsolutePath(value: string, options?: BrowserPathOptions): string;
|
|
27
27
|
export function linuxConfigHome(options?: BrowserPathOptions): string;
|
|
28
28
|
export function linuxChromiumCookieImportUserDataDirs(options?: BrowserPathOptions): string[];
|
|
29
|
+
export function isNativeLinuxChromiumCookieSource(source: string, options?: BrowserPathOptions): boolean;
|
|
29
30
|
export function linuxBrowserSafetyUserDataDirs(options?: BrowserPathOptions): string[];
|
|
30
31
|
export function browserUserDataDirsForPlatform(
|
|
31
32
|
platform?: OraclePlatform,
|