@steipete/oracle 0.16.1 → 0.17.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.
Files changed (69) hide show
  1. package/README.md +72 -337
  2. package/dist/bin/oracle-cli.js +184 -55
  3. package/dist/docs-site/.nojekyll +0 -0
  4. package/dist/docs-site/CNAME +1 -0
  5. package/dist/docs-site/RELEASING.html +410 -0
  6. package/dist/docs-site/agents.html +374 -0
  7. package/dist/docs-site/anthropic.html +368 -0
  8. package/dist/docs-site/bridge.html +416 -0
  9. package/dist/docs-site/browser-mode.html +594 -0
  10. package/dist/docs-site/chromium-forks.html +347 -0
  11. package/dist/docs-site/cli-reference.html +346 -0
  12. package/dist/docs-site/configuration.html +462 -0
  13. package/dist/docs-site/favicon.svg +14 -0
  14. package/dist/docs-site/followup.html +375 -0
  15. package/dist/docs-site/gemini.html +383 -0
  16. package/dist/docs-site/grok.html +325 -0
  17. package/dist/docs-site/index.html +360 -0
  18. package/dist/docs-site/install.html +335 -0
  19. package/dist/docs-site/linux.html +321 -0
  20. package/dist/docs-site/llms.txt +43 -0
  21. package/dist/docs-site/manual-tests.html +596 -0
  22. package/dist/docs-site/mcp.html +391 -0
  23. package/dist/docs-site/multimodel.html +364 -0
  24. package/dist/docs-site/mythical-pro-agents.html +360 -0
  25. package/dist/docs-site/notifier.html +338 -0
  26. package/dist/docs-site/openai-endpoints.html +410 -0
  27. package/dist/docs-site/openrouter.html +344 -0
  28. package/dist/docs-site/quickstart.html +369 -0
  29. package/dist/docs-site/refactor/ux.html +532 -0
  30. package/dist/docs-site/sessions.html +389 -0
  31. package/dist/docs-site/social-card.png +0 -0
  32. package/dist/docs-site/social-card.svg +79 -0
  33. package/dist/docs-site/spec.html +363 -0
  34. package/dist/docs-site/testing.html +320 -0
  35. package/dist/docs-site/tui-debug.html +326 -0
  36. package/dist/docs-site/windows-work.html +324 -0
  37. package/dist/docs-site/windows.html +320 -0
  38. package/dist/scripts/test-browser.js +1 -25
  39. package/dist/src/browser/actions/modelSelection.js +36 -34
  40. package/dist/src/browser/actions/navigation.js +8 -3
  41. package/dist/src/browser/actions/thinkingTime.js +39 -3
  42. package/dist/src/browser/chromeLifecycle.js +2 -37
  43. package/dist/src/browser/index.js +23 -8
  44. package/dist/src/browser/modelDisplay.js +67 -0
  45. package/dist/src/browser/reattach.js +14 -1
  46. package/dist/src/browser/recoverConversation.js +2 -1
  47. package/dist/src/browser/sessionRunner.js +9 -10
  48. package/dist/src/browser/wslHost.js +50 -0
  49. package/dist/src/cli/browserConfig.js +31 -11
  50. package/dist/src/cli/detach.js +21 -4
  51. package/dist/src/cli/dryRun.js +13 -2
  52. package/dist/src/cli/engine.js +2 -2
  53. package/dist/src/cli/options.js +4 -0
  54. package/dist/src/cli/sessionDisplay.js +60 -8
  55. package/dist/src/cli/sessionLifecycle.js +2 -1
  56. package/dist/src/cli/sessionRunner.js +110 -60
  57. package/dist/src/cli/sessionTable.js +5 -1
  58. package/dist/src/cli/tui/index.js +12 -4
  59. package/dist/src/duration.js +3 -0
  60. package/dist/src/gemini-web/client.js +19 -1
  61. package/dist/src/oracle/modelResolver.js +8 -1
  62. package/dist/src/oracle/request.js +9 -2
  63. package/dist/src/oracle/run.js +43 -3
  64. package/dist/src/sessionManager.js +41 -12
  65. package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
  66. package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
  67. package/package.json +15 -15
  68. package/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
  69. package/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
@@ -1,6 +1,7 @@
1
1
  import path from "node:path";
2
2
  import fs from "node:fs/promises";
3
3
  import { createWriteStream, mkdirSync } from "node:fs";
4
+ import { randomUUID } from "node:crypto";
4
5
  import net from "node:net";
