@steipete/oracle 0.18.0 → 0.20.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 (169) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/oracle-cli.js +76 -76
  3. package/dist/bin/oracle-mcp.js +0 -0
  4. package/dist/src/browser/actions/archiveConversation.js +31 -7
  5. package/dist/src/browser/actions/assistantResponse.js +43 -1
  6. package/dist/src/browser/actions/attachmentContext.js +239 -0
  7. package/dist/src/browser/actions/attachmentDataTransfer.js +19 -1
  8. package/dist/src/browser/actions/attachmentEvidence.js +78 -0
  9. package/dist/src/browser/actions/attachmentProgress.js +41 -0
  10. package/dist/src/browser/actions/attachmentPrompt.js +130 -0
  11. package/dist/src/browser/actions/attachments.js +306 -355
  12. package/dist/src/browser/actions/deepResearch.js +170 -45
  13. package/dist/src/browser/actions/modelSelection.js +91 -4
  14. package/dist/src/browser/actions/navigation.js +1 -1
  15. package/dist/src/browser/actions/promptComposer.js +364 -186
  16. package/dist/src/browser/actions/remoteFileTransfer.js +4 -2
  17. package/dist/src/browser/actions/thinkingStatus.js +2 -5
  18. package/dist/src/browser/actions/thinkingTime.js +156 -16
  19. package/dist/src/browser/actions/webSearch.js +96 -0
  20. package/dist/src/browser/attachRunning.js +46 -2
  21. package/dist/src/browser/attachmentValidation.js +53 -0
  22. package/dist/src/browser/cancellation.js +105 -0
  23. package/dist/src/browser/chatgptImages.js +2 -0
  24. package/dist/src/browser/chatgptThrottle.js +104 -0
  25. package/dist/src/browser/chromeLifecycle.js +272 -47
  26. package/dist/src/browser/config.js +14 -1
  27. package/dist/src/browser/detect.js +1 -1
  28. package/dist/src/browser/index.js +525 -274
  29. package/dist/src/browser/liveTabs.js +3 -4
  30. package/dist/src/browser/modelDisplay.js +9 -0
  31. package/dist/src/browser/pageActions.js +2 -2
  32. package/dist/src/browser/profileState.js +114 -9
  33. package/dist/src/browser/projectSourcesRunner.js +83 -15
  34. package/dist/src/browser/prompt.js +272 -113
  35. package/dist/src/browser/providers/chatgptDomProvider.js +3 -0
  36. package/dist/src/browser/reattach.js +31 -4
  37. package/dist/src/browser/recoveryTarget.js +131 -0
  38. package/dist/src/browser/sessionRunner.js +73 -11
  39. package/dist/src/browser/tabLeaseRegistry.js +434 -38
  40. package/dist/src/browser/targetClaim.js +54 -0
  41. package/dist/src/browser/utils.js +20 -2
  42. package/dist/src/cli/browserConfig.js +36 -4
  43. package/dist/src/cli/browserDefaults.js +10 -0
  44. package/dist/src/cli/browserTabs.js +15 -29
  45. package/dist/src/cli/detachedSession.js +69 -0
  46. package/dist/src/cli/dryRun.js +58 -48
  47. package/dist/src/cli/harvestIntegrity.js +140 -0
  48. package/dist/src/cli/options.js +15 -0
  49. package/dist/src/cli/recoveredBrowserHarvest.js +50 -0
  50. package/dist/src/cli/runOptions.js +19 -4
  51. package/dist/src/cli/serveBrowserConfig.js +24 -0
  52. package/dist/src/cli/sessionDisplay.js +13 -7
  53. package/dist/src/cli/sessionRunner.js +95 -12
  54. package/dist/src/config.js +1 -0
  55. package/dist/src/gemini-web/client.js +67 -21
  56. package/dist/src/gemini-web/executor.js +4 -0
  57. package/dist/src/gemini-web/http.js +15 -0
  58. package/dist/src/gemini-web/models.js +15 -11
  59. package/dist/src/mcp/server.js +11 -14
  60. package/dist/src/mcp/tools/chatgptImage.js +4 -4
  61. package/dist/src/mcp/tools/consult.js +86 -24
  62. package/dist/src/mcp/tools/projectSources.js +4 -6
  63. package/dist/src/mcp/tools/sessionResources.js +1 -1
  64. package/dist/src/mcp/tools/sessions.js +2 -2
  65. package/dist/src/mcp/tools/wait.js +182 -0
  66. package/dist/src/mcp/types.js +8 -1
  67. package/dist/src/oracle/config.js +14 -0
  68. package/dist/src/oracle/errors.js +11 -0
  69. package/dist/src/oracle/geminiModels.js +1 -0
  70. package/dist/src/oracle/providerRoutePlan.js +3 -2
  71. package/dist/src/oracle/run.js +27 -4
  72. package/dist/src/remote/client.js +73 -6
  73. package/dist/src/remote/health.js +6 -2
  74. package/dist/src/remote/runSlots.js +83 -0
  75. package/dist/src/remote/server.js +346 -71
  76. package/dist/src/sessionManager.js +36 -1
  77. package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
  78. package/dist/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
  79. package/package.json +25 -23
  80. package/vendor/oracle-notifier/OracleNotifier.app/Contents/CodeResources +0 -0
  81. package/vendor/oracle-notifier/OracleNotifier.app/Contents/MacOS/OracleNotifier +0 -0
  82. package/dist/bin/oracle.js +0 -683
  83. package/dist/docs-site/.nojekyll +0 -0
  84. package/dist/docs-site/CNAME +0 -1
  85. package/dist/docs-site/RELEASING.html +0 -410
  86. package/dist/docs-site/agents.html +0 -374
  87. package/dist/docs-site/anthropic.html +0 -368
  88. package/dist/docs-site/bridge.html +0 -400
  89. package/dist/docs-site/browser-mode.html +0 -588
  90. package/dist/docs-site/chromium-forks.html +0 -347
  91. package/dist/docs-site/cli-reference.html +0 -346
  92. package/dist/docs-site/configuration.html +0 -436
  93. package/dist/docs-site/favicon.svg +0 -14
  94. package/dist/docs-site/followup.html +0 -368
  95. package/dist/docs-site/gemini.html +0 -379
  96. package/dist/docs-site/grok.html +0 -325
  97. package/dist/docs-site/index.html +0 -360
  98. package/dist/docs-site/install.html +0 -335
  99. package/dist/docs-site/linux.html +0 -321
  100. package/dist/docs-site/llms.txt +0 -43
  101. package/dist/docs-site/manual-tests.html +0 -595
  102. package/dist/docs-site/mcp.html +0 -368
  103. package/dist/docs-site/multimodel.html +0 -364
  104. package/dist/docs-site/mythical-pro-agents.html +0 -360
  105. package/dist/docs-site/notifier.html +0 -338
  106. package/dist/docs-site/openai-endpoints.html +0 -387
  107. package/dist/docs-site/openrouter.html +0 -344
  108. package/dist/docs-site/quickstart.html +0 -369
  109. package/dist/docs-site/refactor/ux.html +0 -532
  110. package/dist/docs-site/sessions.html +0 -388
  111. package/dist/docs-site/social-card.png +0 -0
  112. package/dist/docs-site/social-card.svg +0 -79
  113. package/dist/docs-site/spec.html +0 -363
  114. package/dist/docs-site/testing.html +0 -320
  115. package/dist/docs-site/tui-debug.html +0 -326
  116. package/dist/docs-site/windows-work.html +0 -323
  117. package/dist/docs-site/windows.html +0 -320
  118. package/dist/markdansi/types/index.js +0 -4
  119. package/dist/oracle/bin/oracle-cli.js +0 -472
  120. package/dist/oracle/src/browser/actions/assistantResponse.js +0 -471
  121. package/dist/oracle/src/browser/actions/attachments.js +0 -82
  122. package/dist/oracle/src/browser/actions/modelSelection.js +0 -190
  123. package/dist/oracle/src/browser/actions/navigation.js +0 -75
  124. package/dist/oracle/src/browser/actions/promptComposer.js +0 -167
  125. package/dist/oracle/src/browser/chromeLifecycle.js +0 -104
  126. package/dist/oracle/src/browser/config.js +0 -33
  127. package/dist/oracle/src/browser/constants.js +0 -40
  128. package/dist/oracle/src/browser/cookies.js +0 -210
  129. package/dist/oracle/src/browser/domDebug.js +0 -36
  130. package/dist/oracle/src/browser/index.js +0 -331
  131. package/dist/oracle/src/browser/pageActions.js +0 -5
  132. package/dist/oracle/src/browser/prompt.js +0 -88
  133. package/dist/oracle/src/browser/promptSummary.js +0 -20
  134. package/dist/oracle/src/browser/sessionRunner.js +0 -80
  135. package/dist/oracle/src/browser/types.js +0 -1
  136. package/dist/oracle/src/browser/utils.js +0 -62
  137. package/dist/oracle/src/browserMode.js +0 -1
  138. package/dist/oracle/src/cli/browserConfig.js +0 -44
  139. package/dist/oracle/src/cli/dryRun.js +0 -59
  140. package/dist/oracle/src/cli/engine.js +0 -17
  141. package/dist/oracle/src/cli/errorUtils.js +0 -9
  142. package/dist/oracle/src/cli/help.js +0 -70
  143. package/dist/oracle/src/cli/markdownRenderer.js +0 -15
  144. package/dist/oracle/src/cli/options.js +0 -103
  145. package/dist/oracle/src/cli/promptRequirement.js +0 -14
  146. package/dist/oracle/src/cli/rootAlias.js +0 -30
  147. package/dist/oracle/src/cli/sessionCommand.js +0 -77
  148. package/dist/oracle/src/cli/sessionDisplay.js +0 -270
  149. package/dist/oracle/src/cli/sessionRunner.js +0 -94
  150. package/dist/oracle/src/heartbeat.js +0 -43
  151. package/dist/oracle/src/oracle/client.js +0 -48
  152. package/dist/oracle/src/oracle/config.js +0 -29
  153. package/dist/oracle/src/oracle/errors.js +0 -101
  154. package/dist/oracle/src/oracle/files.js +0 -220
  155. package/dist/oracle/src/oracle/format.js +0 -33
  156. package/dist/oracle/src/oracle/fsAdapter.js +0 -7
  157. package/dist/oracle/src/oracle/oscProgress.js +0 -60
  158. package/dist/oracle/src/oracle/request.js +0 -48
  159. package/dist/oracle/src/oracle/run.js +0 -444
  160. package/dist/oracle/src/oracle/tokenStats.js +0 -39
  161. package/dist/oracle/src/oracle/types.js +0 -1
  162. package/dist/oracle/src/oracle.js +0 -9
  163. package/dist/oracle/src/sessionManager.js +0 -205
  164. package/dist/oracle/src/version.js +0 -39
  165. package/dist/scripts/chrome/browser-tools.js +0 -295
  166. package/dist/src/browser/chromeCookies.js +0 -312
  167. package/dist/src/browser/keytarShim.js +0 -56
  168. package/dist/src/browser/profileSync.js +0 -141
  169. package/dist/src/browser/windowsCookies.js +0 -219
