pi-oracle 0.3.3 → 0.4.0
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 +33 -0
- package/README.md +7 -0
- package/docs/ORACLE_DESIGN.md +1 -1
- package/docs/ORACLE_ISOLATED_PI_VALIDATION.md +249 -0
- package/docs/ORACLE_RECOVERY_DRILL.md +5 -4
- package/extensions/oracle/index.ts +8 -1
- package/extensions/oracle/lib/commands.ts +11 -24
- package/extensions/oracle/lib/config.ts +5 -0
- package/extensions/oracle/lib/jobs.ts +117 -217
- package/extensions/oracle/lib/locks.ts +41 -209
- package/extensions/oracle/lib/poller.ts +14 -51
- package/extensions/oracle/lib/queue.ts +75 -112
- package/extensions/oracle/lib/runtime.ts +60 -14
- package/extensions/oracle/lib/tools.ts +70 -67
- package/extensions/oracle/shared/job-coordination-helpers.d.mts +84 -0
- package/extensions/oracle/shared/job-coordination-helpers.mjs +168 -0
- package/extensions/oracle/shared/job-lifecycle-helpers.d.mts +130 -0
- package/extensions/oracle/shared/job-lifecycle-helpers.mjs +377 -0
- package/extensions/oracle/shared/job-observability-helpers.d.mts +59 -0
- package/extensions/oracle/shared/job-observability-helpers.mjs +143 -0
- package/extensions/oracle/shared/process-helpers.d.mts +20 -0
- package/extensions/oracle/shared/process-helpers.mjs +128 -0
- package/extensions/oracle/shared/state-coordination-helpers.d.mts +43 -0
- package/extensions/oracle/shared/state-coordination-helpers.mjs +381 -0
- package/extensions/oracle/worker/artifact-heuristics.mjs +5 -0
- package/extensions/oracle/worker/auth-bootstrap.mjs +100 -139
- package/extensions/oracle/worker/auth-cookie-policy.mjs +5 -0
- package/extensions/oracle/worker/auth-flow-helpers.d.mts +41 -0
- package/extensions/oracle/worker/auth-flow-helpers.mjs +165 -0
- package/extensions/oracle/worker/chatgpt-flow-helpers.d.mts +13 -0
- package/extensions/oracle/worker/chatgpt-flow-helpers.mjs +85 -0
- package/extensions/oracle/worker/chatgpt-ui-helpers.d.mts +33 -0
- package/extensions/oracle/worker/chatgpt-ui-helpers.mjs +292 -0
- package/extensions/oracle/worker/run-job.mjs +235 -380
- package/extensions/oracle/worker/state-locks.mjs +31 -216
- package/package.json +14 -5
- package/prompts/oracle.md +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.0 - 2026-04-12
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- repeatable isolated local-extension `pi` validation guidance for oracle release verification, including smoke workflows that load the in-repo extension source directly
|
|
7
|
+
- persisted oracle lifecycle-event breadcrumbs plus richer detached-job observability in `oracle_submit`, `oracle_read`, poller wake-ups, and `/oracle-status`, including worker-log paths and last-event context
|
|
8
|
+
- shared worker/auth validation helpers, shared concurrency primitives, shared lifecycle reducers, and shared observability formatters to keep extension and worker behavior aligned
|
|
9
|
+
- extracted sanity-harness support and poller suites with typed helper scaffolding and repeated-run stability coverage
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- oracle whole-repo archiving now excludes local tool state like `.pi/`, `.oracle-context/`, `.cursor/`, and `.scratchpad.md` by default while preserving explicitly requested paths
|
|
13
|
+
- lock/lease recovery, queue promotion, process identity handling, and lifecycle transitions now flow through shared helper modules instead of duplicated inline implementations
|
|
14
|
+
- worker/auth verification now leans on behaviorally tested helper modules plus dedicated `typecheck:worker-helpers` coverage instead of syntax checks and brittle source-string assertions alone
|
|
15
|
+
- release validation now expects isolated local-extension `pi` smoke tests and a stronger local oracle verification gate before shipping
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- archive input resolution now rejects symlink escapes outside the repo root and preserves safer repo-boundary handling for targeted archives
|
|
19
|
+
- hung `tar`, `zstd`, `cp`, and auth `agent-browser` subprocesses now time out and fail clearly instead of wedging archive, runtime-clone, or auth flows indefinitely
|
|
20
|
+
- cleanup warnings without a live worker no longer consume runtime/conversation capacity forever, while teardown still attempts lease release and preserves warnings for later triage
|
|
21
|
+
- detached oracle workers and poller flows now report clearer lifecycle breadcrumbs, wake-up settlement state, and failure context during fast-fail auth/bootstrap scenarios
|
|
22
|
+
- sanity-runner cleanup now retries transient temp-directory removal races, and the extracted harness is less timing-fragile and less `any`-driven than the previous monolithic runner
|
|
23
|
+
|
|
24
|
+
## 0.3.4 - 2026-04-11
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
- oracle archive defaults now exclude nested `secrets/` and `.secrets/` directories anywhere in the repo unless they are explicitly requested
|
|
28
|
+
- package metadata now reflects the current runtime floor and platform support (`node >=22`, `darwin`) and local release automation runs `verify:oracle` through `npm test` / `prepublishOnly`
|
|
29
|
+
|
|
30
|
+
### Fixed
|
|
31
|
+
- model verification now distinguishes `thinking`, `pro`, `instant`, and `instant_auto_switch` more conservatively instead of accepting mismatched presets on partial UI evidence
|
|
32
|
+
- artifact-only assistant responses can now complete without timing out on missing plain-text bodies
|
|
33
|
+
- `/oracle-auth` diagnostics now write into a unique private temp directory per run instead of fixed `/tmp/oracle-auth.*` paths
|
|
34
|
+
- sanity coverage now exercises shared ChatGPT UI helpers directly, verifies nested secret exclusion, and guards the new auth diagnostics path handling
|
|
35
|
+
|
|
3
36
|
## 0.3.3 - 2026-04-11
|
|
4
37
|
|
|
5
38
|
### Added
|
package/README.md
CHANGED
|
@@ -147,6 +147,7 @@ Project config should only override safe, non-privileged settings.
|
|
|
147
147
|
## Requirements
|
|
148
148
|
|
|
149
149
|
- macOS
|
|
150
|
+
- Node.js 22 or newer
|
|
150
151
|
- Google Chrome installed
|
|
151
152
|
- ChatGPT already signed into a local Chrome profile
|
|
152
153
|
- `pi` 0.65.0 or newer
|
|
@@ -194,6 +195,7 @@ Project config should only override safe, non-privileged settings.
|
|
|
194
195
|
|
|
195
196
|
- `docs/ORACLE_DESIGN.md` — architecture, lifecycle, queueing, persistence, presets, and recovery behavior
|
|
196
197
|
- `docs/ORACLE_RECOVERY_DRILL.md` — safe expired-auth recovery validation drill
|
|
198
|
+
- `docs/ORACLE_ISOLATED_PI_VALIDATION.md` — repeatable isolated `pi` session smoke test for local-extension validation
|
|
197
199
|
|
|
198
200
|
## Privacy / local data
|
|
199
201
|
|
|
@@ -209,12 +211,17 @@ Review the code and design docs before using it with sensitive material.
|
|
|
209
211
|
```bash
|
|
210
212
|
npm run check:oracle-extension
|
|
211
213
|
npm run typecheck
|
|
214
|
+
npm run typecheck:worker-helpers
|
|
212
215
|
npm run sanity:oracle
|
|
213
216
|
npm run pack:check
|
|
217
|
+
# conventional local gate
|
|
218
|
+
npm test
|
|
214
219
|
# or all at once
|
|
215
220
|
npm run verify:oracle
|
|
216
221
|
```
|
|
217
222
|
|
|
223
|
+
`npm publish` is also guarded locally via `prepublishOnly` and will run `npm run verify:oracle` before publishing.
|
|
224
|
+
|
|
218
225
|
## Beta caveats
|
|
219
226
|
|
|
220
227
|
The highest-risk areas to monitor are:
|
package/docs/ORACLE_DESIGN.md
CHANGED
|
@@ -585,7 +585,7 @@ Remaining non-blocking hardening work:
|
|
|
585
585
|
|
|
586
586
|
Recent proof points:
|
|
587
587
|
- expired-auth drill fail path: `a2460bc1-7d89-4041-b67d-39680d310325`
|
|
588
|
-
- `/oracle-auth` repair evidence: `/tmp/oracle-auth.log`
|
|
588
|
+
- `/oracle-auth` repair evidence: the per-run `/tmp/pi-oracle-auth-*/oracle-auth.log` bundle path printed by `/oracle-auth`
|
|
589
589
|
- expired-auth drill post-repair success: `fa26a2a7-0057-4a21-b3e0-71c1d020facf`
|
|
590
590
|
- successful multi-artifact completion: `b6b3599c-6b91-4315-adfa-8a83aa5eda9b`
|
|
591
591
|
- repo-owned sanity harness: `npm run sanity:oracle`
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# Oracle isolated `pi` validation
|
|
2
|
+
|
|
3
|
+
This document describes the repeatable pre-commit smoke test for validating `pi-oracle` through isolated `pi` agent sessions that load the local extension source.
|
|
4
|
+
|
|
5
|
+
Use this workflow for code changes when you need end-to-end evidence beyond `npm test`.
|
|
6
|
+
|
|
7
|
+
## What this validates
|
|
8
|
+
|
|
9
|
+
- the local extension can be loaded directly by isolated `pi` sessions
|
|
10
|
+
- whole-repo `oracle_submit` archive creation excludes local tool state by default
|
|
11
|
+
- targeted archive inputs cannot escape the repo through symlinked paths
|
|
12
|
+
- the exercised `pi` agents can provide candid feedback about tool clarity or clunkiness
|
|
13
|
+
|
|
14
|
+
## Why this workflow is isolated
|
|
15
|
+
|
|
16
|
+
The test intentionally uses separate directories for:
|
|
17
|
+
|
|
18
|
+
- `PI_CODING_AGENT_DIR`
|
|
19
|
+
- `--session-dir`
|
|
20
|
+
- `PI_ORACLE_JOBS_DIR`
|
|
21
|
+
|
|
22
|
+
That keeps the validation run from reusing your normal `pi` agent state.
|
|
23
|
+
|
|
24
|
+
The extension is loaded from the local checkout with:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pi --no-extensions -e "$REPO/extensions/oracle/index.ts"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
That ensures the session is exercising the in-repo code, not a globally installed package.
|
|
31
|
+
|
|
32
|
+
## Preset requirement
|
|
33
|
+
|
|
34
|
+
Use either:
|
|
35
|
+
|
|
36
|
+
- `instant`
|
|
37
|
+
- `thinking_light`
|
|
38
|
+
|
|
39
|
+
The examples below use `instant` because it is the fastest smoke-test preset.
|
|
40
|
+
|
|
41
|
+
## Prerequisites
|
|
42
|
+
|
|
43
|
+
- `pi` installed locally
|
|
44
|
+
- `tmux` installed locally
|
|
45
|
+
- run from the repository root
|
|
46
|
+
|
|
47
|
+
## Repeatable smoke test
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
set -euo pipefail
|
|
51
|
+
|
|
52
|
+
REPO="$PWD"
|
|
53
|
+
TEST_ROOT="/tmp/pi-oracle-isolated-tests-$$"
|
|
54
|
+
|
|
55
|
+
TEST1_AGENT="$TEST_ROOT/agent1"
|
|
56
|
+
TEST1_SESSIONS="$TEST_ROOT/sessions1"
|
|
57
|
+
TEST1_JOBS="$TEST_ROOT/jobs1"
|
|
58
|
+
TEST2_AGENT="$TEST_ROOT/agent2"
|
|
59
|
+
TEST2_SESSIONS="$TEST_ROOT/sessions2"
|
|
60
|
+
TEST2_JOBS="$TEST_ROOT/jobs2"
|
|
61
|
+
|
|
62
|
+
FIXTURE="$TEST_ROOT/symlink-fixture"
|
|
63
|
+
OUTSIDE="$TEST_ROOT/outside"
|
|
64
|
+
|
|
65
|
+
SESSION1="pi-oracle-test1"
|
|
66
|
+
SESSION2="pi-oracle-test2"
|
|
67
|
+
|
|
68
|
+
mkdir -p \
|
|
69
|
+
"$TEST1_AGENT" "$TEST1_SESSIONS" "$TEST1_JOBS" \
|
|
70
|
+
"$TEST2_AGENT" "$TEST2_SESSIONS" "$TEST2_JOBS" \
|
|
71
|
+
"$FIXTURE" "$OUTSIDE"
|
|
72
|
+
|
|
73
|
+
echo 'secret' > "$OUTSIDE/secret.txt"
|
|
74
|
+
ln -s "$OUTSIDE" "$FIXTURE/linked-outside"
|
|
75
|
+
|
|
76
|
+
PROMPT1='Call oracle_submit directly with prompt "Sanity test for archive exclusions. Reply with OK." files ["."] and preset "instant". Do not use bash. After the tool returns, summarize the outcome in 3 bullets including the job id/status, and give one sentence of candid feedback on whether the oracle tool behavior feels clear or clunky.'
|
|
77
|
+
PROMPT2='Call oracle_submit directly with prompt "Sanity test for symlink escape rejection." files ["linked-outside/secret.txt"] and preset "instant". Do not use bash. After the tool returns, summarize the outcome in 3 bullets and give one sentence of candid feedback on whether the oracle tool behavior feels clear or clunky.'
|
|
78
|
+
|
|
79
|
+
cleanup() {
|
|
80
|
+
tmux kill-session -t "$SESSION1" 2>/dev/null || true
|
|
81
|
+
tmux kill-session -t "$SESSION2" 2>/dev/null || true
|
|
82
|
+
}
|
|
83
|
+
trap cleanup EXIT
|
|
84
|
+
cleanup
|
|
85
|
+
|
|
86
|
+
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'"
|
|
87
|
+
tmux new-session -d -s "$SESSION1" "$TMUX_CMD1"
|
|
88
|
+
sleep 8
|
|
89
|
+
tmux send-keys -t "$SESSION1":0.0 "$PROMPT1" Enter
|
|
90
|
+
sleep 35
|
|
91
|
+
|
|
92
|
+
echo '--- pane:test1'
|
|
93
|
+
tmux capture-pane -p -S -220 -t "$SESSION1":0.0 | tail -n 160
|
|
94
|
+
|
|
95
|
+
JOB_DIR1="$(find "$TEST1_JOBS" -maxdepth 1 -type d -name 'oracle-*' | sort | tail -n 1 || true)"
|
|
96
|
+
echo "--- latest job dir:test1 ${JOB_DIR1:-<none>}"
|
|
97
|
+
|
|
98
|
+
if [ -n "${JOB_DIR1:-}" ] && [ -f "$JOB_DIR1/job.json" ]; then
|
|
99
|
+
ARCHIVE1="$(python3 - <<'PY' "$JOB_DIR1/job.json"
|
|
100
|
+
import json,sys
|
|
101
|
+
with open(sys.argv[1]) as f:
|
|
102
|
+
print(json.load(f)['archivePath'])
|
|
103
|
+
PY
|
|
104
|
+
)"
|
|
105
|
+
echo "--- archive:test1 $ARCHIVE1"
|
|
106
|
+
tar --zstd -tf "$ARCHIVE1" | head -n 80
|
|
107
|
+
LIST="$(mktemp)"
|
|
108
|
+
tar --zstd -tf "$ARCHIVE1" > "$LIST"
|
|
109
|
+
for path in .pi/settings.json .oracle-context .cursor .scratchpad.md README.md; do
|
|
110
|
+
if grep -E -q "^${path}$|^${path}/" "$LIST"; then
|
|
111
|
+
echo "FOUND $path"
|
|
112
|
+
else
|
|
113
|
+
echo "MISSING $path"
|
|
114
|
+
fi
|
|
115
|
+
done
|
|
116
|
+
rm -f "$LIST"
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
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'"
|
|
120
|
+
tmux new-session -d -s "$SESSION2" "$TMUX_CMD2"
|
|
121
|
+
sleep 8
|
|
122
|
+
tmux send-keys -t "$SESSION2":0.0 "$PROMPT2" Enter
|
|
123
|
+
sleep 25
|
|
124
|
+
|
|
125
|
+
echo '--- pane:test2'
|
|
126
|
+
tmux capture-pane -p -S -220 -t "$SESSION2":0.0 | tail -n 160
|
|
127
|
+
|
|
128
|
+
echo '--- jobs created:test2'
|
|
129
|
+
find "$TEST2_JOBS" -maxdepth 1 -type d -name 'oracle-*' | sort || true
|
|
130
|
+
|
|
131
|
+
echo "TEST_ROOT=$TEST_ROOT"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Expected results
|
|
135
|
+
|
|
136
|
+
### Test 1: whole-repo archive exclusions
|
|
137
|
+
|
|
138
|
+
Expected behavior:
|
|
139
|
+
|
|
140
|
+
- the isolated `pi` session loads the local extension successfully
|
|
141
|
+
- `oracle_submit` creates a job and an archive path under the isolated jobs dir
|
|
142
|
+
- the archive should exclude:
|
|
143
|
+
- `.pi/`
|
|
144
|
+
- `.oracle-context/`
|
|
145
|
+
- `.cursor/`
|
|
146
|
+
- `.scratchpad.md`
|
|
147
|
+
- the archive should still include normal repo files such as `README.md`
|
|
148
|
+
|
|
149
|
+
Notes:
|
|
150
|
+
|
|
151
|
+
- this smoke test does not require `/oracle-auth`
|
|
152
|
+
- without an auth seed profile, the worker fails after archive creation, which is useful because the archive remains on disk for inspection
|
|
153
|
+
|
|
154
|
+
### Test 2: symlink escape rejection
|
|
155
|
+
|
|
156
|
+
Expected behavior:
|
|
157
|
+
|
|
158
|
+
- `oracle_submit` rejects `linked-outside/secret.txt`
|
|
159
|
+
- the error should say the archive input must resolve inside the project cwd without symlink escapes
|
|
160
|
+
- no oracle job directory should be created for the rejected submit
|
|
161
|
+
|
|
162
|
+
## Additional failure-mode smoke tests
|
|
163
|
+
|
|
164
|
+
### `/oracle-auth` should fail fast when `agent-browser` hangs
|
|
165
|
+
|
|
166
|
+
Use this when validating timeout hardening around auth/bootstrap browser commands.
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
set -euo pipefail
|
|
170
|
+
|
|
171
|
+
REPO="$PWD"
|
|
172
|
+
TEST_ROOT="/tmp/pi-oracle-auth-timeout-$$"
|
|
173
|
+
AGENT_DIR="$TEST_ROOT/agent"
|
|
174
|
+
SESSION_DIR="$TEST_ROOT/sessions"
|
|
175
|
+
JOBS_DIR="$TEST_ROOT/jobs"
|
|
176
|
+
FAKE_BROWSER="$TEST_ROOT/agent-browser"
|
|
177
|
+
SESSION_NAME="pi-oracle-auth-timeout"
|
|
178
|
+
|
|
179
|
+
mkdir -p "$AGENT_DIR/extensions" "$SESSION_DIR" "$JOBS_DIR"
|
|
180
|
+
|
|
181
|
+
cat > "$AGENT_DIR/extensions/oracle.json" <<JSON
|
|
182
|
+
{
|
|
183
|
+
"auth": {
|
|
184
|
+
"chromeCookiePath": "$TEST_ROOT/missing-cookies.sqlite"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
JSON
|
|
188
|
+
|
|
189
|
+
cat > "$FAKE_BROWSER" <<'SH'
|
|
190
|
+
#!/bin/sh
|
|
191
|
+
trap 'exit 0' TERM INT
|
|
192
|
+
while :; do sleep 1; done
|
|
193
|
+
SH
|
|
194
|
+
chmod +x "$FAKE_BROWSER"
|
|
195
|
+
|
|
196
|
+
cleanup() {
|
|
197
|
+
tmux kill-session -t "$SESSION_NAME" 2>/dev/null || true
|
|
198
|
+
}
|
|
199
|
+
trap 'cleanup; rm -rf "$TEST_ROOT"' EXIT
|
|
200
|
+
cleanup
|
|
201
|
+
|
|
202
|
+
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'"
|
|
203
|
+
|
|
204
|
+
tmux new-session -d -s "$SESSION_NAME" "$TMUX_CMD"
|
|
205
|
+
sleep 8
|
|
206
|
+
tmux send-keys -t "$SESSION_NAME":0.0 '/oracle-auth' Enter
|
|
207
|
+
sleep 12
|
|
208
|
+
|
|
209
|
+
tmux capture-pane -p -S -220 -t "$SESSION_NAME":0.0 | tail -n 140
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Expected behavior:
|
|
213
|
+
|
|
214
|
+
- the isolated `pi` session loads the local extension successfully
|
|
215
|
+
- `/oracle-auth` returns with an error instead of hanging indefinitely
|
|
216
|
+
- the output should mention the missing ChatGPT session-token cookies or the configured cookie source problem
|
|
217
|
+
- the session should remain usable after the command failure
|
|
218
|
+
|
|
219
|
+
## Switching to `thinking_light`
|
|
220
|
+
|
|
221
|
+
To run the same smoke test with `thinking_light`, change both prompts from:
|
|
222
|
+
|
|
223
|
+
```text
|
|
224
|
+
preset "instant"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
to:
|
|
228
|
+
|
|
229
|
+
```text
|
|
230
|
+
preset "thinking_light"
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Cleanup
|
|
234
|
+
|
|
235
|
+
The snippet already kills the temporary `tmux` sessions on exit.
|
|
236
|
+
|
|
237
|
+
To remove the temporary files after inspection:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
rm -rf "$TEST_ROOT"
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Minimum pre-commit evidence
|
|
244
|
+
|
|
245
|
+
Before committing code changes, keep evidence for:
|
|
246
|
+
|
|
247
|
+
- `npm test` passing
|
|
248
|
+
- isolated `pi` session validation using this workflow
|
|
249
|
+
- any agent feedback gathered during the isolated run if it exposed clunky or unclear behavior
|
|
@@ -105,10 +105,11 @@ For the failed run:
|
|
|
105
105
|
- any failure diagnostics under that job dir
|
|
106
106
|
|
|
107
107
|
For the repair:
|
|
108
|
-
- `/tmp/oracle-auth
|
|
109
|
-
-
|
|
110
|
-
-
|
|
111
|
-
-
|
|
108
|
+
- the per-run `/tmp/pi-oracle-auth-*/` diagnostics directory printed by `/oracle-auth`
|
|
109
|
+
- `oracle-auth.log`
|
|
110
|
+
- `oracle-auth.url.txt`
|
|
111
|
+
- `oracle-auth.snapshot.txt`
|
|
112
|
+
- `oracle-auth.body.txt`
|
|
112
113
|
|
|
113
114
|
For the successful rerun:
|
|
114
115
|
- `/tmp/oracle-<job-id>/job.json`
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
// Purpose: Register the oracle extension, wire commands/tools/workers, and manage per-session background maintenance.
|
|
2
|
+
// Responsibilities: Bootstrap oracle commands and tools, start or stop polling, and surface startup/config availability in the pi session UI.
|
|
3
|
+
// Scope: Extension entrypoint only; lifecycle mutation lives in lib modules and browser execution lives in worker scripts.
|
|
4
|
+
// Usage: Loaded by pi as the extension module declared in package.json.
|
|
5
|
+
// Invariants/Assumptions: Oracle only runs against persisted sessions, and startup maintenance should be best-effort without breaking session initialization.
|
|
1
6
|
import { fileURLToPath } from "node:url";
|
|
2
7
|
import { dirname, join } from "node:path";
|
|
3
8
|
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
@@ -42,7 +47,9 @@ export default function oracleExtension(pi: ExtensionAPI) {
|
|
|
42
47
|
|
|
43
48
|
const config = loadOracleConfig(ctx.cwd);
|
|
44
49
|
void runStartupMaintenance(ctx).catch((error) => {
|
|
45
|
-
|
|
50
|
+
const message = `Oracle startup maintenance failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
51
|
+
console.error(message);
|
|
52
|
+
ctx.ui.notify(message, "warning");
|
|
46
53
|
});
|
|
47
54
|
startPoller(pi, ctx, config.poller.intervalMs, workerPath);
|
|
48
55
|
refreshOracleStatus(ctx);
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
// Purpose: Register slash commands for oracle auth/bootstrap, status inspection, cancellation, and cleanup.
|
|
2
|
+
// Responsibilities: Bridge command handlers to shared oracle lifecycle helpers, surface consistent summaries, and coordinate follow-up queue advancement.
|
|
3
|
+
// Scope: Command-facing orchestration only; durable lifecycle mutations live in jobs/runtime/tools modules and browser execution stays in worker scripts.
|
|
4
|
+
// Usage: Imported by the oracle extension entrypoint to register /oracle-* commands with pi.
|
|
5
|
+
// Invariants/Assumptions: Commands operate on persisted project-scoped jobs and rely on shared observability formatting for detached-state clarity.
|
|
1
6
|
import { spawn } from "node:child_process";
|
|
2
7
|
import type { ExtensionAPI, ExtensionCommandContext } from "@mariozechner/pi-coding-agent";
|
|
8
|
+
import { formatOracleJobSummary } from "../shared/job-observability-helpers.mjs";
|
|
3
9
|
import { loadOracleConfig } from "./config.js";
|
|
4
10
|
import {
|
|
5
11
|
cancelOracleJob,
|
|
12
|
+
getJobDir,
|
|
6
13
|
isOpenOracleJob,
|
|
7
14
|
isTerminalOracleJob,
|
|
8
15
|
listJobsForCwd,
|
|
@@ -22,30 +29,10 @@ function summarizeJob(jobId: string): string {
|
|
|
22
29
|
const job = readJob(jobId);
|
|
23
30
|
if (!job) return `Oracle job ${jobId} not found.`;
|
|
24
31
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
`phase: ${job.phase}`,
|
|
30
|
-
`created: ${job.createdAt}`,
|
|
31
|
-
job.queuedAt ? `queued: ${job.queuedAt}` : undefined,
|
|
32
|
-
job.submittedAt ? `submitted: ${job.submittedAt}` : undefined,
|
|
33
|
-
queuePosition ? `queue-position: ${queuePosition.position} of ${queuePosition.depth} global` : undefined,
|
|
34
|
-
`project: ${job.projectId}`,
|
|
35
|
-
`session: ${job.sessionId}`,
|
|
36
|
-
job.completedAt ? `completed: ${job.completedAt}` : undefined,
|
|
37
|
-
job.followUpToJobId ? `follow-up-to: ${job.followUpToJobId}` : undefined,
|
|
38
|
-
job.chatUrl ? `chat: ${job.chatUrl}` : undefined,
|
|
39
|
-
job.conversationId ? `conversation: ${job.conversationId}` : undefined,
|
|
40
|
-
job.responsePath ? `response: ${job.responsePath}` : undefined,
|
|
41
|
-
job.responseFormat ? `response-format: ${job.responseFormat}` : undefined,
|
|
42
|
-
typeof job.artifactFailureCount === "number" ? `artifact-failures: ${job.artifactFailureCount}` : undefined,
|
|
43
|
-
job.lastCleanupAt ? `last-cleanup: ${job.lastCleanupAt}` : undefined,
|
|
44
|
-
job.cleanupWarnings?.length ? `cleanup-warnings: ${job.cleanupWarnings.join(" | ")}` : undefined,
|
|
45
|
-
job.error ? `error: ${job.error}` : undefined,
|
|
46
|
-
]
|
|
47
|
-
.filter(Boolean)
|
|
48
|
-
.join("\n");
|
|
32
|
+
return formatOracleJobSummary(job, {
|
|
33
|
+
queuePosition: job.status === "queued" ? getQueuePosition(job.id) : undefined,
|
|
34
|
+
artifactsPath: `${getJobDir(job.id)}/artifacts`,
|
|
35
|
+
});
|
|
49
36
|
}
|
|
50
37
|
|
|
51
38
|
function getLatestJobId(cwd: string): string | undefined {
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
// Purpose: Define oracle configuration schema, defaults, preset selection, and local config loading behavior.
|
|
2
|
+
// Responsibilities: Normalize preset ids, load extension config from disk, expose default browser/auth/runtime settings, and validate config shape.
|
|
3
|
+
// Scope: Configuration and preset resolution only; runtime/job execution stays in sibling oracle modules.
|
|
4
|
+
// Usage: Imported by oracle tools, commands, runtime helpers, and sanity tests when config or preset resolution is required.
|
|
5
|
+
// Invariants/Assumptions: Preset ids remain the canonical model-selection contract and config loading must fail clearly on invalid user overrides.
|
|
1
6
|
import { execFileSync } from "node:child_process";
|
|
2
7
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
8
|
import { homedir } from "node:os";
|