pi-oracle 0.6.7 → 0.6.9
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 +24 -0
- package/extensions/oracle/lib/poller.ts +146 -46
- package/extensions/oracle/lib/tools.ts +1 -1
- package/package.json +5 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.6.9 - 2026-04-23
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- updated the local pi development baseline to `@mariozechner/pi-ai` / `@mariozechner/pi-coding-agent` `0.69.0`
|
|
9
|
+
- migrated published TypeBox integration metadata and source imports from `@sinclair/typebox` to `typebox` for pi `0.69.0` compatibility
|
|
10
|
+
- updated the local oracle verification flow to externalize `typebox` in the extension bundle check and regenerated the npm lockfile against the current stable dependency graph
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- stopped background poller scans from touching stale pi extension contexts after session replacement or reload
|
|
14
|
+
- avoided consuming wake-up retry attempts when a stopped poller exits before sending its best-effort reminder
|
|
15
|
+
|
|
16
|
+
### Compatibility
|
|
17
|
+
- reviewed the pi `0.69.0` changelog and confirmed the extension already uses explicit session-scoped objects in the relevant flows while now matching the required TypeBox 1.x package name
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## 0.6.8 - 2026-04-21
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- updated the local pi development baseline to `@mariozechner/pi-ai` / `@mariozechner/pi-coding-agent` `0.68.0`
|
|
24
|
+
- regenerated the npm lockfile against the current stable dependency graph
|
|
25
|
+
|
|
26
|
+
### Compatibility
|
|
27
|
+
- reviewed the pi `0.68.0` changelog and confirmed the extension already uses explicit session cwd values instead of relying on removed ambient cwd fallbacks in public helpers
|
|
28
|
+
|
|
5
29
|
## 0.6.7 - 2026-04-18
|
|
6
30
|
|
|
7
31
|
### Changed
|
|
@@ -27,7 +27,24 @@ import {
|
|
|
27
27
|
import { promoteQueuedJobs } from "./queue.js";
|
|
28
28
|
import { getProjectId, getSessionId } from "./runtime.js";
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
interface OraclePollerContextSnapshot {
|
|
31
|
+
cwd: string;
|
|
32
|
+
sessionFile: string | undefined;
|
|
33
|
+
hasUI: boolean;
|
|
34
|
+
ui: ExtensionContext["ui"];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface OracleActivePoller {
|
|
38
|
+
active: boolean;
|
|
39
|
+
sessionKey: string;
|
|
40
|
+
timer?: NodeJS.Timeout;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface OraclePollerLifecycle {
|
|
44
|
+
isActive?: () => boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const activePollers = new Map<string, OracleActivePoller>();
|
|
31
48
|
const scansInFlight = new Set<string>();
|
|
32
49
|
const POLLER_LOCK_TIMEOUT_MS = 50;
|
|
33
50
|
const WAKEUP_TARGET_LEASE_KIND = "wakeup-target";
|
|
@@ -121,13 +138,21 @@ function jobCanNotifyContext(
|
|
|
121
138
|
return job.projectId === getProjectId(cwd) && !jobHasLiveWakeupTarget(job, liveWakeupTargets);
|
|
122
139
|
}
|
|
123
140
|
|
|
124
|
-
function
|
|
125
|
-
|
|
126
|
-
|
|
141
|
+
function snapshotPollerContext(ctx: ExtensionContext): OraclePollerContextSnapshot {
|
|
142
|
+
return {
|
|
143
|
+
cwd: ctx.cwd,
|
|
144
|
+
sessionFile: getSessionFile(ctx),
|
|
145
|
+
hasUI: ctx.hasUI,
|
|
146
|
+
ui: ctx.ui,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function getJobCountsForSession(sessionFile: string | undefined, cwd: string): { active: number; queued: number } {
|
|
151
|
+
if (!sessionFile) return { active: 0, queued: 0 };
|
|
127
152
|
return listOracleJobDirs()
|
|
128
153
|
.map((jobDir) => readJob(jobDir))
|
|
129
154
|
.filter((job): job is NonNullable<typeof job> => Boolean(job))
|
|
130
|
-
.filter((job) => jobMatchesContext(job,
|
|
155
|
+
.filter((job) => jobMatchesContext(job, sessionFile, cwd))
|
|
131
156
|
.reduce(
|
|
132
157
|
(counts, job) => {
|
|
133
158
|
if (job.status === "queued") counts.queued += 1;
|
|
@@ -138,15 +163,19 @@ function getJobCounts(ctx: ExtensionContext): { active: number; queued: number }
|
|
|
138
163
|
);
|
|
139
164
|
}
|
|
140
165
|
|
|
141
|
-
|
|
142
|
-
if (!
|
|
143
|
-
|
|
166
|
+
function refreshOracleStatusSnapshot(snapshot: OraclePollerContextSnapshot): void {
|
|
167
|
+
if (!snapshot.sessionFile) {
|
|
168
|
+
snapshot.ui.setStatus("oracle", snapshot.ui.theme.fg("accent", "oracle: unavailable"));
|
|
144
169
|
return;
|
|
145
170
|
}
|
|
146
|
-
const counts =
|
|
171
|
+
const counts = getJobCountsForSession(snapshot.sessionFile, snapshot.cwd);
|
|
147
172
|
const statusText = buildOracleStatusText(counts);
|
|
148
173
|
const tone = counts.active > 0 ? "success" : "accent";
|
|
149
|
-
|
|
174
|
+
snapshot.ui.setStatus("oracle", snapshot.ui.theme.fg(tone, statusText));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function refreshOracleStatus(ctx: ExtensionContext): void {
|
|
178
|
+
refreshOracleStatusSnapshot(snapshotPollerContext(ctx));
|
|
150
179
|
}
|
|
151
180
|
|
|
152
181
|
function requestWakeupTurn(pi: ExtensionAPI, job: OraclePollerJob): void {
|
|
@@ -165,12 +194,27 @@ function requestWakeupTurn(pi: ExtensionAPI, job: OraclePollerJob): void {
|
|
|
165
194
|
);
|
|
166
195
|
}
|
|
167
196
|
|
|
168
|
-
async function
|
|
169
|
-
|
|
170
|
-
|
|
197
|
+
async function releaseWakeupLeaseIfInactive(leaseKey: string, lifecycle: OraclePollerLifecycle): Promise<boolean> {
|
|
198
|
+
if (lifecycle.isActive?.() === false) {
|
|
199
|
+
await releaseLease(WAKEUP_TARGET_LEASE_KIND, leaseKey).catch(() => undefined);
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async function scan(
|
|
206
|
+
pi: ExtensionAPI,
|
|
207
|
+
snapshot: OraclePollerContextSnapshot,
|
|
208
|
+
workerPath: string,
|
|
209
|
+
hooks: OraclePollerHooks = {},
|
|
210
|
+
lifecycle: OraclePollerLifecycle = {},
|
|
211
|
+
): Promise<void> {
|
|
212
|
+
if (lifecycle.isActive?.() === false) return;
|
|
213
|
+
const currentSessionFile = snapshot.sessionFile;
|
|
214
|
+
const pollerKey = getPollerSessionKey(currentSessionFile, snapshot.cwd);
|
|
171
215
|
const notificationClaimant = `${pollerKey}:${process.pid}`;
|
|
172
216
|
|
|
173
|
-
const projectId = getProjectId(
|
|
217
|
+
const projectId = getProjectId(snapshot.cwd);
|
|
174
218
|
const sessionId = getSessionId(currentSessionFile, projectId);
|
|
175
219
|
const processStartedAt = readProcessStartedAt(process.pid);
|
|
176
220
|
const wakeupTargetLeaseKey = getWakeupTargetLeaseKey(pollerKey, process.pid, processStartedAt || "unknown");
|
|
@@ -183,11 +227,14 @@ async function scan(pi: ExtensionAPI, ctx: ExtensionContext, workerPath: string,
|
|
|
183
227
|
processStartedAt,
|
|
184
228
|
updatedAt: new Date().toISOString(),
|
|
185
229
|
}).catch(() => undefined);
|
|
230
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) return;
|
|
231
|
+
|
|
186
232
|
const liveWakeupTargets = await resolveLiveWakeupTargets();
|
|
233
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) return;
|
|
187
234
|
|
|
188
235
|
try {
|
|
189
236
|
await withGlobalReconcileLock(
|
|
190
|
-
{ processPid: process.pid, cwd:
|
|
237
|
+
{ processPid: process.pid, cwd: snapshot.cwd, sessionFile: currentSessionFile, source: "poller" },
|
|
191
238
|
async () => {
|
|
192
239
|
await reconcileStaleOracleJobs();
|
|
193
240
|
},
|
|
@@ -196,8 +243,10 @@ async function scan(pi: ExtensionAPI, ctx: ExtensionContext, workerPath: string,
|
|
|
196
243
|
} catch (error) {
|
|
197
244
|
if (!isLockTimeoutError(error, "reconcile", "global")) throw error;
|
|
198
245
|
}
|
|
246
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) return;
|
|
199
247
|
|
|
200
248
|
await promoteQueuedJobs({ workerPath, source: "poller" });
|
|
249
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) return;
|
|
201
250
|
|
|
202
251
|
const terminalJobs = listOracleJobDirs()
|
|
203
252
|
.map((jobDir) => readJob(jobDir))
|
|
@@ -207,7 +256,7 @@ async function scan(pi: ExtensionAPI, ctx: ExtensionContext, workerPath: string,
|
|
|
207
256
|
const now = Date.now();
|
|
208
257
|
const candidateJobIds = terminalJobs
|
|
209
258
|
.filter((job) => {
|
|
210
|
-
if (!jobCanNotifyContext(job, currentSessionFile,
|
|
259
|
+
if (!jobCanNotifyContext(job, currentSessionFile, snapshot.cwd, liveWakeupTargets)) return false;
|
|
211
260
|
if (job.notifiedAt) return false;
|
|
212
261
|
if (shouldPruneTerminalJob(job, now)) return false;
|
|
213
262
|
return shouldRequestWakeup(job, now);
|
|
@@ -215,27 +264,53 @@ async function scan(pi: ExtensionAPI, ctx: ExtensionContext, workerPath: string,
|
|
|
215
264
|
.map((job) => job.id);
|
|
216
265
|
|
|
217
266
|
for (const jobId of candidateJobIds) {
|
|
267
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) return;
|
|
218
268
|
await hooks.beforeNotificationClaim?.(jobId);
|
|
269
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) return;
|
|
219
270
|
const claimed = await tryClaimNotification(jobId, notificationClaimant);
|
|
220
271
|
if (!claimed) continue;
|
|
221
272
|
|
|
222
|
-
await hooks.afterNotificationClaim?.(claimed);
|
|
223
|
-
const preNotifyLiveWakeupTargets = await resolveLiveWakeupTargets();
|
|
224
|
-
if (!jobCanNotifyContext(claimed, currentSessionFile, ctx.cwd, preNotifyLiveWakeupTargets)) {
|
|
225
|
-
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
273
|
try {
|
|
274
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
275
|
+
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
await hooks.afterNotificationClaim?.(claimed);
|
|
279
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
280
|
+
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const preNotifyLiveWakeupTargets = await resolveLiveWakeupTargets();
|
|
284
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
285
|
+
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
if (!jobCanNotifyContext(claimed, currentSessionFile, snapshot.cwd, preNotifyLiveWakeupTargets)) {
|
|
289
|
+
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
|
|
230
293
|
if (currentSessionFile) {
|
|
231
294
|
await recordNotificationTarget(jobId, notificationClaimant, {
|
|
232
295
|
notificationSessionKey: pollerKey,
|
|
233
296
|
notificationSessionFile: currentSessionFile,
|
|
234
297
|
});
|
|
235
298
|
}
|
|
299
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
300
|
+
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
236
303
|
await hooks.beforeNotificationPersist?.(claimed);
|
|
304
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
305
|
+
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
237
308
|
const preWakeupLiveWakeupTargets = await resolveLiveWakeupTargets();
|
|
238
|
-
if (
|
|
309
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
310
|
+
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
if (!jobCanNotifyContext(claimed, currentSessionFile, snapshot.cwd, preWakeupLiveWakeupTargets)) {
|
|
239
314
|
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
240
315
|
continue;
|
|
241
316
|
}
|
|
@@ -245,16 +320,22 @@ async function scan(pi: ExtensionAPI, ctx: ExtensionContext, workerPath: string,
|
|
|
245
320
|
continue;
|
|
246
321
|
}
|
|
247
322
|
|
|
323
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
324
|
+
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
requestWakeupTurn(pi, deliverable);
|
|
248
328
|
const notedWakeup = await noteWakeupRequested(jobId);
|
|
249
|
-
|
|
250
|
-
if (!deliverableAfterNote || shouldPruneTerminalJob(deliverableAfterNote, Date.now())) {
|
|
329
|
+
if (!notedWakeup) {
|
|
251
330
|
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
252
331
|
continue;
|
|
253
332
|
}
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
333
|
+
if (await releaseWakeupLeaseIfInactive(wakeupTargetLeaseKey, lifecycle)) {
|
|
334
|
+
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (snapshot.hasUI) {
|
|
338
|
+
snapshot.ui.notify(`Oracle job ${claimed.id} is ${claimed.status}.`, "info");
|
|
258
339
|
}
|
|
259
340
|
await releaseNotificationClaim(jobId, notificationClaimant).catch(() => undefined);
|
|
260
341
|
} catch (error) {
|
|
@@ -265,40 +346,58 @@ async function scan(pi: ExtensionAPI, ctx: ExtensionContext, workerPath: string,
|
|
|
265
346
|
}
|
|
266
347
|
|
|
267
348
|
export async function scanOracleJobsOnce(pi: ExtensionAPI, ctx: ExtensionContext, workerPath: string, options: OraclePollerOptions = {}): Promise<void> {
|
|
268
|
-
await scan(pi, ctx, workerPath, options.hooks);
|
|
349
|
+
await scan(pi, snapshotPollerContext(ctx), workerPath, options.hooks);
|
|
269
350
|
}
|
|
270
351
|
|
|
271
352
|
export function startPoller(pi: ExtensionAPI, ctx: ExtensionContext, intervalMs: number, workerPath: string, options: OraclePollerOptions = {}): void {
|
|
272
|
-
const
|
|
353
|
+
const snapshot = snapshotPollerContext(ctx);
|
|
354
|
+
const sessionKey = getPollerSessionKey(snapshot.sessionFile, snapshot.cwd);
|
|
273
355
|
const existing = activePollers.get(sessionKey);
|
|
274
|
-
if (existing)
|
|
356
|
+
if (existing) {
|
|
357
|
+
existing.active = false;
|
|
358
|
+
if (existing.timer) clearInterval(existing.timer);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const handle: OracleActivePoller = {
|
|
362
|
+
active: true,
|
|
363
|
+
sessionKey,
|
|
364
|
+
};
|
|
365
|
+
activePollers.set(sessionKey, handle);
|
|
366
|
+
|
|
367
|
+
const isCurrentPollerActive = () => handle.active && activePollers.get(sessionKey) === handle;
|
|
275
368
|
|
|
276
369
|
const runScan = async () => {
|
|
370
|
+
if (!isCurrentPollerActive()) return;
|
|
277
371
|
if (scansInFlight.has(sessionKey)) return;
|
|
278
372
|
scansInFlight.add(sessionKey);
|
|
279
373
|
try {
|
|
280
|
-
await
|
|
374
|
+
await scan(pi, snapshot, workerPath, options.hooks, { isActive: isCurrentPollerActive });
|
|
281
375
|
} catch (error) {
|
|
282
|
-
|
|
376
|
+
if (isCurrentPollerActive()) {
|
|
377
|
+
console.error(`Oracle poller scan failed (${sessionKey}):`, error);
|
|
378
|
+
}
|
|
283
379
|
} finally {
|
|
284
380
|
scansInFlight.delete(sessionKey);
|
|
285
|
-
|
|
381
|
+
if (isCurrentPollerActive()) {
|
|
382
|
+
refreshOracleStatusSnapshot(snapshot);
|
|
383
|
+
}
|
|
286
384
|
}
|
|
287
385
|
};
|
|
288
386
|
|
|
289
|
-
|
|
387
|
+
refreshOracleStatusSnapshot(snapshot);
|
|
290
388
|
void runScan();
|
|
291
389
|
const timer = setInterval(() => {
|
|
292
390
|
void runScan();
|
|
293
391
|
}, intervalMs);
|
|
294
|
-
|
|
392
|
+
handle.timer = timer;
|
|
295
393
|
}
|
|
296
394
|
|
|
297
395
|
export function stopPollerForSession(sessionFile: string | undefined, cwd: string): void {
|
|
298
396
|
const sessionKey = getPollerSessionKey(sessionFile, cwd);
|
|
299
|
-
const
|
|
300
|
-
if (
|
|
301
|
-
|
|
397
|
+
const handle = activePollers.get(sessionKey);
|
|
398
|
+
if (handle) {
|
|
399
|
+
handle.active = false;
|
|
400
|
+
if (handle.timer) clearInterval(handle.timer);
|
|
302
401
|
activePollers.delete(sessionKey);
|
|
303
402
|
}
|
|
304
403
|
const wakeupTargetLeaseKey = getWakeupTargetLeaseKey(sessionKey);
|
|
@@ -306,13 +405,14 @@ export function stopPollerForSession(sessionFile: string | undefined, cwd: strin
|
|
|
306
405
|
}
|
|
307
406
|
|
|
308
407
|
export async function stopAllPollers(): Promise<void> {
|
|
309
|
-
const
|
|
310
|
-
for (const
|
|
311
|
-
|
|
408
|
+
const handles = [...activePollers.values()];
|
|
409
|
+
for (const handle of handles) {
|
|
410
|
+
handle.active = false;
|
|
411
|
+
if (handle.timer) clearInterval(handle.timer);
|
|
312
412
|
}
|
|
313
413
|
activePollers.clear();
|
|
314
|
-
await Promise.all(
|
|
315
|
-
const wakeupTargetLeaseKey = getWakeupTargetLeaseKey(sessionKey);
|
|
414
|
+
await Promise.all(handles.map(async (handle) => {
|
|
415
|
+
const wakeupTargetLeaseKey = getWakeupTargetLeaseKey(handle.sessionKey);
|
|
316
416
|
await releaseLease(WAKEUP_TARGET_LEASE_KIND, wakeupTargetLeaseKey).catch(() => undefined);
|
|
317
417
|
}));
|
|
318
418
|
}
|
|
@@ -9,7 +9,7 @@ import { tmpdir } from "node:os";
|
|
|
9
9
|
import { basename, join, posix } from "node:path";
|
|
10
10
|
import { runOracleAuthBootstrap } from "./auth.js";
|
|
11
11
|
import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
|
|
12
|
-
import { Type } from "
|
|
12
|
+
import { Type } from "typebox";
|
|
13
13
|
import { formatOracleCancelOutcome, formatOracleJobSummary, formatOracleSubmitResponse } from "../shared/job-observability-helpers.mjs";
|
|
14
14
|
import { getLatestOracleJobLifecycleEvent, getLatestOracleTerminalLifecycleEvent, transitionOracleJobPhase } from "../shared/job-lifecycle-helpers.mjs";
|
|
15
15
|
import { isLockTimeoutError, withGlobalReconcileLock, withLock } from "./locks.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-oracle",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.9",
|
|
4
4
|
"description": "ChatGPT web-oracle extension for pi with isolated browser auth, async jobs, and project-context archives.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
]
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
|
-
"check:oracle-extension": "node --check extensions/oracle/shared/process-helpers.mjs && node --check extensions/oracle/shared/state-coordination-helpers.mjs && node --check extensions/oracle/shared/job-coordination-helpers.mjs && node --check extensions/oracle/shared/job-lifecycle-helpers.mjs && node --check extensions/oracle/shared/job-observability-helpers.mjs && node --check extensions/oracle/worker/run-job.mjs && node --check extensions/oracle/worker/state-locks.mjs && node --check extensions/oracle/worker/artifact-heuristics.mjs && node --check extensions/oracle/worker/chatgpt-ui-helpers.mjs && node --check extensions/oracle/worker/chatgpt-flow-helpers.mjs && node --check extensions/oracle/worker/auth-flow-helpers.mjs && node --check extensions/oracle/worker/auth-cookie-policy.mjs && node --check extensions/oracle/worker/auth-bootstrap.mjs && esbuild extensions/oracle/index.ts --bundle --platform=node --format=esm --external:@mariozechner/pi-coding-agent --external:@mariozechner/pi-ai --external
|
|
45
|
+
"check:oracle-extension": "node --check extensions/oracle/shared/process-helpers.mjs && node --check extensions/oracle/shared/state-coordination-helpers.mjs && node --check extensions/oracle/shared/job-coordination-helpers.mjs && node --check extensions/oracle/shared/job-lifecycle-helpers.mjs && node --check extensions/oracle/shared/job-observability-helpers.mjs && node --check extensions/oracle/worker/run-job.mjs && node --check extensions/oracle/worker/state-locks.mjs && node --check extensions/oracle/worker/artifact-heuristics.mjs && node --check extensions/oracle/worker/chatgpt-ui-helpers.mjs && node --check extensions/oracle/worker/chatgpt-flow-helpers.mjs && node --check extensions/oracle/worker/auth-flow-helpers.mjs && node --check extensions/oracle/worker/auth-cookie-policy.mjs && node --check extensions/oracle/worker/auth-bootstrap.mjs && esbuild extensions/oracle/index.ts --bundle --platform=node --format=esm --external:@mariozechner/pi-coding-agent --external:@mariozechner/pi-ai --external:typebox --outfile=/tmp/pi-oracle-extension-check.js",
|
|
46
46
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
47
47
|
"typecheck:worker-helpers": "tsc --noEmit -p tsconfig.worker-helpers.json",
|
|
48
48
|
"sanity:oracle": "node scripts/oracle-sanity-runner.mjs",
|
|
@@ -55,19 +55,18 @@
|
|
|
55
55
|
"@steipete/sweet-cookie": "^0.2.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"
|
|
58
|
+
"typebox": "*"
|
|
59
59
|
},
|
|
60
60
|
"overrides": {
|
|
61
61
|
"basic-ftp": "5.3.0",
|
|
62
62
|
"protobufjs": "7.5.5"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
|
-
"@mariozechner/pi-
|
|
66
|
-
"@mariozechner/pi-coding-agent": "^0.67.68",
|
|
67
|
-
"@sinclair/typebox": "^0.34.49",
|
|
65
|
+
"@mariozechner/pi-coding-agent": "^0.69.0",
|
|
68
66
|
"@types/node": "^25.6.0",
|
|
69
67
|
"esbuild": "^0.28.0",
|
|
70
68
|
"tsx": "^4.21.0",
|
|
69
|
+
"typebox": "^1.1.31",
|
|
71
70
|
"typescript": "^6.0.3"
|
|
72
71
|
},
|
|
73
72
|
"engines": {
|