@@ -0,0 +1,131 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { sessionStore } from "../sessionStore.js";
3
+ import { connectToRemoteChromeTarget } from "./chromeLifecycle.js";
4
+ import { resolveBrowserApprovalWait } from "./config.js";
5
+ import { extractConversationIdFromUrl } from "./reattachHelpers.js";
6
+ import { STOP_BUTTON_SELECTORS } from "./constants.js";
7
+ import { hasActiveBrowserTargetLease } from "./tabLeaseRegistry.js";
8
+ import { buildTargetRetirementExpression, buildTargetRetirementRollbackExpression, normalizeChromeHost, } from "./targetClaim.js";
9
+ function processMayBeAlive(pid) {
10
+ try {
11
+ process.kill(pid, 0);
12
+ return true;
13
+ }
14
+ catch (error) {
15
+ return error.code !== "ESRCH";
16
+ }
17
+ }
18
+ export function hasOtherLiveBrowserController(metadata) {
19
+ for (const pid of [metadata.browser?.runtime?.controllerPid, metadata.lifecycle?.workerPid]) {
20
+ if (!pid || pid === process.pid)
21
+ continue;
22
+ if (processMayBeAlive(pid))
23
+ return true;
24
+ }
25
+ return false;
26
+ }
27
+ async function targetHasActiveController(metadata, capture) {
28
+ for (const other of await sessionStore.listSessions()) {
29
+ if (other.id === metadata.id)
30
+ continue;
31
+ const runtime = other.browser?.runtime;
32
+ if (runtime?.chromeTargetId !== capture.targetId ||
33
+ runtime.chromePort !== capture.port ||
34
+ normalizeChromeHost(runtime.chromeHost ?? "127.0.0.1") !== normalizeChromeHost(capture.host))
35
+ continue;
36
+ if ([runtime.controllerPid, other.lifecycle?.workerPid].some((pid) => pid && processMayBeAlive(pid)))
37
+ return true;
38
+ }
39
+ const runtime = metadata.browser?.runtime;
40
+ const profileDirs = new Set([
41
+ runtime?.userDataDir,
42
+ runtime?.chromeProfileRoot,
43
+ metadata.browser?.config?.manualLoginProfileDir,
44
+ ].filter((dir) => Boolean(dir)));
45
+ for (const dir of profileDirs) {
46
+ if (await hasActiveBrowserTargetLease(dir, capture))
47
+ return true;
48
+ }
49
+ return false;
50
+ }
51
+ export function matchesOwnedRecoveryTarget(metadata, capture) {
52
+ const runtime = metadata.browser?.runtime;
53
+ const owned = runtime?.ownedRecoveryTarget;
54
+ const conversationId = runtime?.conversationId ?? extractConversationIdFromUrl(runtime?.tabUrl ?? "");
55
+ return Boolean(owned &&
56
+ capture &&
57
+ conversationId &&
58
+ capture.conversationId === conversationId &&
59
+ owned.targetId === capture.targetId &&
60
+ normalizeChromeHost(owned.host) === normalizeChromeHost(capture.host) &&
61
+ owned.port === capture.port &&
62
+ owned.browserWSEndpoint === capture.browserWSEndpoint);
63
+ }
64
+ /** Call only after the full recovered answer and completed session have been saved. */
65
+ export async function retireRecoveredBrowserTarget(sessionId, capture, logger, deps = {}) {
66
+ if (!capture)
67
+ return;
68
+ let connection;
69
+ let lockedClaim;
70
+ const reservationId = randomUUID();
71
+ let retired = false;
72
+ try {
73
+ const metadata = await sessionStore.readSession(sessionId);
74
+ if (!metadata ||
75
+ metadata.status !== "completed" ||
76
+ hasOtherLiveBrowserController(metadata) ||
77
+ !matchesOwnedRecoveryTarget(metadata, capture))
78
+ return;
79
+ const claimId = metadata.browser?.runtime?.ownedRecoveryTarget?.claimId;
80
+ if (!claimId)
81
+ return;
82
+ const connect = deps.connect ?? connectToRemoteChromeTarget;
83
+ connection = await connect(capture.host, capture.port, logger, {
84
+ targetId: capture.targetId,
85
+ browserWSEndpoint: capture.browserWSEndpoint,
86
+ closeTargetOnDispose: false,
87
+ approvalWaitMs: resolveBrowserApprovalWait(metadata.browser?.config?.approvalWaitMs),
88
+ });
89
+ const { Runtime, Target } = connection.client;
90
+ const state = await Runtime.evaluate({
91
+ expression: `(() => ({ url: location.href, generating: Array.from(document.querySelectorAll(${JSON.stringify(STOP_BUTTON_SELECTORS.join(","))})).some(node => node.getBoundingClientRect().width > 0 && node.getBoundingClientRect().height > 0) }))()`,
92
+ returnByValue: true,
93
+ });
94
+ const value = state.result?.value;
95
+ if (!value ||
96
+ value.generating !== false ||
97
+ extractConversationIdFromUrl(value.url ?? "") !== capture.conversationId)
98
+ return;
99
+ const { targetInfos } = await Target.getTargets();
100
+ if (!targetInfos.some((target) => target.type === "page" && target.targetId !== capture.targetId)) {
101
+ const replacement = await Target.createTarget({ url: "about:blank" });
102
+ if (!replacement.targetId)
103
+ return;
104
+ }
105
+ if (await targetHasActiveController(metadata, capture))
106
+ return;
107
+ lockedClaim = claimId;
108
+ const locked = await Runtime.evaluate({
109
+ expression: buildTargetRetirementExpression(claimId, capture.conversationId, reservationId),
110
+ returnByValue: true,
111
+ });
112
+ if (locked.exceptionDetails || locked.result?.value !== true)
113
+ return;
114
+ const result = await Target.closeTarget({ targetId: capture.targetId });
115
+ if (!result.success)
116
+ throw new Error("Chrome refused target retirement");
117
+ retired = true;
118
+ logger("Retired Oracle-owned browser tab after saving the recovered answer.");
119
+ }
120
+ catch (error) {
121
+ logger(`Recovered answer is saved; browser tab cleanup failed: ${error instanceof Error ? error.message : String(error)}`);
122
+ }
123
+ finally {
124
+ if (connection && lockedClaim && !retired) {
125
+ await connection.client.Runtime.evaluate({
126
+ expression: buildTargetRetirementRollbackExpression(lockedClaim, reservationId),
127
+ }).catch(() => undefined);
128
+ }
129
+ await connection?.close().catch(() => undefined);
130
+ }
131
+ }
@@ -2,10 +2,11 @@ import chalk from "chalk";
2
2
  import { formatTokenCount } from "../oracle/runUtils.js";
