@steipete/oracle 0.16.0 → 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.
- package/README.md +72 -337
- package/dist/bin/oracle-cli.js +184 -55
- package/dist/bin/oracle-mcp.js +0 -0
- package/dist/docs-site/.nojekyll +0 -0
- package/dist/docs-site/CNAME +1 -0
- package/dist/docs-site/RELEASING.html +410 -0
- package/dist/docs-site/agents.html +374 -0
- package/dist/docs-site/anthropic.html +368 -0
- package/dist/docs-site/bridge.html +416 -0
- package/dist/docs-site/browser-mode.html +594 -0
- package/dist/docs-site/chromium-forks.html +347 -0
- package/dist/docs-site/cli-reference.html +346 -0
- package/dist/docs-site/configuration.html +462 -0
- package/dist/docs-site/favicon.svg +14 -0
- package/dist/docs-site/followup.html +375 -0
- package/dist/docs-site/gemini.html +383 -0
- package/dist/docs-site/grok.html +325 -0
- package/dist/docs-site/index.html +360 -0
- package/dist/docs-site/install.html +335 -0
- package/dist/docs-site/linux.html +321 -0
- package/dist/docs-site/llms.txt +43 -0
- package/dist/docs-site/manual-tests.html +596 -0
- package/dist/docs-site/mcp.html +391 -0
- package/dist/docs-site/multimodel.html +364 -0
- package/dist/docs-site/mythical-pro-agents.html +360 -0
- package/dist/docs-site/notifier.html +338 -0
- package/dist/docs-site/openai-endpoints.html +410 -0
- package/dist/docs-site/openrouter.html +344 -0
- package/dist/docs-site/quickstart.html +369 -0
- package/dist/docs-site/refactor/ux.html +532 -0
- package/dist/docs-site/sessions.html +389 -0
- package/dist/docs-site/social-card.png +0 -0
- package/dist/docs-site/social-card.svg +79 -0
- package/dist/docs-site/spec.html +363 -0
- package/dist/docs-site/testing.html +320 -0
- package/dist/docs-site/tui-debug.html +326 -0
- package/dist/docs-site/windows-work.html +324 -0
- package/dist/docs-site/windows.html +320 -0
- package/dist/scripts/test-browser.js +1 -25
- package/dist/src/browser/actions/modelSelection.js +36 -34
- package/dist/src/browser/actions/navigation.js +8 -3
- package/dist/src/browser/actions/thinkingTime.js +39 -3
- package/dist/src/browser/cdpLiveness.js +78 -0
- package/dist/src/browser/chromeLifecycle.js +85 -39
- package/dist/src/browser/conversationUrl.js +16 -0
- package/dist/src/browser/conversationUrlMonitor.js +2 -4
- package/dist/src/browser/cookies.js +6 -4
- package/dist/src/browser/index.js +181 -50
- package/dist/src/browser/liveTabs.js +2 -2
- package/dist/src/browser/modelDisplay.js +67 -0
- package/dist/src/browser/reattach.js +14 -1
- package/dist/src/browser/reattachHelpers.js +3 -5
- package/dist/src/browser/reattachability.js +2 -1
- package/dist/src/browser/recoverConversation.js +2 -1
- package/dist/src/browser/sessionRunner.js +9 -10
- package/dist/src/browser/tabLeaseRegistry.js +9 -3
- package/dist/src/browser/wslHost.js +50 -0
- package/dist/src/cli/browserConfig.js +31 -11
- package/dist/src/cli/browserDefaults.js +4 -1
- package/dist/src/cli/detach.js +21 -4
- package/dist/src/cli/dryRun.js +13 -2
- package/dist/src/cli/engine.js +2 -2
- package/dist/src/cli/options.js +4 -0
- package/dist/src/cli/sessionDisplay.js +60 -8
- package/dist/src/cli/sessionLifecycle.js +2 -1
- package/dist/src/cli/sessionRunner.js +159 -62
- package/dist/src/cli/sessionTable.js +5 -1
- package/dist/src/cli/tui/index.js +12 -4
- package/dist/src/duration.js +3 -0
- package/dist/src/gemini-web/client.js +19 -1
- package/dist/src/oracle/modelResolver.js +8 -1
- package/dist/src/oracle/request.js +9 -2
- package/dist/src/oracle/run.js +43 -3
- package/dist/src/remote/server.js +8 -0
- package/dist/src/sessionManager.js +41 -12
- package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
- package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
- package/package.json +16 -16
- package/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
- package/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
package/dist/bin/oracle-cli.js
CHANGED
|
@@ -21,7 +21,7 @@ import { applyHelpStyling } from "../src/cli/help.js";
|
|
|
21
21
|
import { collectPaths, collectModelList, collectTextValues, parseFloatOption, parseIntOption, parseSearchOption, parseThinkingTimeOption, usesDefaultStatusFilters, resolvePreviewMode, normalizeModelOption, normalizeBaseUrl, resolveApiModel, inferModelFromLabel, parseHeartbeatOption, parseTimeoutOption, parseDurationOption, mergePathLikeOptions, dedupePathInputs, } from "../src/cli/options.js";
|
|
22
22
|
import { copyToClipboard } from "../src/cli/clipboard.js";
|
|
23
23
|
import { buildMarkdownBundle } from "../src/cli/markdownBundle.js";
|
|
24
|
-
import { shouldDetachSession } from "../src/cli/detach.js";
|
|
24
|
+
import { shouldDetachSession, stopDetachedWorker } from "../src/cli/detach.js";
|
|
25
25
|
import { applyHiddenAliases } from "../src/cli/hiddenAliases.js";
|
|
26
26
|
import { isMediaFile } from "../src/browser/prompt.js";
|
|
27
27
|
import { formatCompactNumber } from "../src/cli/format.js";
|
|
@@ -227,10 +227,19 @@ program
|
|
|
227
227
|
.addOption(new Option("--copy-markdown", "Copy the assembled markdown bundle to the clipboard; pair with --render to print it too.").default(false))
|
|
228
228
|
.addOption(new Option("--copy").hideHelp().default(false))
|
|
229
229
|
.option("-s, --slug <words>", "Custom session slug (3-5 words).")
|
|
230
|
-
.option("-m, --model <model>",
|
|
230
|
+
.option("-m, --model <model>", "Model to target (gpt-5.5-pro default). GPT-5.6 aliases gpt-5.6 and gpt-5.6-sol work with the OpenAI API or ChatGPT browser. Browser mode also supports current GPT-5.5/GPT-5.4 targets and legacy Pro aliases; retired GPT-5.2 base/Instant/Thinking aliases are API-only. Other API targets include gpt-5.1-codex, gpt-5.2, gpt-5.2-instant, Gemini, Claude, and custom model IDs.", normalizeModelOption)
|
|
231
231
|
.addOption(new Option("--models <models>", 'Comma-separated API model list to query in parallel (e.g., "gpt-5.5-pro,gemini-3-pro").')
|
|
232
232
|
.argParser(collectModelList)
|
|
233
233
|
.default([]))
|
|
234
|
+
.addOption(new Option("--reasoning-effort <effort>", "Reasoning effort for GPT-5.6 API models.").choices([
|
|
235
|
+
"none",
|
|
236
|
+
"low",
|
|
237
|
+
"medium",
|
|
238
|
+
"high",
|
|
239
|
+
"xhigh",
|
|
240
|
+
"max",
|
|
241
|
+
]))
|
|
242
|
+
.addOption(new Option("--reasoning-mode <mode>", 'Responses API reasoning execution mode for GPT-5.6 models ("standard" or "pro").').choices(["standard", "pro"]))
|
|
234
243
|
.addOption(new Option("-e, --engine <mode>", "Execution engine (api | browser). Browser engine: GPT models automate ChatGPT; Gemini models use a cookie-based client for gemini.google.com. If omitted, oracle picks api when OPENAI_API_KEY is set, otherwise browser.").choices(["api", "browser"]))
|
|
235
244
|
.addOption(new Option("--mode <mode>", "Alias for --engine (api | browser).")
|
|
236
245
|
.choices(["api", "browser"])
|
|
@@ -659,6 +668,8 @@ function buildRunOptions(options, overrides = {}) {
|
|
|
659
668
|
prompt: options.prompt,
|
|
660
669
|
model: options.model,
|
|
661
670
|
models: overrides.models ?? options.models,
|
|
671
|
+
reasoningEffort: overrides.reasoningEffort ?? options.reasoningEffort,
|
|
672
|
+
reasoningMode: overrides.reasoningMode ?? options.reasoningMode,
|
|
662
673
|
previousResponseId: overrides.previousResponseId ?? options.previousResponseId,
|
|
663
674
|
browserResumeConversationUrl: overrides.browserResumeConversationUrl ?? options.browserResumeConversationUrl,
|
|
664
675
|
effectiveModelId: overrides.effectiveModelId ?? options.effectiveModelId ?? options.model,
|
|
@@ -902,6 +913,8 @@ function buildRunOptionsFromMetadata(metadata) {
|
|
|
902
913
|
browserResumeConversationUrl: stored.browserResumeConversationUrl,
|
|
903
914
|
effectiveModelId: stored.effectiveModelId ?? stored.model,
|
|
904
915
|
modelOverrides: stored.modelOverrides,
|
|
916
|
+
reasoningEffort: stored.reasoningEffort,
|
|
917
|
+
reasoningMode: stored.reasoningMode,
|
|
905
918
|
file: stored.file ?? [],
|
|
906
919
|
maxFileSizeBytes: stored.maxFileSizeBytes,
|
|
907
920
|
slug: stored.slug,
|
|
@@ -929,6 +942,8 @@ function buildRunOptionsFromMetadata(metadata) {
|
|
|
929
942
|
browserInlineFiles: stored.browserInlineFiles,
|
|
930
943
|
browserBundleFiles: stored.browserBundleFiles,
|
|
931
944
|
browserBundleFormat: stored.browserBundleFormat,
|
|
945
|
+
generateImage: stored.generateImage,
|
|
946
|
+
outputPath: stored.outputPath,
|
|
932
947
|
browserFollowUps: stored.browserFollowUps,
|
|
933
948
|
background: stored.background,
|
|
934
949
|
renderPlain: stored.renderPlain,
|
|
@@ -1213,6 +1228,7 @@ async function runRootCommand(options) {
|
|
|
1213
1228
|
return;
|
|
1214
1229
|
}
|
|
1215
1230
|
if (options.execSession) {
|
|
1231
|
+
await waitForDetachedStartGate();
|
|
1216
1232
|
await executeSession(options.execSession);
|
|
1217
1233
|
return;
|
|
1218
1234
|
}
|
|
@@ -1296,6 +1312,12 @@ async function runRootCommand(options) {
|
|
|
1296
1312
|
}
|
|
1297
1313
|
}
|
|
1298
1314
|
const activeModel = resolvedOptions.model;
|
|
1315
|
+
if (options.reasoningMode && engine !== "api") {
|
|
1316
|
+
throw new Error("--reasoning-mode requires --engine api.");
|
|
1317
|
+
}
|
|
1318
|
+
if (options.reasoningEffort && engine !== "api") {
|
|
1319
|
+
throw new Error("--reasoning-effort requires --engine api.");
|
|
1320
|
+
}
|
|
1299
1321
|
const browserFollowUpCount = options.browserFollowUp?.filter((entry) => entry.trim().length > 0).length ?? 0;
|
|
1300
1322
|
if (engine !== "browser" && browserFollowUpCount > 0) {
|
|
1301
1323
|
throw new Error("--browser-follow-up requires --engine browser.");
|
|
@@ -1445,13 +1467,16 @@ async function runRootCommand(options) {
|
|
|
1445
1467
|
}, {});
|
|
1446
1468
|
return;
|
|
1447
1469
|
}
|
|
1448
|
-
// Decide whether
|
|
1470
|
+
// Decide whether the original CLI stays attached until completion:
|
|
1449
1471
|
// - explicit --wait / --no-wait wins
|
|
1450
|
-
// - otherwise
|
|
1472
|
+
// - otherwise stay attached for fast models and browser runs
|
|
1473
|
+
// Local Pro browser work may still use a detached worker so CLI interruption
|
|
1474
|
+
// cannot terminate the browser controller.
|
|
1451
1475
|
let waitPreference = resolveWaitFlag({
|
|
1452
1476
|
waitFlag: options.wait,
|
|
1453
1477
|
model: activeModel,
|
|
1454
1478
|
engine,
|
|
1479
|
+
reasoningMode: resolvedOptions.reasoningMode,
|
|
1455
1480
|
});
|
|
1456
1481
|
if (remoteHost && waitPreference === false) {
|
|
1457
1482
|
console.log(chalk.dim("Remote browser runs require --wait; ignoring --no-wait."));
|
|
@@ -1498,22 +1523,34 @@ async function runRootCommand(options) {
|
|
|
1498
1523
|
: shouldDetachSession({
|
|
1499
1524
|
engine,
|
|
1500
1525
|
model: activeModel,
|
|
1526
|
+
reasoningMode: resolvedOptions.reasoningMode,
|
|
1501
1527
|
waitPreference,
|
|
1502
1528
|
disableDetachEnv,
|
|
1503
1529
|
});
|
|
1504
|
-
|
|
1505
|
-
? false
|
|
1506
|
-
: await launchDetachedSession(sessionMeta.id).catch((error) => {
|
|
1507
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1508
|
-
console.log(chalk.yellow(`Unable to detach session runner (${message}). Running inline...`));
|
|
1509
|
-
return false;
|
|
1510
|
-
});
|
|
1511
|
-
const lifecycle = buildSessionLifecycle({
|
|
1530
|
+
let lifecycle = buildSessionLifecycle({
|
|
1512
1531
|
engine,
|
|
1513
|
-
detached,
|
|
1532
|
+
detached: false,
|
|
1514
1533
|
reattachCommand: `oracle session ${sessionMeta.id}`,
|
|
1515
1534
|
});
|
|
1516
|
-
|
|
1535
|
+
const workerPid = !detachAllowed
|
|
1536
|
+
? undefined
|
|
1537
|
+
: await launchDetachedSession(sessionMeta.id, async (pid) => {
|
|
1538
|
+
lifecycle = buildSessionLifecycle({
|
|
1539
|
+
engine,
|
|
1540
|
+
detached: true,
|
|
1541
|
+
workerPid: pid,
|
|
1542
|
+
reattachCommand: `oracle session ${sessionMeta.id}`,
|
|
1543
|
+
});
|
|
1544
|
+
await sessionStore.updateSession(sessionMeta.id, { lifecycle });
|
|
1545
|
+
}).catch((error) => {
|
|
1546
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1547
|
+
console.log(chalk.yellow(`Unable to detach session runner (${message}). Running inline...`));
|
|
1548
|
+
return undefined;
|
|
1549
|
+
});
|
|
1550
|
+
const detached = workerPid !== undefined;
|
|
1551
|
+
if (!detached) {
|
|
1552
|
+
await sessionStore.updateSession(sessionMeta.id, { lifecycle });
|
|
1553
|
+
}
|
|
1517
1554
|
const sessionWithLifecycle = { ...sessionMeta, lifecycle };
|
|
1518
1555
|
if (!waitPreference) {
|
|
1519
1556
|
if (!detached) {
|
|
@@ -1533,8 +1570,7 @@ async function runRootCommand(options) {
|
|
|
1533
1570
|
}
|
|
1534
1571
|
if (detached) {
|
|
1535
1572
|
console.log(chalk.blue(`Reattach via: oracle session ${sessionMeta.id}`));
|
|
1536
|
-
|
|
1537
|
-
await attachSession(sessionMeta.id, { suppressMetadata: true });
|
|
1573
|
+
await attachToDetachedSession(sessionMeta.id, workerPid);
|
|
1538
1574
|
}
|
|
1539
1575
|
}
|
|
1540
1576
|
async function runInteractiveSession(sessionMeta, runOptions, mode, browserConfig, showReattachHint = true, notifications, userConfig, suppressSummary = false, browserDeps, cwd = process.cwd()) {
|
|
@@ -1593,20 +1629,35 @@ async function runInteractiveSession(sessionMeta, runOptions, mode, browserConfi
|
|
|
1593
1629
|
stream.end();
|
|
1594
1630
|
}
|
|
1595
1631
|
}
|
|
1596
|
-
async function launchDetachedSession(sessionId) {
|
|
1632
|
+
async function launchDetachedSession(sessionId, prepare) {
|
|
1597
1633
|
return new Promise((resolve, reject) => {
|
|
1598
1634
|
try {
|
|
1599
1635
|
const args = ["--", CLI_ENTRYPOINT, "--exec-session", sessionId];
|
|
1600
|
-
const env =
|
|
1636
|
+
const env = {
|
|
1637
|
+
...buildDetachedPerfTraceEnv(process.env, perfTraceArgs.value, sessionId),
|
|
1638
|
+
ORACLE_DETACHED_START_GATE: "1",
|
|
1639
|
+
};
|
|
1601
1640
|
const child = spawn(process.execPath, args, {
|
|
1602
1641
|
detached: true,
|
|
1603
|
-
stdio: "ignore",
|
|
1642
|
+
stdio: ["pipe", "ignore", "ignore"],
|
|
1604
1643
|
env,
|
|
1605
1644
|
});
|
|
1606
1645
|
child.once("error", reject);
|
|
1607
|
-
child.once("spawn", () => {
|
|
1608
|
-
child.
|
|
1609
|
-
|
|
1646
|
+
child.once("spawn", async () => {
|
|
1647
|
+
if (child.pid === undefined) {
|
|
1648
|
+
reject(new Error("Detached session worker started without a process ID."));
|
|
1649
|
+
return;
|
|
1650
|
+
}
|
|
1651
|
+
try {
|
|
1652
|
+
await prepare(child.pid);
|
|
1653
|
+
child.stdin.end("ready\n");
|
|
1654
|
+
child.unref();
|
|
1655
|
+
resolve(child.pid);
|
|
1656
|
+
}
|
|
1657
|
+
catch (error) {
|
|
1658
|
+
child.kill();
|
|
1659
|
+
reject(error);
|
|
1660
|
+
}
|
|
1610
1661
|
});
|
|
1611
1662
|
}
|
|
1612
1663
|
catch (error) {
|
|
@@ -1614,6 +1665,49 @@ async function launchDetachedSession(sessionId) {
|
|
|
1614
1665
|
}
|
|
1615
1666
|
});
|
|
1616
1667
|
}
|
|
1668
|
+
async function waitForDetachedStartGate() {
|
|
1669
|
+
if (process.env.ORACLE_DETACHED_START_GATE !== "1") {
|
|
1670
|
+
return;
|
|
1671
|
+
}
|
|
1672
|
+
const chunks = [];
|
|
1673
|
+
await new Promise((resolve, reject) => {
|
|
1674
|
+
process.stdin.on("data", (chunk) => chunks.push(chunk));
|
|
1675
|
+
process.stdin.once("end", resolve);
|
|
1676
|
+
process.stdin.once("error", reject);
|
|
1677
|
+
process.stdin.resume();
|
|
1678
|
+
});
|
|
1679
|
+
if (Buffer.concat(chunks).toString("utf8") !== "ready\n") {
|
|
1680
|
+
throw new Error("Detached session worker start gate closed before lifecycle handoff.");
|
|
1681
|
+
}
|
|
1682
|
+
}
|
|
1683
|
+
async function attachToDetachedSession(sessionId, workerPid) {
|
|
1684
|
+
let cancelled = false;
|
|
1685
|
+
const cancelWorker = () => {
|
|
1686
|
+
cancelled = true;
|
|
1687
|
+
try {
|
|
1688
|
+
stopDetachedWorker(workerPid);
|
|
1689
|
+
}
|
|
1690
|
+
catch (error) {
|
|
1691
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1692
|
+
console.error(chalk.red(`Unable to stop detached worker ${workerPid}: ${message}`));
|
|
1693
|
+
}
|
|
1694
|
+
};
|
|
1695
|
+
process.once("SIGINT", cancelWorker);
|
|
1696
|
+
try {
|
|
1697
|
+
const { attachSession } = await import("../src/cli/sessionDisplay.js");
|
|
1698
|
+
await attachSession(sessionId, {
|
|
1699
|
+
suppressMetadata: true,
|
|
1700
|
+
renderPrompt: false,
|
|
1701
|
+
propagateFailure: true,
|
|
1702
|
+
});
|
|
1703
|
+
}
|
|
1704
|
+
finally {
|
|
1705
|
+
process.off("SIGINT", cancelWorker);
|
|
1706
|
+
if (cancelled) {
|
|
1707
|
+
process.exitCode = 130;
|
|
1708
|
+
}
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1617
1711
|
async function restartSession(sessionId, options) {
|
|
1618
1712
|
const metadata = await sessionStore.readSession(sessionId);
|
|
1619
1713
|
if (!metadata) {
|
|
@@ -1657,6 +1751,7 @@ async function restartSession(sessionId, options) {
|
|
|
1657
1751
|
storedPreference: storedOptions.waitPreference,
|
|
1658
1752
|
model: runOptions.model,
|
|
1659
1753
|
engine,
|
|
1754
|
+
reasoningMode: runOptions.reasoningMode,
|
|
1660
1755
|
});
|
|
1661
1756
|
const remoteConfig = resolveRemoteServiceConfig({
|
|
1662
1757
|
cliHost: options.remoteHost,
|
|
@@ -1732,22 +1827,34 @@ async function restartSession(sessionId, options) {
|
|
|
1732
1827
|
: shouldDetachSession({
|
|
1733
1828
|
engine,
|
|
1734
1829
|
model: runOptions.model,
|
|
1830
|
+
reasoningMode: runOptions.reasoningMode,
|
|
1735
1831
|
waitPreference,
|
|
1736
1832
|
disableDetachEnv,
|
|
1737
1833
|
});
|
|
1738
|
-
|
|
1739
|
-
? false
|
|
1740
|
-
: await launchDetachedSession(sessionMeta.id).catch((error) => {
|
|
1741
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1742
|
-
console.log(chalk.yellow(`Unable to detach session runner (${message}). Running inline...`));
|
|
1743
|
-
return false;
|
|
1744
|
-
});
|
|
1745
|
-
const lifecycle = buildSessionLifecycle({
|
|
1834
|
+
let lifecycle = buildSessionLifecycle({
|
|
1746
1835
|
engine,
|
|
1747
|
-
detached,
|
|
1836
|
+
detached: false,
|
|
1748
1837
|
reattachCommand: `oracle session ${sessionMeta.id}`,
|
|
1749
1838
|
});
|
|
1750
|
-
|
|
1839
|
+
const workerPid = !detachAllowed
|
|
1840
|
+
? undefined
|
|
1841
|
+
: await launchDetachedSession(sessionMeta.id, async (pid) => {
|
|
1842
|
+
lifecycle = buildSessionLifecycle({
|
|
1843
|
+
engine,
|
|
1844
|
+
detached: true,
|
|
1845
|
+
workerPid: pid,
|
|
1846
|
+
reattachCommand: `oracle session ${sessionMeta.id}`,
|
|
1847
|
+
});
|
|
1848
|
+
await sessionStore.updateSession(sessionMeta.id, { lifecycle });
|
|
1849
|
+
}).catch((error) => {
|
|
1850
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1851
|
+
console.log(chalk.yellow(`Unable to detach session runner (${message}). Running inline...`));
|
|
1852
|
+
return undefined;
|
|
1853
|
+
});
|
|
1854
|
+
const detached = workerPid !== undefined;
|
|
1855
|
+
if (!detached) {
|
|
1856
|
+
await sessionStore.updateSession(sessionMeta.id, { lifecycle });
|
|
1857
|
+
}
|
|
1751
1858
|
const sessionWithLifecycle = { ...sessionMeta, lifecycle };
|
|
1752
1859
|
if (!waitPreference) {
|
|
1753
1860
|
if (!detached) {
|
|
@@ -1767,24 +1874,27 @@ async function restartSession(sessionId, options) {
|
|
|
1767
1874
|
}
|
|
1768
1875
|
if (detached) {
|
|
1769
1876
|
console.log(chalk.blue(`Reattach via: oracle session ${sessionMeta.id}`));
|
|
1770
|
-
|
|
1771
|
-
await attachSession(sessionMeta.id, { suppressMetadata: true });
|
|
1877
|
+
await attachToDetachedSession(sessionMeta.id, workerPid);
|
|
1772
1878
|
}
|
|
1773
1879
|
}
|
|
1774
1880
|
async function executeSession(sessionId) {
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
console.error(chalk.red(`No session found with ID ${sessionId}`));
|
|
1778
|
-
process.exitCode = 1;
|
|
1779
|
-
return;
|
|
1780
|
-
}
|
|
1781
|
-
const runOptions = buildRunOptionsFromMetadata(metadata);
|
|
1782
|
-
const sessionMode = getSessionMode(metadata);
|
|
1783
|
-
const browserConfig = getBrowserConfigFromMetadata(metadata);
|
|
1784
|
-
const { logLine, writeChunk, stream } = sessionStore.createLogWriter(sessionId);
|
|
1785
|
-
const userConfig = (await loadUserConfig()).config;
|
|
1786
|
-
const notifications = deriveNotificationSettingsFromMetadata(metadata, process.env, userConfig.notify);
|
|
1881
|
+
let metadata = null;
|
|
1882
|
+
let writer = null;
|
|
1787
1883
|
try {
|
|
1884
|
+
metadata = await sessionStore.readSession(sessionId);
|
|
1885
|
+
if (!metadata) {
|
|
1886
|
+
throw new Error(`No session found with ID ${sessionId}`);
|
|
1887
|
+
}
|
|
1888
|
+
if (process.env.ORACLE_DETACHED_START_GATE === "1" &&
|
|
1889
|
+
metadata.lifecycle?.workerPid !== process.pid) {
|
|
1890
|
+
throw new Error("Detached session worker started without a matching lifecycle handoff.");
|
|
1891
|
+
}
|
|
1892
|
+
const runOptions = buildRunOptionsFromMetadata(metadata);
|
|
1893
|
+
const sessionMode = getSessionMode(metadata);
|
|
1894
|
+
const browserConfig = getBrowserConfigFromMetadata(metadata);
|
|
1895
|
+
writer = sessionStore.createLogWriter(sessionId);
|
|
1896
|
+
const userConfig = (await loadUserConfig()).config;
|
|
1897
|
+
const notifications = deriveNotificationSettingsFromMetadata(metadata, process.env, userConfig.notify);
|
|
1788
1898
|
const { performSessionRun } = await import("../src/cli/sessionRunner.js");
|
|
1789
1899
|
await performSessionRun({
|
|
1790
1900
|
sessionMeta: metadata,
|
|
@@ -1792,17 +1902,36 @@ async function executeSession(sessionId) {
|
|
|
1792
1902
|
mode: sessionMode,
|
|
1793
1903
|
browserConfig,
|
|
1794
1904
|
cwd: metadata.cwd ?? process.cwd(),
|
|
1795
|
-
log: logLine,
|
|
1796
|
-
write: writeChunk,
|
|
1905
|
+
log: writer.logLine,
|
|
1906
|
+
write: writer.writeChunk,
|
|
1797
1907
|
version: VERSION,
|
|
1798
1908
|
notifications,
|
|
1799
1909
|
});
|
|
1800
1910
|
}
|
|
1801
|
-
catch {
|
|
1802
|
-
|
|
1911
|
+
catch (error) {
|
|
1912
|
+
process.exitCode = 1;
|
|
1913
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1914
|
+
if (!metadata) {
|
|
1915
|
+
console.error(chalk.red(message));
|
|
1916
|
+
return;
|
|
1917
|
+
}
|
|
1918
|
+
writer?.logLine(`ERROR: Detached session worker failed: ${message}`);
|
|
1919
|
+
const latest = await sessionStore.readSession(sessionId).catch(() => null);
|
|
1920
|
+
if (latest && !["completed", "partial", "error"].includes(latest.status)) {
|
|
1921
|
+
await sessionStore.updateSession(sessionId, {
|
|
1922
|
+
status: "error",
|
|
1923
|
+
completedAt: new Date().toISOString(),
|
|
1924
|
+
errorMessage: message,
|
|
1925
|
+
response: { status: "error" },
|
|
1926
|
+
error: {
|
|
1927
|
+
category: "internal",
|
|
1928
|
+
message,
|
|
1929
|
+
},
|
|
1930
|
+
});
|
|
1931
|
+
}
|
|
1803
1932
|
}
|
|
1804
1933
|
finally {
|
|
1805
|
-
stream.end();
|
|
1934
|
+
writer?.stream.end();
|
|
1806
1935
|
}
|
|
1807
1936
|
}
|
|
1808
1937
|
function printDebugHelp(cliName) {
|
|
@@ -1871,21 +2000,21 @@ function printDebugOptionGroup(entries) {
|
|
|
1871
2000
|
console.log(` ${label}${description}`);
|
|
1872
2001
|
});
|
|
1873
2002
|
}
|
|
1874
|
-
function resolveWaitFlag({ waitFlag, model, engine, }) {
|
|
2003
|
+
function resolveWaitFlag({ waitFlag, model, engine, reasoningMode, }) {
|
|
1875
2004
|
if (waitFlag === true)
|
|
1876
2005
|
return true;
|
|
1877
2006
|
if (waitFlag === false)
|
|
1878
2007
|
return false;
|
|
1879
|
-
return defaultWaitPreference(model, engine);
|
|
2008
|
+
return defaultWaitPreference(model, engine, reasoningMode);
|
|
1880
2009
|
}
|
|
1881
|
-
function resolveRestartWaitPreference({ waitFlag, storedPreference, model, engine, }) {
|
|
2010
|
+
function resolveRestartWaitPreference({ waitFlag, storedPreference, model, engine, reasoningMode, }) {
|
|
1882
2011
|
if (waitFlag === true)
|
|
1883
2012
|
return true;
|
|
1884
2013
|
if (waitFlag === false)
|
|
1885
2014
|
return false;
|
|
1886
2015
|
if (typeof storedPreference === "boolean")
|
|
1887
2016
|
return storedPreference;
|
|
1888
|
-
return defaultWaitPreference(model, engine);
|
|
2017
|
+
return defaultWaitPreference(model, engine, reasoningMode);
|
|
1889
2018
|
}
|
|
1890
2019
|
function resolveEffectiveModelIdForRun(model, stored) {
|
|
1891
2020
|
if (stored)
|
package/dist/bin/oracle-mcp.js
CHANGED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
askoracle.sh
|