5
6
  import { DEFAULT_MODEL } from "./oracle/config.js";
6
7
  import { formatElapsed } from "./oracle/format.js";
@@ -57,6 +58,20 @@ function sessionDir(id) {
57
58
  function metaPath(id) {
58
59
  return path.join(sessionDir(id), METADATA_FILENAME);
59
60
  }
61
+ async function writeSessionMetadataFile(sessionId, metadata) {
62
+ const targetPath = metaPath(sessionId);
63
+ const temporaryPath = `${targetPath}.${process.pid}.${randomUUID()}.tmp`;
64
+ try {
65
+ await fs.writeFile(temporaryPath, JSON.stringify(metadata, null, 2), {
66
+ encoding: "utf8",
67
+ mode: 0o600,
68
+ });
69
+ await fs.rename(temporaryPath, targetPath);
70
+ }
71
+ finally {
72
+ await fs.rm(temporaryPath, { force: true }).catch(() => undefined);
73
+ }
74
+ }
60
75
  function requestPath(id) {
61
76
  return path.join(sessionDir(id), LEGACY_REQUEST_FILENAME);
62
77
  }
@@ -193,6 +208,8 @@ export async function initializeSession(options, cwd, notifications, baseSlugOve
193
208
  maxFileSizeBytes: options.maxFileSizeBytes,
194
209
  model: options.model,
195
210
  models: modelList,
211
+ reasoningEffort: options.reasoningEffort,
212
+ reasoningMode: options.reasoningMode,
196
213
  previousResponseId: options.previousResponseId,
197
214
  followupSessionId: options.followupSessionId,
198
215
  followupModel: options.followupModel,
@@ -235,7 +252,7 @@ export async function initializeSession(options, cwd, notifications, baseSlugOve
235
252
  },
236
253
  };
237
254
  await ensureDir(modelsDir(sessionId));
238
- await fs.writeFile(metaPath(sessionId), JSON.stringify(metadata, null, 2), "utf8");
255
+ await writeSessionMetadataFile(sessionId, metadata);
239
256
  await Promise.all((modelList.length > 0 ? modelList : [metadata.model ?? DEFAULT_MODEL]).map(async (modelName) => {
240
257
  const jsonPath = modelJsonPath(sessionId, modelName);
241
258
  const logFilePath = modelLogPath(sessionId, modelName);
@@ -266,7 +283,7 @@ export async function updateSessionMetadata(sessionId, updates) {
266
283
  (await readLegacySessionMetadata(sessionId, { reconcile: false, persist: false })) ??
267
284
  { id: sessionId };
268
285
  const next = { ...existing, ...updates };
269
- await fs.writeFile(metaPath(sessionId), JSON.stringify(next, null, 2), "utf8");
286
+ await writeSessionMetadataFile(sessionId, next);
270
287
  return next;
271
288
  }
272
289
  async function readModernSessionMetadata(sessionId, options) {
@@ -299,8 +316,26 @@ async function readRawSessionMetadata(sessionId) {
299
316
  (await readLegacySessionMetadata(sessionId, { reconcile: false, persist: false })));
300
317
  }
301
318
  async function reconcileSessionMetadata(meta, { persist }) {
302
- const runtimeChecked = await markDeadBrowser(meta, { persist });
303
- return await markZombie(runtimeChecked, { persist });
319
+ let current = meta;
320
+ const workerPid = current.lifecycle?.workerPid;
321
+ if (workerPid) {
322
+ if (isProcessAlive(workerPid)) {
323
+ return current;
324
+ }
325
+ current = (await readRawSessionMetadata(current.id)) ?? current;
326
+ if (current.status !== "running") {
327
+ return current;
328
+ }
329
+ if (current.lifecycle?.workerPid && isProcessAlive(current.lifecycle.workerPid)) {
330
+ return current;
331
+ }
332
+ }
333
+ const runtimeChecked = await markDeadBrowser(current);
334
+ const reconciled = await markZombie(runtimeChecked);
335
+ if (persist && reconciled !== current) {
336
+ await writeSessionMetadataFile(current.id, reconciled);
337
+ }
338
+ return reconciled;
304
339
  }
305
340
  function isSessionMetadataRecord(value) {
306
341
  return Boolean(value && typeof value.id === "string" && value.status);
@@ -479,7 +514,7 @@ export async function getSessionPaths(sessionId) {
479
514
  }
480
515
  return { dir, metadata, log, request };
481
516
  }
482
- async function markZombie(meta, { persist }) {
517
+ async function markZombie(meta) {
483
518
  if (!(await isZombie(meta))) {
484
519
  return meta;
485
520
  }
@@ -506,12 +541,9 @@ async function markZombie(meta, { persist }) {
506
541
  errorMessage: `Session marked as zombie (> ${formatElapsed(maxAgeMs)} stale)`,
507
542
  completedAt: new Date().toISOString(),
508
543
  };
509
- if (persist) {
510
- await fs.writeFile(metaPath(meta.id), JSON.stringify(updated, null, 2), "utf8");
511
- }
512
544
  return updated;
513
545
  }
514
- async function markDeadBrowser(meta, { persist }) {
546
+ async function markDeadBrowser(meta) {
515
547
  if (meta.status !== "running" || meta.mode !== "browser") {
516
548
  return meta;
517
549
  }
@@ -544,9 +576,6 @@ async function markDeadBrowser(meta, { persist }) {
544
576
  completedAt: new Date().toISOString(),
545
577
  response,
546
578
  };
547
- if (persist) {
548
- await fs.writeFile(metaPath(meta.id), JSON.stringify(updated, null, 2), "utf8");
549
- }
550
579
  return updated;
551
580
  }
552
581
  async function isZombie(meta) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steipete/oracle",
3
- "version": "0.16.1",
3
+ "version": "0.17.0",
4
4
  "description": "CLI wrapper around OpenAI Responses API with GPT-5.6 Sol, GPT-5.6, GPT-5.5 Pro, GPT-5.5, GPT-5.4, GPT-5.2, GPT-5.1, and GPT-5.1 Codex high reasoning modes.",
5
5
  "keywords": [],
6
6
  "homepage": "https://askoracle.sh",
@@ -58,11 +58,11 @@
58
58
  },
59
59
  "dependencies": {
60
60
  "@anthropic-ai/tokenizer": "^0.0.4",
61
- "@google/genai": "^2.13.0",
61
+ "@google/genai": "^2.15.0",
62
62
  "@google/generative-ai": "^0.24.1",
63
- "@modelcontextprotocol/sdk": "^1.29.0",
64
- "@steipete/sweet-cookie": "^0.4.0",
65
- "chalk": "^5.6.2",
63
+ "@modelcontextprotocol/sdk": "^1.30.0",
64
+ "@steipete/sweet-cookie": "^0.4.1",
65
+ "chalk": "^6.0.0",
66
66
  "chrome-launcher": "^1.2.1",
67
67
  "chrome-remote-interface": "^0.34.0",
68
68
  "clipboardy": "^5.3.2",
@@ -74,27 +74,27 @@
74
74
  "json5": "^2.2.3",
75
75
  "kleur": "^4.1.5",
76
76
  "markdansi": "0.3.2",
77
- "openai": "^6.48.0",
77
+ "openai": "^7.3.0",
78
78
  "osc-progress": "^0.3.2",
79
79
  "qs": "^6.15.3",
80
- "shiki": "^4.3.1",
80
+ "shiki": "^4.4.1",
81
81
  "toasted-notifier": "^10.1.0",
82
- "tokentally": "^0.1.2",
82
+ "tokentally": "^0.1.3",
83
83
  "zod": "^4.4.3"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@anthropic-ai/tokenizer": "^0.0.4",
87
87
  "@types/chrome-remote-interface": "^0.34.0",
88
88
  "@types/inquirer": "^9.0.10",
89
- "@types/node": "^26.1.1",
89
+ "@types/node": "^26.1.2",
90
90
  "@vitest/coverage-v8": "4.1.10",
91
- "devtools-protocol": "0.0.1666840",
92
- "es-toolkit": "^1.49.0",
91
+ "devtools-protocol": "0.0.1672245",
92
+ "es-toolkit": "^1.50.0",
93
93
  "esbuild": "^0.28.1",
94
- "oxfmt": "0.60.0",
95
- "oxlint": "^1.75.0",
96
- "puppeteer-core": "^25.3.0",
97
- "tsx": "^4.23.1",
94
+ "oxfmt": "0.61.0",
95
+ "oxlint": "^1.76.0",
96
+ "puppeteer-core": "^25.4.0",
97
+ "tsx": "^4.23.5",
98
98
  "typescript": "^7.0.2",
99
99
  "vitest": "^4.1.10"
100
100
  },