3
3
  import { formatFinishLine } from "../oracle/finishLine.js";
4
4
  import { runBrowserMode } from "../browserMode.js";
5
- import { assembleBrowserPrompt } from "./prompt.js";
5
+ import { DEFAULT_BROWSER_CONFIG } from "./config.js";
6
+ import { assembleBrowserPrompt, cleanupGeneratedBrowserBundles, materializeBrowserFallback, } from "./prompt.js";
6
7
  import { BrowserAutomationError } from "../oracle/errors.js";
7
8
  import { appendArtifacts, saveBrowserTranscriptArtifact, saveDeepResearchReportArtifact, } from "./artifacts.js";
8
- import { formatBrowserModelSelectionEvidence, formatBrowserModelTarget, resolveBrowserModelDisplayName, } from "./modelDisplay.js";
9
+ import { formatBrowserModelSelectionEvidence, formatBrowserThinkingSelectionEvidence, formatBrowserModelTarget, resolveBrowserModelDisplayName, } from "./modelDisplay.js";
9
10
  const LARGE_PRO_FAST_INPUT_TOKEN_THRESHOLD = 25_000;
10
11
  const LARGE_PRO_FAST_ELAPSED_MS_THRESHOLD = 120_000;
11
12
  function buildUnavailableModelSelectionEvidence(browserConfig) {
@@ -57,7 +58,50 @@ function buildBrowserRunWarnings(args) {
57
58
  export async function runBrowserSessionExecution({ runOptions, browserConfig, cwd, log }, deps = {}) {
58
59
  const assemblePrompt = deps.assemblePrompt ?? assembleBrowserPrompt;
59
60
  const executeBrowser = deps.executeBrowser ?? runBrowserMode;
60
- const promptArtifacts = await assemblePrompt(runOptions, { cwd });
61
+ const persistRuntimeHint = deps.persistRuntimeHint ?? (() => { });
62
+ const inputTimeoutMs = browserConfig.inputTimeoutMs ?? DEFAULT_BROWSER_CONFIG.inputTimeoutMs;
63
+ let preparationTimedOut = false;
64
+ let preparationTimeout;
65
+ let promptArtifacts;
66
+ try {
67
+ promptArtifacts = await Promise.race([
68
+ assemblePrompt(runOptions, { cwd }).then(async (artifacts) => {
69
+ if (preparationTimedOut)
70
+ await cleanupGeneratedBrowserBundles(artifacts);
71
+ return artifacts;
72
+ }),
73
+ new Promise((_, reject) => {
74
+ preparationTimeout = setTimeout(() => {
75
+ preparationTimedOut = true;
76
+ reject(new BrowserAutomationError(`Browser prompt preparation timed out after ${inputTimeoutMs}ms; increase --browser-input-timeout if local files need more time.`, {
77
+ stage: "prepare-prompt",
78
+ code: "prompt-preparation-timeout",
79
+ timeoutMs: inputTimeoutMs,
80
+ }));
81
+ }, inputTimeoutMs);
82
+ }),
83
+ ]);
84
+ }
85
+ finally {
86
+ if (preparationTimeout) {
87
+ clearTimeout(preparationTimeout);
88
+ }
89
+ }
90
+ try {
91
+ return await executeAssembledBrowserSession({
92
+ runOptions,
93
+ browserConfig,
94
+ log,
95
+ promptArtifacts,
96
+ executeBrowser,
97
+ persistRuntimeHint,
98
+ });
99
+ }
100
+ finally {
101
+ await cleanupGeneratedBrowserBundles(promptArtifacts);
102
+ }
103
+ }
104
+ async function executeAssembledBrowserSession({ runOptions, browserConfig, log, promptArtifacts, executeBrowser, persistRuntimeHint, }) {
61
105
  if (runOptions.verbose) {
62
106
  log(chalk.dim(`[verbose] Browser config: ${JSON.stringify({
63
107
  ...browserConfig,
@@ -91,7 +135,7 @@ export async function runBrowserSessionExecution({ runOptions, browserConfig, cw
91
135
  if (typeof message !== "string")
92
136
  return;
93
137
  const shouldAlwaysPrint = message.startsWith("[browser] ") &&
94
- /archive|fallback|follow-up|retry|thinking|waiting for chatgpt|browser slot|browser control|browser guidance|model selection|model picker/i.test(message);
138
+ /archive|fallback|follow-up|retry|thinking|research|waiting for chatgpt|remote debugging approval|browser slot|browser control|browser guidance|model selection|model picker/i.test(message);
95
139
  if (!runOptions.verbose && !shouldAlwaysPrint)
96
140
  return;
97
141
  log(message);
@@ -103,7 +147,22 @@ export async function runBrowserSessionExecution({ runOptions, browserConfig, cw
103
147
  if (runOptions.verbose) {
104
148
  log(chalk.dim("Chrome automation does not stream output; this may take a minute..."));
105
149
  }
106
- const persistRuntimeHint = deps.persistRuntimeHint ?? (() => { });
150
+ let fallbackSubmission = undefined;
151
+ if (promptArtifacts.fallback) {
152
+ fallbackSubmission = {
153
+ prompt: promptArtifacts.fallback.composerText,
154
+ attachments: promptArtifacts.fallback.attachments,
155
+ pendingBundle: promptArtifacts.fallback.pendingBundle ?? undefined,
156
+ prepare: async () => {
157
+ const prepared = await materializeBrowserFallback(promptArtifacts);
158
+ if (!prepared || !fallbackSubmission)
159
+ return;
160
+ fallbackSubmission.prompt = prepared.composerText;
161
+ fallbackSubmission.attachments = prepared.attachments;
162
+ fallbackSubmission.pendingBundle = undefined;
163
+ },
164
+ };
165
+ }
107
166
  const executionBrowserConfig = runOptions.browserResumeConversationUrl
108
167
  ? { ...browserConfig, resumeConversationUrl: runOptions.browserResumeConversationUrl }
109
168
  : browserConfig;
@@ -112,12 +171,7 @@ export async function runBrowserSessionExecution({ runOptions, browserConfig, cw
112
171
  browserResult = await executeBrowser({
113
172
  prompt: promptArtifacts.composerText,
114
173
  attachments: promptArtifacts.attachments,
115
- fallbackSubmission: promptArtifacts.fallback
116
- ? {
117
- prompt: promptArtifacts.fallback.composerText,
118
- attachments: promptArtifacts.fallback.attachments,
119
- }
120
- : undefined,
174
+ fallbackSubmission,
121
175
  config: executionBrowserConfig,
122
176
  log: automationLogger,
123
177
  heartbeatIntervalMs: runOptions.heartbeatIntervalMs,
@@ -151,6 +205,10 @@ export async function runBrowserSessionExecution({ runOptions, browserConfig, cw
151
205
  if (modelSelection) {
152
206
  log(`[browser] Model selection evidence: ${formatBrowserModelSelectionEvidence(modelSelection, runOptions.model)}`);
153
207
  }
208
+ const thinkingSelection = browserResult.thinkingSelection;
209
+ if (thinkingSelection) {
210
+ log(`[browser] Thinking effort evidence: ${formatBrowserThinkingSelectionEvidence(thinkingSelection)}`);
211
+ }
154
212
  const warnings = buildBrowserRunWarnings({
155
213
  runOptions,
156
214
  browserConfig,
@@ -220,16 +278,20 @@ export async function runBrowserSessionExecution({ runOptions, browserConfig, cw
220
278
  chromeProfileRoot: browserResult.chromeProfileRoot,
221
279
  userDataDir: browserResult.userDataDir,
222
280
  chromeTargetId: browserResult.chromeTargetId,
281
+ ownedRecoveryTarget: browserResult.ownedRecoveryTarget,
223
282
  tabUrl: browserResult.tabUrl,
224
283
  conversationId: browserResult.conversationId,
225
284
  promptSubmitted: browserResult.promptSubmitted,
285
+ researchPlan: browserResult.researchPlan,
226
286
  controllerPid: browserResult.controllerPid ?? process.pid,
227
287
  },
228
288
  archive: browserResult.archive,
229
289
  modelSelection,
290
+ thinkingSelection,
230
291
  warnings,
231
292
  answerText,
232
293
  artifacts: savedArtifacts,
294
+ savedFiles: browserResult.savedFiles,
233
295
  };
234
296
  }
235
297
  export async function ensureSessionArtifacts(params) {