@steipete/oracle 0.21.0 → 0.21.2
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/dist/bin/oracle-cli.js +14 -15
- package/dist/src/browser/executor.js +9 -4
- package/dist/src/browser/profileState.js +2 -0
- package/dist/src/browser/provider.js +15 -1
- package/dist/src/browser/sessionRunner.js +2 -2
- package/dist/src/gemini-web/browserSessionManager.js +15 -2
- package/dist/src/gemini-web/executor.js +1 -1
- package/dist/src/gemini-web/http.js +11 -2
- package/dist/src/remote/client.js +25 -9
- package/dist/src/remote/server.js +19 -5
- package/package.json +11 -10
- package/dist/docs-site/.nojekyll +0 -0
- package/dist/docs-site/CNAME +0 -1
- package/dist/docs-site/RELEASING.html +0 -403
- package/dist/docs-site/advisor.html +0 -317
- package/dist/docs-site/agents.html +0 -375
- package/dist/docs-site/anthropic.html +0 -368
- package/dist/docs-site/bridge.html +0 -421
- package/dist/docs-site/browser-mode.html +0 -636
- package/dist/docs-site/chromium-forks.html +0 -355
- package/dist/docs-site/cli-reference.html +0 -347
- package/dist/docs-site/configuration.html +0 -464
- package/dist/docs-site/favicon.svg +0 -14
- package/dist/docs-site/followup.html +0 -375
- package/dist/docs-site/gemini.html +0 -387
- package/dist/docs-site/grok.html +0 -325
- package/dist/docs-site/index.html +0 -360
- package/dist/docs-site/install.html +0 -335
- package/dist/docs-site/linux.html +0 -321
- package/dist/docs-site/llms.txt +0 -44
- package/dist/docs-site/manual-tests.html +0 -621
- package/dist/docs-site/mcp.html +0 -412
- package/dist/docs-site/multimodel.html +0 -364
- package/dist/docs-site/mythical-pro-agents.html +0 -360
- package/dist/docs-site/notifier.html +0 -338
- package/dist/docs-site/openai-endpoints.html +0 -417
- package/dist/docs-site/openrouter.html +0 -344
- package/dist/docs-site/quickstart.html +0 -369
- package/dist/docs-site/refactor/ux.html +0 -321
- package/dist/docs-site/sessions.html +0 -397
- package/dist/docs-site/social-card.png +0 -0
- package/dist/docs-site/social-card.svg +0 -79
- package/dist/docs-site/spec.html +0 -363
- package/dist/docs-site/testing.html +0 -323
- package/dist/docs-site/tui-debug.html +0 -326
- package/dist/docs-site/windows-work.html +0 -348
- package/dist/docs-site/windows.html +0 -320
|
@@ -1,636 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
-
<title>Browser Mode — oracle</title>
|
|
7
|
-
<meta name="description" content="Browser Mode — oracle CLI documentation.">
|
|
8
|
-
<link rel="canonical" href="https://askoracle.sh/browser-mode.html">
|
|
9
|
-
<meta property="og:type" content="website">
|
|
10
|
-
<meta property="og:site_name" content="oracle">
|
|
11
|
-
<meta property="og:title" content="Browser Mode — oracle">
|
|
12
|
-
<meta property="og:description" content="Browser Mode — oracle CLI documentation.">
|
|
13
|
-
<meta property="og:url" content="https://askoracle.sh/browser-mode.html">
|
|
14
|
-
<meta property="og:image" content="https://askoracle.sh/social-card.png">
|
|
15
|
-
<meta property="og:image:width" content="1200">
|
|
16
|
-
<meta property="og:image:height" content="630">
|
|
17
|
-
<meta name="twitter:card" content="summary_large_image">
|
|
18
|
-
<meta name="twitter:title" content="Browser Mode — oracle">
|
|
19
|
-
<meta name="twitter:description" content="Browser Mode — oracle CLI documentation.">
|
|
20
|
-
<meta name="twitter:image" content="https://askoracle.sh/social-card.png">
|
|
21
|
-
<link rel="icon" href="favicon.svg" type="image/svg+xml">
|
|
22
|
-
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
23
|
-
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
24
|
-
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
|
|
25
|
-
<script>(function(){var s;try{s=localStorage.getItem('theme')}catch(e){}var d=window.matchMedia&&matchMedia('(prefers-color-scheme: dark)').matches;document.documentElement.dataset.theme=s||(d?'dark':'light')})();</script>
|
|
26
|
-
<style>
|
|
27
|
-
:root{
|
|
28
|
-
--ink:#0e0a1f;
|
|
29
|
-
--text:#1d1832;
|
|
30
|
-
--muted:#6b6582;
|
|
31
|
-
--subtle:#9c95b5;
|
|
32
|
-
--bg:#fafaff;
|
|
33
|
-
--paper:#ffffff;
|
|
34
|
-
--accent:#7c3aed;
|
|
35
|
-
--accent-soft:rgba(124,58,237,.10);
|
|
36
|
-
--accent-strong:#5b21b6;
|
|
37
|
-
--accent-2:#0ea5e9;
|
|
38
|
-
--accent-glow:#a78bfa;
|
|
39
|
-
--line:#e7e3f0;
|
|
40
|
-
--line-soft:#f2eff8;
|
|
41
|
-
--code-bg:#0c0a1a;
|
|
42
|
-
--code-fg:#e9e6f5;
|
|
43
|
-
--code-inline-fg:#1c1734;
|
|
44
|
-
--pill-border:#dcd5ec;
|
|
45
|
-
--shadow-card:0 4px 14px rgba(14,10,31,.08);
|
|
46
|
-
--scrollbar:#cbc4dc;
|
|
47
|
-
}
|
|
48
|
-
:root[data-theme="dark"]{
|
|
49
|
-
--ink:#f5f2ff;
|
|
50
|
-
--text:#cec7e4;
|
|
51
|
-
--muted:#9189a8;
|
|
52
|
-
--subtle:#6a6383;
|
|
53
|
-
--bg:#0a0815;
|
|
54
|
-
--paper:#15102a;
|
|
55
|
-
--accent:#a78bfa;
|
|
56
|
-
--accent-soft:rgba(167,139,250,.18);
|
|
57
|
-
--accent-strong:#c4b5fd;
|
|
58
|
-
--accent-2:#38bdf8;
|
|
59
|
-
--accent-glow:#c4b5fd;
|
|
60
|
-
--line:#272140;
|
|
61
|
-
--line-soft:#1c1734;
|
|
62
|
-
--code-bg:#06040d;
|
|
63
|
-
--code-fg:#e9e6f5;
|
|
64
|
-
--code-inline-fg:#e9e6f5;
|
|
65
|
-
--pill-border:#2c2549;
|
|
66
|
-
--shadow-card:0 4px 18px rgba(0,0,0,.45);
|
|
67
|
-
--scrollbar:#3a3358;
|
|
68
|
-
}
|
|
69
|
-
:root{color-scheme:light}
|
|
70
|
-
:root[data-theme="dark"]{color-scheme:dark}
|
|
71
|
-
*{box-sizing:border-box}
|
|
72
|
-
html{scroll-behavior:smooth;scroll-padding-top:24px}
|
|
73
|
-
body{margin:0;background:var(--bg);color:var(--text);font-family:"Inter",ui-sans-serif,system-ui,-apple-system,Segoe UI,sans-serif;line-height:1.65;overflow-x:hidden;-webkit-font-smoothing:antialiased;font-feature-settings:"cv02","cv03","cv04","cv11";transition:background-color .18s,color .18s}
|
|
74
|
-
::selection{background:var(--accent);color:#fff}
|
|
75
|
-
a{color:var(--accent);text-decoration:none;transition:color .12s}
|
|
76
|
-
a:hover{text-decoration:underline;text-underline-offset:.2em}
|
|
77
|
-
.shell{display:grid;grid-template-columns:268px minmax(0,1fr);min-height:100vh}
|
|
78
|
-
.sidebar{position:sticky;top:0;height:100vh;overflow:auto;padding:24px 22px;background:var(--paper);border-right:1px solid var(--line);scrollbar-width:thin;scrollbar-color:var(--line) transparent;transition:background-color .18s,border-color .18s}
|
|
79
|
-
.sidebar::-webkit-scrollbar{width:6px}
|
|
80
|
-
.sidebar::-webkit-scrollbar-thumb{background:var(--line);border-radius:6px}
|
|
81
|
-
.sidebar-head{display:flex;align-items:center;gap:10px;margin-bottom:24px}
|
|
82
|
-
.brand{display:flex;align-items:center;gap:11px;color:var(--ink);text-decoration:none;flex:1;min-width:0}
|
|
83
|
-
.brand:hover{text-decoration:none}
|
|
84
|
-
.brand .mark{flex:0 0 30px;width:30px;height:30px;border-radius:50%;background:radial-gradient(circle at 32% 32%,#fff 0,#e0d4ff 22%,#7c3aed 60%,#1e1240 100%);box-shadow:0 0 0 1px rgba(124,58,237,.35),0 6px 18px rgba(124,58,237,.35);position:relative}
|
|
85
|
-
.brand .mark::after{content:"";position:absolute;left:50%;top:50%;width:9px;height:9px;border-radius:50%;background:#0c0820;transform:translate(-50%,-50%)}
|
|
86
|
-
.brand strong{display:block;font-size:1.05rem;line-height:1.1;font-weight:600;letter-spacing:0;color:var(--ink)}
|
|
87
|
-
.brand small{display:block;color:var(--muted);font-size:.74rem;margin-top:3px;font-weight:400}
|
|
88
|
-
.theme-toggle{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:34px;height:34px;border-radius:8px;border:1px solid var(--line);background:var(--paper);color:var(--muted);cursor:pointer;padding:0;transition:border-color .15s,color .15s,background-color .15s,transform .12s}
|
|
89
|
-
.theme-toggle:hover{border-color:var(--ink);color:var(--ink)}
|
|
90
|
-
.theme-toggle:active{transform:scale(.94)}
|
|
91
|
-
.theme-toggle svg{width:16px;height:16px;display:block}
|
|
92
|
-
.theme-icon-sun{display:none}
|
|
93
|
-
:root[data-theme="dark"] .theme-icon-sun{display:block}
|
|
94
|
-
:root[data-theme="dark"] .theme-icon-moon{display:none}
|
|
95
|
-
.search{display:block;margin:0 0 22px}
|
|
96
|
-
.search span{display:block;color:var(--muted);font-size:.7rem;font-weight:600;text-transform:uppercase;letter-spacing:0;margin-bottom:7px}
|
|
97
|
-
.search input{width:100%;border:1px solid var(--line);background:var(--paper);border-radius:8px;padding:9px 12px;font:inherit;font-size:.9rem;color:var(--text);outline:none;transition:border-color .15s,box-shadow .15s,background-color .18s}
|
|
98
|
-
.search input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}
|
|
99
|
-
nav section{margin:0 0 18px}
|
|
100
|
-
nav h2{font-size:.68rem;color:var(--muted);text-transform:uppercase;letter-spacing:0;margin:0 0 6px;font-weight:600}
|
|
101
|
-
.nav-link{display:block;color:var(--text);text-decoration:none;border-radius:6px;padding:5px 10px;margin:1px 0;font-size:.9rem;line-height:1.4;transition:background .12s,color .12s}
|
|
102
|
-
.nav-link:hover{background:var(--line-soft);color:var(--ink);text-decoration:none}
|
|
103
|
-
.nav-link.active{background:var(--accent-soft);color:var(--accent);font-weight:600}
|
|
104
|
-
main{min-width:0;padding:32px clamp(20px,4.5vw,56px) 80px;max-width:1180px;margin:0 auto;width:100%}
|
|
105
|
-
.hero{display:flex;align-items:flex-end;justify-content:space-between;gap:22px;border-bottom:1px solid var(--line);padding:8px 0 22px;margin-bottom:8px;flex-wrap:wrap}
|
|
106
|
-
.hero-text{min-width:0;flex:1 1 320px}
|
|
107
|
-
.eyebrow{margin:0 0 8px;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:0;font-size:.7rem}
|
|
108
|
-
.hero h1{font-size:2.25rem;line-height:1.1;letter-spacing:0;margin:0;font-weight:700;color:var(--ink)}
|
|
109
|
-
.hero-meta{display:flex;gap:8px;flex:0 0 auto;flex-wrap:wrap}
|
|
110
|
-
.repo,.edit,.btn-ghost{border:1px solid var(--line);color:var(--text);text-decoration:none;border-radius:7px;padding:6px 11px;font-weight:500;font-size:.83rem;background:var(--paper);transition:border-color .15s,color .15s,background .15s}
|
|
111
|
-
.repo:hover,.edit:hover,.btn-ghost:hover{border-color:var(--ink);color:var(--ink);text-decoration:none}
|
|
112
|
-
.edit{color:var(--muted)}
|
|
113
|
-
.home-hero{position:relative;padding:24px 0 32px;margin-bottom:8px;border-bottom:1px solid var(--line)}
|
|
114
|
-
.home-hero>*{position:relative;z-index:1}
|
|
115
|
-
.home-hero h1{font-size:3.4rem;line-height:1.04;letter-spacing:0;margin:0 0 .35em;font-weight:700;color:var(--ink);background:linear-gradient(135deg,var(--ink) 0,#7c3aed 60%,#0ea5e9 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
|
|
116
|
-
:root[data-theme="dark"] .home-hero h1{background:linear-gradient(135deg,#f5f2ff 0,#c4b5fd 50%,#7dd3fc 100%);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
|
|
117
|
-
.home-hero .lede{font-size:1.18rem;line-height:1.55;color:var(--text);margin:0 0 1.2em;max-width:62ch}
|
|
118
|
-
.home-cta{display:flex;flex-wrap:wrap;gap:10px;align-items:center;margin:0 0 18px}
|
|
119
|
-
.home-cta .btn{display:inline-flex;align-items:center;gap:7px;border-radius:8px;padding:10px 16px;font-weight:600;font-size:.92rem;text-decoration:none;transition:background .15s,border-color .15s,color .15s,transform .12s}
|
|
120
|
-
.home-cta .btn-primary{background:linear-gradient(135deg,var(--accent),var(--accent-strong));color:#fff;border:1px solid var(--accent);box-shadow:0 4px 14px rgba(124,58,237,.35)}
|
|
121
|
-
.home-cta .btn-primary:hover{background:var(--accent-strong);border-color:var(--accent-strong);text-decoration:none;transform:translateY(-1px)}
|
|
122
|
-
.home-cta .btn-ghost{padding:10px 16px}
|
|
123
|
-
.home-install{display:flex;align-items:center;gap:12px;background:var(--code-bg);color:var(--code-fg);border-radius:8px;padding:10px 10px 10px 16px;font:500 .9rem/1.2 "JetBrains Mono","SF Mono",ui-monospace,monospace;max-width:34em;border:1px solid #1f1840}
|
|
124
|
-
.home-install .prompt{color:#6f63a3;user-select:none;flex:0 0 auto}
|
|
125
|
-
.home-install code{flex:1;background:transparent;border:0;color:var(--code-fg);font:inherit;padding:0;white-space:pre;overflow:hidden;text-overflow:ellipsis}
|
|
126
|
-
.home-install .copy{flex:0 0 auto;background:rgba(255,255,255,.08);color:var(--code-fg);border:1px solid rgba(255,255,255,.16);border-radius:6px;padding:5px 11px;font:500 .72rem/1 "Inter",sans-serif;cursor:pointer;transition:background .15s,border-color .15s}
|
|
127
|
-
.home-install .copy:hover{background:rgba(255,255,255,.16)}
|
|
128
|
-
.home-install .copy.copied{background:var(--accent);border-color:var(--accent)}
|
|
129
|
-
.home-services{display:flex;flex-wrap:wrap;gap:6px;margin:6px 0 18px}
|
|
130
|
-
.home-services span{display:inline-block;padding:3px 10px;border:1px solid var(--pill-border);border-radius:999px;font-size:.78rem;color:var(--muted);background:var(--paper)}
|
|
131
|
-
.home-services span.pill-pro{background:var(--accent-soft);color:var(--accent);border-color:transparent;font-weight:600}
|
|
132
|
-
.home-visual{display:block;width:min(100%,620px);height:auto;margin:22px 0 0;border-radius:8px;border:1px solid var(--line);box-shadow:var(--shadow-card);background:var(--paper)}
|
|
133
|
-
.doc-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:48px;margin-top:24px}
|
|
134
|
-
.doc-grid-home{margin-top:8px}
|
|
135
|
-
@media(min-width:1180px){.doc-grid{grid-template-columns:minmax(0,72ch) 200px;justify-content:start}.doc-grid-home{grid-template-columns:minmax(0,76ch);justify-content:start}}
|
|
136
|
-
.doc{min-width:0;max-width:72ch;overflow-wrap:break-word}
|
|
137
|
-
.doc-home{max-width:76ch}
|
|
138
|
-
.doc h1{font-size:2.6rem;line-height:1.08;letter-spacing:0;margin:0 0 .4em;font-weight:700;color:var(--ink)}
|
|
139
|
-
body:not(.home) .doc>h1:first-child{display:none}
|
|
140
|
-
.doc h2{font-size:1.45rem;line-height:1.2;margin:2em 0 .5em;font-weight:600;letter-spacing:0;color:var(--ink);position:relative}
|
|
141
|
-
.doc h3{font-size:1.1rem;margin:1.7em 0 .35em;position:relative;font-weight:600;color:var(--ink);letter-spacing:0}
|
|
142
|
-
.doc h4{font-size:.98rem;margin:1.4em 0 .25em;color:var(--ink);position:relative;font-weight:600}
|
|
143
|
-
.doc h2:first-child,.doc h3:first-child,.doc h4:first-child{margin-top:.2em}
|
|
144
|
-
.doc :is(h2,h3,h4) .anchor{position:absolute;left:-1.05em;top:0;color:var(--subtle);opacity:0;text-decoration:none;font-weight:400;padding-right:.3em;transition:opacity .12s,color .12s}
|
|
145
|
-
.doc :is(h2,h3,h4):hover .anchor{opacity:.7}
|
|
146
|
-
.doc :is(h2,h3,h4) .anchor:hover{opacity:1;color:var(--accent);text-decoration:none}
|
|
147
|
-
.doc p{margin:0 0 1.05em}
|
|
148
|
-
.doc ul,.doc ol{padding-left:1.3rem;margin:0 0 1.15em}
|
|
149
|
-
.doc li{margin:.25em 0}
|
|
150
|
-
.doc li>p{margin:0 0 .4em}
|
|
151
|
-
.doc strong{font-weight:600;color:var(--ink)}
|
|
152
|
-
.doc em{font-style:italic}
|
|
153
|
-
.doc code{font-family:"JetBrains Mono","SF Mono",ui-monospace,monospace;font-size:.84em;background:var(--line-soft);border:1px solid var(--line);border-radius:5px;padding:.08em .35em;color:var(--code-inline-fg)}
|
|
154
|
-
.doc pre{position:relative;overflow:auto;background:var(--code-bg);color:var(--code-fg);border-radius:8px;padding:14px 18px;margin:1.3em 0;font-size:.85em;line-height:1.6;scrollbar-width:thin;scrollbar-color:#3a3358 transparent;border:1px solid #221c40}
|
|
155
|
-
.doc pre.shiki{background:var(--code-bg)!important;color:var(--code-fg)!important}
|
|
156
|
-
.doc pre::-webkit-scrollbar{height:8px;width:8px}
|
|
157
|
-
.doc pre::-webkit-scrollbar-thumb{background:#3a3358;border-radius:8px}
|
|
158
|
-
.doc pre code{display:block;background:transparent;border:0;color:inherit;padding:0;font-size:1em;white-space:pre}
|
|
159
|
-
.doc pre code .line{display:block;min-height:1.6em}
|
|
160
|
-
.doc pre .copy{position:absolute;top:8px;right:8px;background:rgba(255,255,255,.06);color:var(--code-fg);border:1px solid rgba(255,255,255,.16);border-radius:6px;padding:3px 9px;font:500 .7rem/1 "Inter",sans-serif;cursor:pointer;opacity:0;transition:opacity .15s,background .15s,border-color .15s}
|
|
161
|
-
.doc pre:hover .copy,.doc pre .copy:focus{opacity:1}
|
|
162
|
-
.doc pre .copy:hover{background:rgba(255,255,255,.12)}
|
|
163
|
-
.doc pre .copy.copied{background:var(--accent);border-color:var(--accent);opacity:1}
|
|
164
|
-
.doc blockquote{margin:1.4em 0;padding:10px 16px;border-left:3px solid var(--accent);background:var(--accent-soft);border-radius:0 8px 8px 0;color:var(--text)}
|
|
165
|
-
.doc blockquote p:last-child{margin-bottom:0}
|
|
166
|
-
.doc table{width:100%;border-collapse:collapse;margin:1.2em 0;font-size:.92em}
|
|
167
|
-
.doc th,.doc td{border-bottom:1px solid var(--line);padding:9px 10px;text-align:left;vertical-align:top}
|
|
168
|
-
.doc th{font-weight:600;color:var(--ink);background:var(--line-soft);border-bottom:1px solid var(--line)}
|
|
169
|
-
.doc hr{border:0;border-top:1px solid var(--line);margin:2.2em 0}
|
|
170
|
-
.toc{position:sticky;top:24px;align-self:start;font-size:.84rem;padding-left:14px;border-left:1px solid var(--line);max-height:calc(100vh - 48px);overflow:auto;scrollbar-width:thin;scrollbar-color:var(--line) transparent}
|
|
171
|
-
.toc::-webkit-scrollbar{width:5px}
|
|
172
|
-
.toc::-webkit-scrollbar-thumb{background:var(--line);border-radius:5px}
|
|
173
|
-
.toc h2{font-size:.66rem;color:var(--muted);text-transform:uppercase;letter-spacing:0;margin:0 0 10px;font-weight:600}
|
|
174
|
-
.toc a{display:block;color:var(--muted);text-decoration:none;padding:4px 0 4px 10px;line-height:1.35;border-left:2px solid transparent;margin-left:-12px;transition:color .12s,border-color .12s}
|
|
175
|
-
.toc a:hover{color:var(--ink);text-decoration:none}
|
|
176
|
-
.toc a.active{color:var(--accent);border-left-color:var(--accent);font-weight:500}
|
|
177
|
-
.toc-l3{padding-left:22px!important;font-size:.94em}
|
|
178
|
-
@media(max-width:1179px){.toc{display:none}}
|
|
179
|
-
.page-nav{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:48px;border-top:1px solid var(--line);padding-top:20px}
|
|
180
|
-
.page-nav>a{display:block;border:1px solid var(--line);background:var(--paper);border-radius:9px;padding:13px 16px;text-decoration:none;color:var(--text);transition:border-color .15s,transform .15s,box-shadow .15s,background-color .18s}
|
|
181
|
-
.page-nav>a:hover{border-color:var(--accent);text-decoration:none;color:var(--ink)}
|
|
182
|
-
.page-nav small{display:block;color:var(--muted);font-size:.7rem;text-transform:uppercase;letter-spacing:0;margin-bottom:5px;font-weight:600}
|
|
183
|
-
.page-nav span{display:block;font-weight:600;line-height:1.3;color:var(--ink)}
|
|
184
|
-
.page-nav-prev{text-align:left}
|
|
185
|
-
.page-nav-next{text-align:right;grid-column:2}
|
|
186
|
-
.page-nav-prev:only-child{grid-column:1}
|
|
187
|
-
.nav-toggle{display:none;position:fixed;top:14px;right:14px;top:calc(14px + env(safe-area-inset-top, 0px));right:calc(14px + env(safe-area-inset-right, 0px));z-index:20;width:40px;height:40px;border-radius:9px;background:var(--paper);border:1px solid var(--line);color:var(--ink);cursor:pointer;padding:10px 9px;flex-direction:column;align-items:stretch;justify-content:space-between;box-shadow:var(--shadow-card)}
|
|
188
|
-
.nav-toggle span{display:block;width:100%;height:2px;flex:0 0 2px;background:currentColor;border-radius:2px;transition:transform .2s,opacity .2s}
|
|
189
|
-
.nav-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(8px) rotate(45deg)}
|
|
190
|
-
.nav-toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
|
|
191
|
-
.nav-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-8px) rotate(-45deg)}
|
|
192
|
-
@media(max-width:900px){
|
|
193
|
-
.shell{display:block}
|
|
194
|
-
.sidebar{position:fixed;inset:0 30% 0 0;max-width:320px;height:100vh;z-index:15;transform:translateX(-100%);transition:transform .25s ease,background-color .18s,border-color .18s;box-shadow:0 18px 40px rgba(0,0,0,.18);background:var(--paper);pointer-events:none}
|
|
195
|
-
.sidebar.open{transform:translateX(0);pointer-events:auto}
|
|
196
|
-
.nav-toggle{display:flex}
|
|
197
|
-
main{padding:64px 18px 56px}
|
|
198
|
-
.hero{padding-top:6px}
|
|
199
|
-
.hero h1{font-size:1.8rem}
|
|
200
|
-
.home-hero h1{font-size:2.45rem}
|
|
201
|
-
.doc h1{font-size:2.1rem}
|
|
202
|
-
.hero-meta{width:100%;justify-content:flex-start}
|
|
203
|
-
.home-hero{padding-top:8px}
|
|
204
|
-
.home-visual{margin-top:18px}
|
|
205
|
-
.doc{padding:0}
|
|
206
|
-
.doc-grid{margin-top:18px;gap:24px}
|
|
207
|
-
.doc :is(h2,h3,h4) .anchor{display:none}
|
|
208
|
-
}
|
|
209
|
-
@media(max-width:520px){
|
|
210
|
-
main{padding:60px 14px 48px}
|
|
211
|
-
.doc pre{margin-left:-14px;margin-right:-14px;border-radius:0;border-left:0;border-right:0}
|
|
212
|
-
.home-install{flex-wrap:wrap}
|
|
213
|
-
}
|
|
214
|
-
</style>
|
|
215
|
-
</head>
|
|
216
|
-
<body>
|
|
217
|
-
<button class="nav-toggle" type="button" aria-label="Toggle navigation" aria-expanded="false">
|
|
218
|
-
<span aria-hidden="true"></span><span aria-hidden="true"></span><span aria-hidden="true"></span>
|
|
219
|
-
</button>
|
|
220
|
-
<div class="shell">
|
|
221
|
-
<aside class="sidebar">
|
|
222
|
-
<div class="sidebar-head">
|
|
223
|
-
<a class="brand" href="./" aria-label="oracle docs home">
|
|
224
|
-
<span class="mark" aria-hidden="true"></span>
|
|
225
|
-
<span><strong>oracle</strong><small>askoracle.sh</small></span>
|
|
226
|
-
</a>
|
|
227
|
-
<button class="theme-toggle" type="button" aria-label="Toggle dark mode" aria-pressed="false" data-theme-toggle>
|
|
228
|
-
<svg class="theme-icon-moon" viewBox="0 0 20 20" aria-hidden="true"><path d="M14.6 12.1A6.5 6.5 0 0 1 7.4 2.7a6.5 6.5 0 1 0 7.2 9.4z" fill="currentColor"/></svg>
|
|
229
|
-
<svg class="theme-icon-sun" viewBox="0 0 20 20" aria-hidden="true"><circle cx="10" cy="10" r="3.4" fill="currentColor"/><g stroke="currentColor" stroke-width="1.6" stroke-linecap="round"><line x1="10" y1="2" x2="10" y2="4"/><line x1="10" y1="16" x2="10" y2="18"/><line x1="2" y1="10" x2="4" y2="10"/><line x1="16" y1="10" x2="18" y2="10"/><line x1="4.2" y1="4.2" x2="5.6" y2="5.6"/><line x1="14.4" y1="14.4" x2="15.8" y2="15.8"/><line x1="4.2" y1="15.8" x2="5.6" y2="14.4"/><line x1="14.4" y1="5.6" x2="15.8" y2="4.2"/></g></svg>
|
|
230
|
-
</button>
|
|
231
|
-
</div>
|
|
232
|
-
<label class="search"><span>Search</span><input id="doc-search" type="search" placeholder="browser, mcp, sessions"></label>
|
|
233
|
-
<nav><section><h2>Start</h2><a class="nav-link" href="./">Overview</a><a class="nav-link" href="install.html">Install</a><a class="nav-link" href="quickstart.html">Quickstart</a><a class="nav-link" href="configuration.html">Local configuration (JSON5)</a></section><section><h2>Mythical Pro Agents</h2><a class="nav-link" href="mythical-pro-agents.html">Mythical Pro Agents</a><a class="nav-link" href="openai-endpoints.html">OpenAI-Compatible Endpoints</a><a class="nav-link" href="anthropic.html">Anthropic (Claude) Integration Plan</a><a class="nav-link" href="gemini.html">Gemini Integration</a><a class="nav-link" href="openrouter.html">OpenRouter</a><a class="nav-link" href="grok.html">Grok 4.1 (xAI) Support</a></section><section><h2>Browser Mode</h2><a class="nav-link active" href="browser-mode.html">Browser Mode</a><a class="nav-link" href="chromium-forks.html">Chromium-based browsers (Chromium, Edge, Brave variants)</a><a class="nav-link" href="linux.html">Linux Notes</a><a class="nav-link" href="windows.html">Windows compatibility notes</a><a class="nav-link" href="windows-work.html">Windows Work</a><a class="nav-link" href="bridge.html">Bridge (Windows-hosted ChatGPT session → Linux clients)</a></section><section><h2>Agents & MCP</h2><a class="nav-link" href="agents.html">Coding Agents</a><a class="nav-link" href="mcp.html">MCP Server</a></section><section><h2>Workflows</h2><a class="nav-link" href="sessions.html">Sessions</a><a class="nav-link" href="followup.html">Followups & Lineage</a><a class="nav-link" href="multimodel.html">Multi-Model Execution</a></section><section><h2>Reference</h2><a class="nav-link" href="cli-reference.html">CLI Reference</a><a class="nav-link" href="spec.html">Spec</a><a class="nav-link" href="notifier.html">Session completion notifications</a><a class="nav-link" href="tui-debug.html">TUI navigation crash notes (2025-11-19)</a><a class="nav-link" href="manual-tests.html">Manual Test Suite (Browser Mode + Live API)</a><a class="nav-link" href="testing.html">Testing quickstart</a><a class="nav-link" href="RELEASING.html">Release Checklist (npm + Homebrew)</a></section></nav>
|
|
234
|
-
</aside>
|
|
235
|
-
<main>
|
|
236
|
-
<header class="hero">
|
|
237
|
-
<div class="hero-text">
|
|
238
|
-
<p class="eyebrow">Browser Mode</p>
|
|
239
|
-
<h1>Browser Mode</h1>
|
|
240
|
-
</div>
|
|
241
|
-
<div class="hero-meta">
|
|
242
|
-
<a class="repo" href="https://github.com/steipete/oracle" rel="noopener">GitHub</a>
|
|
243
|
-
<a class="edit" href="https://github.com/steipete/oracle/edit/main/docs/browser-mode.md" rel="noopener">Edit page</a>
|
|
244
|
-
</div>
|
|
245
|
-
</header>
|
|
246
|
-
<div class="doc-grid">
|
|
247
|
-
<article class="doc"><h1 id="browser-mode">Browser Mode</h1>
|
|
248
|
-
<p>Oracle’s <code>--engine browser</code> supports three different execution paths:</p>
|
|
249
|
-
<ul>
|
|
250
|
-
<li><strong>ChatGPT launcher mode</strong> (GPT-\* models): Oracle launches Chrome itself and drives the ChatGPT web UI over CDP.</li>
|
|
251
|
-
<li><strong>ChatGPT attach-running mode</strong> (GPT-\* models): Oracle attaches to your already-running local Chrome session through Chrome’s local remote-debugging toggle, opens a dedicated tab, and leaves the browser process/profile alone.</li>
|
|
252
|
-
<li><strong>Gemini web mode</strong> (Gemini models): talks directly to <code>gemini.google.com</code> using your signed-in Chrome cookies (no ChatGPT automation).</li>
|
|
253
|
-
</ul>
|
|
254
|
-
<p>If you’re running Gemini, also see <code>docs/gemini.md</code>.</p>
|
|
255
|
-
<p><code>oracle --engine browser</code> routes the assembled prompt bundle through the ChatGPT web UI instead of the Responses API. (Legacy <code>--browser</code> still maps to <code>--engine browser</code>, but it will be removed.) If you omit <code>--engine</code>, Oracle first honors <code>ORACLE_ENGINE</code>, then any <code>engine</code> value in the effective config, including project <code>.oracle/config.json</code> files layered over <code>~/.oracle/config.json</code>. It auto-picks API when <code>OPENAI_API_KEY</code> is available and falls back to browser otherwise. The CLI writes the same session metadata/logs as API runs. Use <code>--browser-manual-login</code> for the recommended persistent automation profile, or supply inline cookies. A plain launcher run still uses a temporary Chrome profile, but it no longer copies cookies from your live Chrome profile unless you explicitly opt in.</p>
|
|
256
|
-
<p><code>--preview</code> now works with <code>--engine browser</code>: it renders the composed prompt, lists which files would be uploaded vs inlined, and shows the bundle location when bundling is enabled, without launching Chrome.</p>
|
|
257
|
-
<h2 id="quick-example-browser-mode-with-custom-cookies"><a class="anchor" href="#quick-example-browser-mode-with-custom-cookies" aria-label="Anchor link">#</a>Quick example: browser mode with custom cookies</h2>
|
|
258
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#768390"># Minimal inline-cookies flow: keep ChatGPT logged in without Keychain</span></span>
|
|
259
|
-
<span class="line"><span style="color:#F69D50">jq</span><span style="color:#96D0FF"> '.'</span><span style="color:#96D0FF"> ~/.oracle/cookies.json</span><span style="color:#768390"> # file must contain CookieParam[]</span></span>
|
|
260
|
-
<span class="line"><span style="color:#F69D50">oracle</span><span style="color:#6CB6FF"> --engine</span><span style="color:#96D0FF"> browser</span><span style="color:#F47067"> \</span></span>
|
|
261
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-inline-cookies-file</span><span style="color:#96D0FF"> ~/.oracle/cookies.json</span><span style="color:#F47067"> \</span></span>
|
|
262
|
-
<span class="line"><span style="color:#6CB6FF"> --model</span><span style="color:#96D0FF"> gpt-5.5</span><span style="color:#F47067"> \</span></span>
|
|
263
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-thinking-time</span><span style="color:#96D0FF"> pro</span><span style="color:#F47067"> \</span></span>
|
|
264
|
-
<span class="line"><span style="color:#6CB6FF"> -p</span><span style="color:#96D0FF"> "Run the UI smoke"</span><span style="color:#F47067"> \</span></span>
|
|
265
|
-
<span class="line"><span style="color:#6CB6FF"> --file</span><span style="color:#96D0FF"> "src/**/*.ts"</span><span style="color:#6CB6FF"> --file</span><span style="color:#96D0FF"> "!src/**/*.test.ts"</span></span></code></pre>
|
|
266
|
-
<p><code>~/.oracle/cookies.json</code> should be a JSON array shaped like:</p>
|
|
267
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-json"><span class="line"><span style="color:#ADBAC7">[</span></span>
|
|
268
|
-
<span class="line"><span style="color:#ADBAC7"> {</span></span>
|
|
269
|
-
<span class="line"><span style="color:#8DDB8C"> "name"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"__Secure-next-auth.session-token"</span><span style="color:#ADBAC7">,</span></span>
|
|
270
|
-
<span class="line"><span style="color:#8DDB8C"> "value"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"<token>"</span><span style="color:#ADBAC7">,</span></span>
|
|
271
|
-
<span class="line"><span style="color:#8DDB8C"> "domain"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"chatgpt.com"</span><span style="color:#ADBAC7">,</span></span>
|
|
272
|
-
<span class="line"><span style="color:#8DDB8C"> "path"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"/"</span><span style="color:#ADBAC7">,</span></span>
|
|
273
|
-
<span class="line"><span style="color:#8DDB8C"> "secure"</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">true</span><span style="color:#ADBAC7">,</span></span>
|
|
274
|
-
<span class="line"><span style="color:#8DDB8C"> "httpOnly"</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">true</span></span>
|
|
275
|
-
<span class="line"><span style="color:#ADBAC7"> },</span></span>
|
|
276
|
-
<span class="line"><span style="color:#ADBAC7"> { </span><span style="color:#8DDB8C">"name"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"_account"</span><span style="color:#ADBAC7">, </span><span style="color:#8DDB8C">"value"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"personal"</span><span style="color:#ADBAC7">, </span><span style="color:#8DDB8C">"domain"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"chatgpt.com"</span><span style="color:#ADBAC7">, </span><span style="color:#8DDB8C">"path"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"/"</span><span style="color:#ADBAC7">, </span><span style="color:#8DDB8C">"secure"</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">true</span><span style="color:#ADBAC7"> }</span></span>
|
|
277
|
-
<span class="line"><span style="color:#ADBAC7">]</span></span></code></pre>
|
|
278
|
-
<p>You can pass the same payload inline (<code>--browser-inline-cookies '<json or base64>'</code>) or via env (<code>ORACLE_BROWSER_COOKIES_JSON</code>, <code>ORACLE_BROWSER_COOKIES_FILE</code>). Cloudflare cookies (<code>cf_clearance</code>, <code>__cf_bm</code>, etc.) are only needed when you hit a challenge.</p>
|
|
279
|
-
<p>When no model is supplied on the command line or in configuration, Oracle keeps its existing browser default. If the visible ChatGPT selection is a newer model, Oracle prints a model-selection warning before switching and submitting the prompt. Pass <code>--model</code> to choose explicitly, or <code>--browser-model-strategy current</code> to retain ChatGPT's selection. Explicit models, saved model preferences, and <code>current</code>/<code>ignore</code> strategies do not produce this warning.</p>
|
|
280
|
-
<h2 id="quick-example-attach-to-your-running-chrome"><a class="anchor" href="#quick-example-attach-to-your-running-chrome" aria-label="Anchor link">#</a>Quick example: attach to your running Chrome</h2>
|
|
281
|
-
<p>Use this when you already have a signed-in Chrome session running with DevTools access enabled and want Oracle to reuse that browser instead of launching its own copy.</p>
|
|
282
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#F69D50">oracle</span><span style="color:#6CB6FF"> --engine</span><span style="color:#96D0FF"> browser</span><span style="color:#F47067"> \</span></span>
|
|
283
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-attach-running</span><span style="color:#F47067"> \</span></span>
|
|
284
|
-
<span class="line"><span style="color:#6CB6FF"> --model</span><span style="color:#96D0FF"> gpt-5.5</span><span style="color:#F47067"> \</span></span>
|
|
285
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-thinking-time</span><span style="color:#96D0FF"> pro</span><span style="color:#F47067"> \</span></span>
|
|
286
|
-
<span class="line"><span style="color:#6CB6FF"> -p</span><span style="color:#96D0FF"> "Summarize the last assistant response in one paragraph"</span></span></code></pre>
|
|
287
|
-
<p>Notes:</p>
|
|
288
|
-
<ul>
|
|
289
|
-
<li><code>--browser-attach-running</code> defaults to local attach discovery at <code>127.0.0.1:9222</code>.</li>
|
|
290
|
-
<li>If the browser UI shows a different local endpoint, you can point Oracle at it explicitly:</li>
|
|
291
|
-
<p>``<code>bash oracle --engine browser \ --browser-attach-running \ --remote-chrome 127.0.0.1:63332 \ --model gpt-5.5 \ --browser-thinking-time pro \ -p "Summarize the last assistant response in one paragraph" </code>``</p>
|
|
292
|
-
<li>Oracle first reads local <code>DevToolsActivePort</code> metadata. If no matching metadata exists, it probes the selected local endpoint's <code>/json/version</code> (including IPv6) for the browser websocket. Each of two attempts has a one-second deadline covering headers and the complete response body, with a 500 ms pause before retrying. It then reuses the normal CDP automation flow without taking ownership of the browser profile.</li>
|
|
293
|
-
<li>Chrome 144+ can show an <strong>Allow remote debugging?</strong> prompt for each browser WebSocket. Oracle shares one connection to the same browser endpoint for its process lifetime, including target discovery, page sessions, and successive <code>oracle serve</code> requests. Completing or cancelling a request detaches its page session while retaining the connection. An actual browser disconnect permits a new connection. Separate CLI processes still need separate approval; use one long-running <code>oracle serve</code> host to share approval across client commands. Keep <strong>at least one Chrome window open</strong> so Chrome can display the approval sheet.</li>
|
|
294
|
-
<li>Oracle waits 20 seconds per approval by default. Use <code>--browser-approval-wait 5m</code> to allow five minutes, <code>ORACLE_BROWSER_APPROVAL_WAIT=5m</code>, or <code>browser.approvalWaitMs: 300000</code> in configuration. Durations accept milliseconds or <code>ms</code>/<code>s</code>/<code>m</code>/<code>h</code> units; they must be positive. CLI flags override the environment, which overrides saved CLI configuration. Session reattach uses the saved wait (or the environment/default for older sessions). The service host controls its own approval wait. Oracle logs when each connection starts waiting and every 15 seconds until it connects or fails; click Allow for each prompt. It keeps a pending connection open rather than issuing parallel approval requests.</li>
|
|
295
|
-
<li>Attach mode always opens a fresh Oracle-owned tab and closes only that tab after a successful run.</li>
|
|
296
|
-
<li>Cookie sync, Chrome launch flags, and profile lifecycle flags are skipped because the browser is already running.</li>
|
|
297
|
-
<li>If Chrome is not exposing a classic <code>/json/version</code> endpoint, use <code>--browser-attach-running</code> instead of standalone <code>--remote-chrome</code>.</li>
|
|
298
|
-
</ul>
|
|
299
|
-
<h2 id="current-pipeline"><a class="anchor" href="#current-pipeline" aria-label="Anchor link">#</a>Current Pipeline</h2>
|
|
300
|
-
<ol>
|
|
301
|
-
<li><strong>Prompt assembly</strong> – we reuse the normal prompt builder (<code>buildPrompt</code>) and the markdown renderer. Browser mode pastes the system + user text (no special markers) into the ChatGPT composer and, by default, pastes resolved file contents inline until the total pasted content reaches ~60k characters (then switches to uploads).</li>
|
|
302
|
-
<li><strong>Automation stack</strong> – code lives under <code>src/browser/</code>:</li>
|
|
303
|
-
</ol>
|
|
304
|
-
<ul>
|
|
305
|
-
<li>Launcher mode starts Chrome via <code>chrome-launcher</code> and connects with <code>chrome-remote-interface</code>.</li>
|
|
306
|
-
<li>Attach-running mode reads local <code>DevToolsActivePort</code> metadata for the selected local port, or probes <code>/json/version</code> if metadata is absent, connects to the browser websocket, opens a dedicated tab, and reuses the same DOM automation/capture flow against that attached browser.</li>
|
|
307
|
-
<li>Launcher mode can optionally copy cookies from the requested browser profile via Oracle’s built-in cookie reader (Keychain/DPAPI aware), but this requires <code>--browser-cookie-sync</code> or <code>browser.cookieSync=true</code>.</li>
|
|
308
|
-
<li>Navigates to <code>chatgpt.com</code>, switches the model to the requested GPT-5.5 / GPT-5.4 / GPT-5.2 variant (including <code>Advanced</code> → <code>Model</code> in the unified picker), optionally activates Deep Research, pastes the prompt, waits for completion, and copies the markdown via the built-in “copy turn” button.</li>
|
|
309
|
-
<li>Immediately probes the cookie-authenticated <code>/api/auth/session</code> endpoint in the ChatGPT tab and checks only whether it contains a user; returned tokens are never logged. If that endpoint is unavailable, Oracle falls back to the legacy <code>/backend-api/me</code> probe and a visible composer plus profile or chat-history authentication signals. Auth pages, visible login controls, resolved sessions without a user, composer-only shells, and pages without profile/history signals still fail with login guidance.</li>
|
|
310
|
-
<li>When <code>--file</code> inputs would push the pasted composer content over ~60k characters, we switch to uploads and wait for ChatGPT to re-enable the send button before submitting the combined system+user prompt. A single text/source file is uploaded directly; multiple text/source files are packed into one bundle. Text-only <code>auto</code> bundles stay flattened text; ZIP is used when raw files are present or <code>--browser-bundle-format zip</code> is set.</li>
|
|
311
|
-
<li>Launcher mode cleans up the temporary profile unless <code>--browser-keep-browser</code> is passed.</li>
|
|
312
|
-
</ul>
|
|
313
|
-
<ol>
|
|
314
|
-
<li><strong>Session integration</strong> – browser sessions use the normal log writer, add <code>mode: "browser"</code> plus <code>browser.config/runtime</code> metadata, and persist Chrome pid/port or websocket attach metadata plus the Oracle-owned target/tab URL for reattach.</li>
|
|
315
|
-
<li><strong>Usage accounting</strong> – we estimate input tokens with the same tokenizer used for API runs and estimate output tokens via <code>estimateTokenCount</code>. <code>oracle status</code> therefore shows comparable cost/timing info even though the call ran through the browser.</li>
|
|
316
|
-
</ol>
|
|
317
|
-
<h3 id="cli-options"><a class="anchor" href="#cli-options" aria-label="Anchor link">#</a>CLI Options</h3>
|
|
318
|
-
<ul>
|
|
319
|
-
<li><code>--engine browser</code>: enables browser mode (legacy <code>--browser</code> remains as an alias for now). Without <code>--engine</code>, Oracle chooses API when <code>OPENAI_API_KEY</code> exists, otherwise browser.</li>
|
|
320
|
-
<li><code>--browser-chrome-profile</code>: selects the cookie source profile when copying is explicitly enabled. <code>--browser-chrome-path</code> overrides the launched Chrome/Chromium binary.</li>
|
|
321
|
-
<li><code>--browser-cookie-path</code>: explicit path to the Chrome/Chromium/Edge <code>Cookies</code> SQLite DB. Handy when you launch a fork via <code>--browser-chrome-path</code> and want to copy its session cookies; see <a href="chromium-forks.html">docs/chromium-forks.md</a> for examples.</li>
|
|
322
|
-
<li><code>--browser-approval-wait <duration></code>: time to allow each Chrome remote-debugging connection (default <code>20s</code>); also <code>browser.approvalWaitMs</code> or <code>ORACLE_BROWSER_APPROVAL_WAIT</code>.</li>
|
|
323
|
-
<li><code>--browser-attach-running</code>: attach to a local already-running browser instead of launching Chrome directly. Defaults to <code>127.0.0.1:9222</code>; combine with <code>--remote-chrome <host:port></code> to use a different local attach hint.</li>
|
|
324
|
-
<li><code>--chatgpt-url</code>: override the ChatGPT base URL. Works with the root homepage (<code>https://chatgpt.com/</code>), Temporary Chat (<code>https://chatgpt.com/?temporary-chat=true</code>), <strong>or</strong> a specific workspace/folder link such as <code>https://chatgpt.com/g/.../project</code>. <code>--browser-url</code> stays as a hidden alias.</li>
|
|
325
|
-
<li><code>--browser-timeout</code>, <code>--browser-input-timeout</code>, <code>--browser-attachment-timeout</code>: <code>1200s (20m)</code>/<code>60s</code>/<code>45s</code> defaults. The input timeout bounds local prompt/file preparation and browser-input readiness; it does not shorten attachment uploads or assistant-response waits. The attachment timeout controls upload/readiness before clicking Send and can also be set with <code>ORACLE_BROWSER_ATTACHMENT_TIMEOUT</code> or <code>browser.attachmentTimeoutMs</code>. Durations accept <code>ms</code>, <code>s</code>, <code>m</code>, or <code>h</code> and can be chained (<code>1h2m10s</code>).</li>
|
|
326
|
-
<li><code>--browser-recheck-delay</code>, <code>--browser-recheck-timeout</code>: after an assistant timeout, wait the delay, revisit the conversation, and retry capture (default recheck timeout 120s). Useful for Pro runs that finish later.</li>
|
|
327
|
-
<li><code>--browser-reuse-wait</code>: wait for a shared Chrome profile (DevToolsActivePort) to appear before launching a new Chrome. Helps multiple parallel runs reuse the same Chromium instance.</li>
|
|
328
|
-
<li><code>--browser-profile-lock-timeout</code>: wait for the shared manual-login profile lock before sending, serializing parallel runs that share a Chrome profile.</li>
|
|
329
|
-
<li><code>--browser-max-concurrent-tabs</code>: soft limit for simultaneous ChatGPT tabs sharing one manual-login profile (default <code>3</code>). Set <code>ORACLE_BROWSER_MAX_CONCURRENT_TABS</code> for a per-host default; explicit CLI/config values win. Additional runs wait up to the browser timeout for a slot and log <code>[browser] Waiting for ChatGPT browser slot...</code>.</li>
|
|
330
|
-
<li><code>--browser-auto-reattach-delay</code>, <code>--browser-auto-reattach-interval</code>, <code>--browser-auto-reattach-timeout</code>: after a timeout, start periodic auto-reattach attempts (delay before first attempt, repeat interval, per-attempt timeout). This lets Oracle keep polling a finished Pro response without manual <code>oracle session</code> runs.</li>
|
|
331
|
-
<li><code>--heartbeat</code>: browser mode uses this interval to emit long-run ChatGPT status. When ChatGPT exposes a Thinking/Reasoning disclosure, Oracle opens it and logs only liveness metadata such as sidecar presence, UI progress percentage, elapsed time, and last-change age. It does not log the reasoning text.</li>
|
|
332
|
-
<li>If an assistant response still times out (common with long Pro runs), Oracle marks the session as an incomplete capture, stores reattach/runtime diagnostics, and keeps enough browser metadata for <code>oracle session <id></code> to recover the final answer. Visible ChatGPT rate-limit, temporary-unavailable, and authentication/challenge warnings are included in the error and session metadata instead of being reduced to a generic timeout. Increase <code>--browser-timeout</code> only when the browser session is truly unrecoverable.</li>
|
|
333
|
-
<li>When the new assistant turn reports a known English generation failure with a visible Retry control and generation has stopped, Oracle reports <code>chatgpt-ui-warning</code> immediately. Unrecognized or localized failure states retain the configured timeout. Oracle never clicks Retry or resubmits. Headful runs retain the browser for manual recovery; copied-profile runs still clean up because they cannot be reattached.</li>
|
|
334
|
-
<li>Successful reattach or harvest saves the full recovered answer and completed session before retiring an explicitly recorded Oracle-created tab. Existing tabs selected with <code>--browser-tab</code>, explicit <code>--browser-keep-browser</code> tabs, older sessions without ownership evidence, fallback targets, and tabs still used by another controller remain open. Recovery failures preserve the tab; there is no automatic retention deadline for unharvested runs.</li>
|
|
335
|
-
<li>If a controller dies while reserving a tab for retirement, the reservation remains in place to prevent another run from racing a pending close. The saved answer remains available; choose a new tab instead of reusing the reserved target.</li>
|
|
336
|
-
<li><code>--browser-model-strategy <select|current|ignore></code>: control ChatGPT model selection. <code>select</code> (default) switches to the requested model; <code>current</code> keeps the active model and logs its label; <code>ignore</code> skips the picker entirely. (Ignored for Gemini web runs.)</li>
|
|
337
|
-
<li>Temporary Chat can reduce account-sidebar clutter for one-shot browser consults, but it is a different ChatGPT workflow: Oracle skips archive attempts there and the local transcript/artifacts are the durable record. Verify live behavior before relying on Project Sources, Deep Research reports, or multi-turn persistence.</li>
|
|
338
|
-
<li><code>--browser-thinking-time <light|standard|extended|extra-high|pro|heavy></code>: set the ChatGPT thinking-time intensity (Thinking/Pro models only). On GPT-5.6 Sol, <code>extra-high</code> selects Extra High; a <code>heavy</code> request accepts an already-selected Pro pill but otherwise selects only a matching Heavy row. The generic current-Pro aliases (<code>gpt-5-pro</code>, <code>gpt-5.1-pro</code>, <code>gpt-5.2-pro</code>, and <code>gpt-5.4-pro</code>) follow ChatGPT's current Pro target and select GPT-5.6 Sol with Pro effort automatically. Use the explicit <code>--model gpt-5.5-pro</code> to pin the historical GPT-5.5 target, or pass another thinking-time value to override the alias default. The direct slider waits for its keyboard control to mount and become visible before sending a tier-changing keystroke. It supports both the five-tier layout and the quota-limited four-tier layout, whose maximum remains Extra High; requesting Pro on the four-tier layout reports it unavailable before sending input or submitting. Because Pro is expensive and rate-limited, <code>pro</code> fails closed: an unconfirmed selection aborts the run rather than quietly submitting at a cheaper tier. Effort rows are matched in English, German (<code>Sofort</code>/<code>Mittel</code>/<code>Hoch</code>/<code>Sehr hoch</code>), Japanese, Chinese, and Korean (<code>즉시</code>/<code>중간</code>/<code>높음</code>/<code>매우 높음</code>); when the requested tier has no row in the current UI language, Oracle keeps the effort already selected in the tab instead of switching the model. In ChatGPT's unified Intelligence picker Oracle opens <code>Advanced</code> → <code>Model</code> first, verifies the requested version, then opens <code>Advanced</code> → <code>Effort</code>; if either opener label is not recognized it declines to guess which control to use. You can also set a default in <code>~/.oracle/config.json</code> via <code>browser.thinkingTime</code>.</li>
|
|
339
|
-
<li>When a thinking tier is requested, <code>browser.thinkingSelection</code> records the requested level, observed selected label, verification status, strict-failure policy, and capture time. <code>oracle status <id></code> displays this separately from model-selection evidence, and remote runs retain it in the structured result. An unverified result does not claim a selected tier; strict Pro requests still stop before submission when selection cannot be confirmed. This is UI evidence at <code>capturedAt</code>, not proof of backend effort or of later UI state.</li>
|
|
340
|
-
<li>GPT-5.5 Pro Extended is verified from the selected item in ChatGPT's standalone Pro/Thinking effort pill or compatible Intelligence/model-picker menu. A run <strong>fails closed</strong> if Extended cannot be confirmed rather than silently submitting at a weaker effort. Detection failures write a bounded, redacted model-picker diagnostic to the normal session log.</li>
|
|
341
|
-
<li>In the direct-slider picker without an Advanced → Effort submenu, Oracle adjusts the five-tier slider with arrow keys and verifies its associated tier announcement and numeric value together. A rightmost thumb without a confirmed <code>Pro</code> label never satisfies a Pro request; unknown ranges or inconsistent feedback fail verification.</li>
|
|
342
|
-
<li><code>--browser-research search</code>: explicitly select Web Search for a normal ChatGPT answer. The pilot supports English ChatGPT with local Chrome, attach-running, or direct remote Chrome; <code>--remote-host</code> is not supported yet.</li>
|
|
343
|
-
<li><code>--browser-research deep</code>: activate ChatGPT Deep Research before submitting the prompt. Use this for broad public-web research and final cited reports, not as a replacement for GPT-5.x Pro Heavy code review or pure reasoning.</li>
|
|
344
|
-
<li><code>--browser-follow-up <prompt></code>: submit another prompt in the same ChatGPT conversation after the initial answer. Repeat the flag for multi-turn reviews such as “challenge your recommendation”, “compare against this constraint”, then “give the final decision”. Deep Research has its own report lifecycle, so browser follow-ups are rejected when <code>--browser-research deep</code> is enabled.</li>
|
|
345
|
-
<li><code>--followup <session-id></code>: reopen the exact saved ChatGPT conversation from a completed browser session. Oracle inherits the parent browser profile, configuration, and model, then verifies the thread and prior turns before submitting.</li>
|
|
346
|
-
<li><code>--browser-archive <auto|always|never></code>: archive completed ChatGPT conversations after local artifacts are saved. The default <code>auto</code> archives only successful one-shot chats and skips project, Deep Research, multi-turn, failed, and incomplete sessions.</li>
|
|
347
|
-
<li><code>--browser-port <port></code> (alias: <code>--browser-debug-port</code>; env: <code>ORACLE_BROWSER_PORT</code>/<code>ORACLE_BROWSER_DEBUG_PORT</code>): pin the DevTools port (handy on WSL/Windows firewalls). When omitted, a random open port is chosen.</li>
|
|
348
|
-
<li><code>ORACLE_CHATGPT_ACCOUNT_EMAIL</code>: exact saved-account email to select if ChatGPT shows its “Welcome back” account picker. Set it on the machine running browser automation. Oracle never logs the address; without it, Oracle selects only a single unambiguous saved account and fails closed when several are present.</li>
|
|
349
|
-
<li><code>--browser-cookie-sync</code> explicitly copies cookies from live Chrome into the temporary automation profile. Prefer <code>--browser-manual-login</code> (persistent automation profile + user-driven login), inline cookies, or attach-running mode; copied ChatGPT session tokens may rotate in the automation browser and invalidate the live Chrome session. <code>--browser-no-cookie-sync</code> remains as a compatibility override for configurations that enabled copying.</li>
|
|
350
|
-
<li><code>--browser-headless</code>, <code>--browser-hide-window</code>, <code>--browser-keep-browser</code>, and the global <code>-v/--verbose</code> flag control the launcher and diagnostics. On macOS, Oracle records a locally launched window before positioning it off-screen, then restores that recorded placement on a later visible run. Windows without Oracle's saved marker—including valid negative-coordinate placements on another display—remain untouched; attach-running and remote Chrome windows are never repositioned by this policy.</li>
|
|
351
|
-
<li>Verbose browser diagnostics replace inline cookie payloads with a cookie count, including the saved session log.</li>
|
|
352
|
-
<li><code>--copy-profile <dir></code>: copy a signed-in Chrome user-data directory (e.g. <code>"$HOME/Library/Application Support/Google/Chrome"</code>) to a throwaway profile and run against it, reusing your live ChatGPT session with no manual sign-in. Oracle copies the profile recorded as active in <code>Local State</code>; pass <code>--browser-chrome-profile <name></code> to select another direct child profile. The copy is launched with the real Keychain (not mocked) so its encrypted cookies decrypt, and is always deleted afterward—including setup/launch failures, incomplete captures, Cloudflare challenges, and interrupts. Copied-profile runs cannot be kept or reattached. Not compatible with <code>--browser-keep-browser</code>, <code>--browser-manual-login</code>, <code>--browser-attach-running</code>, <code>--remote-chrome</code>, or <code>--remote-host</code>, and fails fast if the required <code>Local State</code> cannot be copied. macOS/Linux; requires <code>rsync</code>.</li>
|
|
353
|
-
<li><code>--browser-url</code>: override ChatGPT base URL if needed.</li>
|
|
354
|
-
<li><code>--browser-attachments <auto|never|always></code>: control how <code>--file</code> inputs are delivered in browser mode. Default <code>auto</code> pastes text contents inline up to ~60k characters and uploads larger or raw files. <code>never</code> requires inline-compatible text inputs and rejects raw/binary files.</li>
|
|
355
|
-
<li>Attachment name checks accept ChatGPT's collision suffixes (for example, <code>01.jpg</code> → <code>01(5).jpg</code> or <code>document.md</code> → <code>document(20260818-145702).md</code>) in chip text and accessible labels. Unicode letters, numbers, and combining marks remain part of the filename: <code>가01(5).jpg</code> cannot satisfy a request for <code>01.jpg</code>, and a visible different extension cannot satisfy a name match.</li>
|
|
356
|
-
<li>Filename-less attachment previews are accepted only when that file's assignment creates a distinct removal control in the active composer. Oracle retains that per-file evidence through local/remote upload, completion, and send readiness; removing or replacing the control invalidates it. A generic file count or an old attachment is not proof of a new upload.</li>
|
|
357
|
-
<li>Attachment context checks recognize Work conversation IDs (<code>WEB:</code>), selected controls with a <code>work</code> machine value, and known Work labels on composer controls/placeholders. Unknown localized labels alone are not classified as modes; unrelated selected controls do not block valid chats. Fresh signed-in DOM variants need live validation. Plus activation revalidates the original exact button, focus, and page identity at key/click delivery. Attachment prompt staging also binds browser editing commands and fallback writes to the original renderer/editor, with guarded input events, with no retry after ambiguous transport acknowledgement.</li>
|
|
358
|
-
<li>Before sending an attachment prompt, Oracle rechecks the pre-upload Chat/Work and page identity, closes the exact plus menu if needed, focuses the exact enabled send button, and activates only that button with one trusted keyboard action. If the exact button is unavailable, or delayed navigation enters Work, another conversation, or a different non-conversation landing/project path, the attachment flow fails closed instead of using broad selectors or coordinates. Query, hash, and trailing-slash rewrites are ignored, and a project-scoped rewrite remains allowed when it preserves the conversation id. Plain-text sends retain the stable-coordinate path: Oracle activates the target, scrolls only when the button is offscreen, then remeasures before its one click. Once either action is dispatched, Oracle waits for the original turn to commit and never retries with another send or an upload fallback merely because the prompt remains staged. An ambiguous commit timeout preserves diagnostics for inspection; do not blindly rerun it. Truncation detected before dispatch can still use the normal upload fallback.</li>
|
|
359
|
-
<li><code>--browser-inline-files</code>: alias for <code>--browser-attachments never</code> (forces inline paste; never uploads attachments).</li>
|
|
360
|
-
<li><code>--browser-bundle-files</code>: force one browser upload bundle, including when <code>auto</code> would otherwise paste small files inline. With <code>auto</code> or <code>zip</code>, it contains all resolved attachments. Explicit <code>text</code> can flatten only text/source files, leaving native attachments separate. Without this flag, Oracle already bundles multiple text/source uploads while leaving images, PDFs, archives, and other native attachments separate when the 10-attachment limit permits. Generated <code>oracle-browser-bundle-*</code> directories are deleted after the run or dry-run.</li>
|
|
361
|
-
<li><code>--browser-bundle-format <auto|text|zip></code>: choose the bundle format. <code>auto</code> keeps the established flattened-text bundle for text-only uploads and uses a byte-preserving ZIP when raw/native files are present; <code>text</code> always flattens; <code>zip</code> always archives. ZIP inputs are capped at 128 MiB because bundle creation is in-memory. Oracle adds a short composer instruction telling ChatGPT to extract ZIP bundles into its sandbox before inspection.</li>
|
|
362
|
-
<li>sqlite bindings: automatic rebuilds now require <code>ORACLE_ALLOW_SQLITE_REBUILD=1</code>. Without it, the CLI logs instructions instead of running <code>pnpm rebuild</code> on your behalf.</li>
|
|
363
|
-
<li><code>--model gpt-6-pro</code> (or <code>gpt-6</code>, <code>gpt-6-astra</code>, <code>latest</code>): GPT-6 Astra. ChatGPT shows it as the <strong>Latest</strong> model of the advanced picker rather than as a named entry; <code>gpt-6-pro</code> also selects the Pro power tier by default (composer pill "6 Pro"), and Oracle only reports it as selected when that radio is checked or the pill reads "6 …" (never "5.6 …"). An explicit CLI <code>--model gpt-6-pro</code> keeps its Pro effort even when saved browser settings specify another tier; an explicit <code>--browser-thinking-time</code> still wins, and config-only model/effort preferences remain unchanged.</li>
|
|
364
|
-
<li><code>--model</code>: the same GPT-5.6 aliases work in API and browser mode. Use <code>gpt-5.6</code> for the current GPT-5.6 default or <code>gpt-5.6-sol</code> to pin Sol; browser mode maps either alias to the <code>GPT-5.6 Sol</code> picker entry, while API mode sends the corresponding first-party OpenAI model ID. GPT-5.2 base, Instant, and Thinking aliases remain available through the API but browser mode rejects them because ChatGPT retired those picker entries. Legacy Pro aliases (<code>gpt-5-pro</code>, etc.) still resolve to the GPT-5.6 Sol target.</li>
|
|
365
|
-
<li>Live Chrome cookie copying is disabled by default. The recommended migration is <code>--browser-manual-login</code>, which keeps token rotation inside a dedicated persistent automation profile. To retain the old launcher behavior, pass <code>--browser-cookie-sync</code> or set <code>browser.cookieSync=true</code> in the user config; Oracle warns about the live-session invalidation risk. When enabled, cookie copy is mandatory—if Oracle cannot copy cookies, the run exits early. Oracle copies a small ChatGPT auth/Cloudflare allowlist to avoid oversized request headers; use <code>--browser-cookie-names</code> only when you need to override that set.</li>
|
|
366
|
-
<li>Attach-running mode is mutually exclusive with launcher-owned flags such as <code>--browser-manual-login</code>, <code>--browser-chrome-profile</code>, <code>--browser-cookie-path</code>, <code>--browser-hide-window</code>, <code>--browser-keep-browser</code>, and <code>--browser-port</code>. <code>--remote-chrome</code> is allowed in attach-running mode, but only as the local host:port hint used for metadata discovery and the endpoint fallback. <code>--browser-chrome-path</code> is accepted but ignored.</li>
|
|
367
|
-
<li>Cookie controls:</li>
|
|
368
|
-
<li><code>--browser-cookie-sync</code> or user config <code>browser.cookieSync=true</code>: opt in to copying cookies from a live Chrome profile. Project config cannot enable this machine-local authentication behavior.</li>
|
|
369
|
-
<li><code>--browser-cookie-names <comma-list></code> or <code>ORACLE_BROWSER_COOKIE_NAMES</code>: override the default allowlist of cookies to sync. Useful when ChatGPT changes auth cookie names.</li>
|
|
370
|
-
<li><code>--browser-cookie-wait <ms|s|m></code>: if cookie sync fails or returns no cookies, wait once and retry (helps when macOS Keychain prompts are slow).</li>
|
|
371
|
-
<li><code>--browser-inline-cookies <jsonOrBase64></code> or <code>ORACLE_BROWSER_COOKIES_JSON</code>: skip Chrome/keychain and set cookies directly. Payload is a JSON array of DevTools <code>CookieParam</code> objects (or the same, base64-encoded). At minimum you need <code>name</code>, <code>value</code>, and either <code>url</code> or <code>domain</code>; we infer <code>path=/</code>, <code>secure=true</code>, <code>httpOnly=false</code>.</li>
|
|
372
|
-
<li><code>--browser-inline-cookies-file <path></code> or <code>ORACLE_BROWSER_COOKIES_FILE</code>: load the same payload from disk (JSON or base64 JSON). If no args/env are provided, Oracle also auto-loads <code>~/.oracle/cookies.json</code> or <code>~/.oracle/cookies.base64</code> when present.</li>
|
|
373
|
-
<li>Practical minimal set that keeps ChatGPT logged in and avoids the workspace picker: <code>__Secure-next-auth.session-token</code> (include <code>.0</code>/<code>.1</code> variants) and <code>_account</code> (active workspace/account). Cloudflare proofs (<code>cf_clearance</code>, <code>__cf_bm</code>/<code>_cfuvid</code>/<code>CF_Authorization</code>/<code>__cflb</code>) are only needed when a challenge is active. In practice our allowlist pulls just two cookies (session token + <code>_account</code>) and works; add the Cloudflare names if you hit a challenge.</li>
|
|
374
|
-
<li>Inline payload shape example (we ignore extra fields like <code>expirationDate</code>, <code>sameSite</code>, <code>hostOnly</code>):</li>
|
|
375
|
-
<p>``<code>json [ { "name": "__Secure-next-auth.session-token", "value": "<token>", "domain": "chatgpt.com", "path": "/", "secure": true, "httpOnly": true, "expires": 1771295753 }, { "name": "_account", "value": "personal", "domain": "chatgpt.com", "path": "/", "secure": true, "httpOnly": false, "expires": 1770702447 } ] </code>``</p>
|
|
376
|
-
</ul>
|
|
377
|
-
<p>All options are persisted with the session so restarts (<code>oracle restart <id></code>) reuse the same automation settings.</p>
|
|
378
|
-
<p>For the direct five-tier effort slider, Oracle verifies the leading effort label and the numeric slider position independently. Localized punctuation and ordinal wording, including Japanese <code>Pro、5件中5件目。</code>, do not affect selection. The label must end or be followed by whitespace or punctuation; word continuations such as <code>Professional</code> or <code>Proé</code>, missing labels, and contradictory positions cannot verify Pro.</p>
|
|
379
|
-
<h3 id="web-search"><a class="anchor" href="#web-search" aria-label="Anchor link">#</a>Web Search</h3>
|
|
380
|
-
<p>Use <code>oracle --engine browser --browser-research search -p "Find the current Node.js LTS releases and cite official sources"</code> to explicitly select ChatGPT's Web Search tool. Oracle verifies the selected search hint and the complete staged prompt before sending. Missing or changed controls stop the run before submission. Answers and citations use the normal browser transcript and output paths; search activation is UI evidence, not independent attestation of a provider's internal tool execution. The API <code>--search on/off</code> setting retains its existing meaning.</p>
|
|
381
|
-
<h3 id="deep-research-mode"><a class="anchor" href="#deep-research-mode" aria-label="Anchor link">#</a>Deep Research mode</h3>
|
|
382
|
-
<p>Use <code>--browser-research deep</code> when the task needs broad web discovery, source comparison, or a cited report:</p>
|
|
383
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#F69D50">oracle</span><span style="color:#6CB6FF"> --engine</span><span style="color:#96D0FF"> browser</span><span style="color:#F47067"> \</span></span>
|
|
384
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-manual-login</span><span style="color:#F47067"> \</span></span>
|
|
385
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-research</span><span style="color:#96D0FF"> deep</span><span style="color:#F47067"> \</span></span>
|
|
386
|
-
<span class="line"><span style="color:#6CB6FF"> -p</span><span style="color:#96D0FF"> "Research the current browser support for WebGPU in enterprise-managed Chrome and cite sources."</span></span></code></pre>
|
|
387
|
-
<p>Oracle activates ChatGPT Deep Research through the composer tools menu, recognizing the English <code>Deep research</code> / <code>Get a detailed report</code> labels and the Chinese <code>深度研究</code> / <code>获取详细报告</code> variants. It waits for the research plan to auto-confirm, logs high-level progress, then captures the final report from the Deep Research report surface instead of trusting the assistant tool-call wrapper.</p>
|
|
388
|
-
<p>When the research frame exposes a plan, Oracle logs its visible title and steps and saves its latest planning/researching phase and Edit/Update action under <code>browser.runtime.researchPlan</code> in the session metadata. It begins monitoring as soon as the frame reports researching, without waiting out a fixed plan countdown. This optional observation does not change terminal session status or retry a submitted prompt.</p>
|
|
389
|
-
<p>Remote-service results carry the optional plan with the completed answer. Plan log lines are available while the remote run is in progress; no new MCP wait event or terminal-status policy is introduced.</p>
|
|
390
|
-
<p>If ChatGPT initially exposes only <code>Called tool</code> / <code>Used tool</code>, Oracle treats that as an incomplete capture for Deep Research rather than a final answer. Reattach the existing session with <code>oracle session <id> --render</code> so Oracle can recover the lazy-loaded report from the existing Chrome tab; do not rerun the research unless the browser session is unrecoverable.</p>
|
|
391
|
-
<p>Deep Research is browser-only. It does not use connected apps in v1; give it public-web scope, uploaded files, and any domain/source guidance in the prompt. For deep thinking over code or architecture without web search, prefer a normal browser run with GPT-5.6 Sol and <code>--browser-thinking-time extra-high</code>, or a Pro model with <code>--browser-thinking-time extended</code>.</p>
|
|
392
|
-
<p>Completed browser sessions also save durable artifacts under <code>~/.oracle/sessions/<id>/artifacts/</code>. Deep Research writes the extracted report to <code>deep-research-report.md</code>, and every browser run writes <code>transcript.md</code> with the prompt, final answer, conversation URL, and saved artifact references. Use <code>--write-output <path></code> when you also need a copy of just the final answer at a specific path.</p>
|
|
393
|
-
<p>For a new browser run, add <code>--write-artifacts</code> with <code>--write-output <path></code> to copy captured files beside the written answer. This is opt-in; plain <code>--write-output</code> still writes only the answer. Canonical session files stay intact, binary copies are checked against their recorded size and SHA-256, and existing files are preserved using numbered names such as <code>report-2.csv</code>. Copy failures are logged and saved in session warnings while the answer remains successful. Files that could not be captured or transferred from a remote host cannot be exported; the existing manual-copy guidance still applies.</p>
|
|
394
|
-
<p>When ChatGPT generates downloadable files in the assistant response (for example a ZIP, wheel, source distribution, CSV, or PDF), Oracle saves those files beside the transcript before any archive attempt. The downloader is intentionally narrow: it only follows ChatGPT-owned file/download URLs from the assistant response and uses <code>sandbox:/mnt/data/...</code> links as source metadata and filename hints, not as arbitrary fetch targets. External links in the response are left in the transcript but are not downloaded. In bridge mode, a patched Windows host advertises artifact-transfer capability through <code>/health</code>; the Linux client then pulls each saved file over the authenticated bridge endpoint, stores it under the Linux session <code>artifacts/</code> directory, and verifies safe filename, byte size, SHA-256, and ZIP structure where applicable. If either side is older or transfer validation fails, the text response still completes and Oracle prints a manual-copy fallback instead of leaking host paths or signed download URLs.</p>
|
|
395
|
-
<h3 id="conversation-archiving"><a class="anchor" href="#conversation-archiving" aria-label="Anchor link">#</a>Conversation archiving</h3>
|
|
396
|
-
<p>Browser mode keeps the local session as the source of truth, so Oracle can optionally archive the ChatGPT conversation after a successful run. The default <code>--browser-archive auto</code> archives only successful non-project, non-Deep-Research, non-multi-turn one-shot chats after <code>transcript.md</code>, generated artifacts, the final answer, and the conversation URL are saved locally.</p>
|
|
397
|
-
<p>Oracle does not auto-archive failed, incomplete, running, project, Deep Research, or multi-turn sessions. Use <code>--browser-archive never</code> to disable archiving, or <code>--browser-archive always</code> when you explicitly want a successful browser conversation archived even outside the default one-shot policy. Archived chats are still visible and manageable from ChatGPT's own archive UI.</p>
|
|
398
|
-
<h3 id="chatgpt-project-sources"><a class="anchor" href="#chatgpt-project-sources" aria-label="Anchor link">#</a>ChatGPT Project Sources</h3>
|
|
399
|
-
<p>ChatGPT Project Sources can act as explicit shared context for project workflows where chats should not implicitly share memory. This is especially useful with Developer Mode / Memory Off: separate chats do not see each other's conversation history, but they can read files attached to the Project Sources tab.</p>
|
|
400
|
-
<p>Oracle exposes a narrow, non-destructive v1:</p>
|
|
401
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#768390"># Preview the upload plan without touching ChatGPT</span></span>
|
|
402
|
-
<span class="line"><span style="color:#F69D50">oracle</span><span style="color:#96D0FF"> project-sources</span><span style="color:#96D0FF"> add</span><span style="color:#F47067"> \</span></span>
|
|
403
|
-
<span class="line"><span style="color:#6CB6FF"> --chatgpt-url</span><span style="color:#96D0FF"> "https://chatgpt.com/g/g-p-example/project"</span><span style="color:#F47067"> \</span></span>
|
|
404
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-manual-login</span><span style="color:#F47067"> \</span></span>
|
|
405
|
-
<span class="line"><span style="color:#6CB6FF"> --file</span><span style="color:#96D0FF"> docs/architecture.md</span><span style="color:#F47067"> \</span></span>
|
|
406
|
-
<span class="line"><span style="color:#6CB6FF"> --dry-run</span></span>
|
|
407
|
-
<span class="line"></span>
|
|
408
|
-
<span class="line"><span style="color:#768390"># List current sources</span></span>
|
|
409
|
-
<span class="line"><span style="color:#F69D50">oracle</span><span style="color:#96D0FF"> project-sources</span><span style="color:#96D0FF"> list</span><span style="color:#F47067"> \</span></span>
|
|
410
|
-
<span class="line"><span style="color:#6CB6FF"> --chatgpt-url</span><span style="color:#96D0FF"> "https://chatgpt.com/g/g-p-example/project"</span><span style="color:#F47067"> \</span></span>
|
|
411
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-manual-login</span></span>
|
|
412
|
-
<span class="line"></span>
|
|
413
|
-
<span class="line"><span style="color:#768390"># Append files to the Sources tab</span></span>
|
|
414
|
-
<span class="line"><span style="color:#F69D50">oracle</span><span style="color:#96D0FF"> project-sources</span><span style="color:#96D0FF"> add</span><span style="color:#F47067"> \</span></span>
|
|
415
|
-
<span class="line"><span style="color:#6CB6FF"> --chatgpt-url</span><span style="color:#96D0FF"> "https://chatgpt.com/g/g-p-example/project"</span><span style="color:#F47067"> \</span></span>
|
|
416
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-manual-login</span><span style="color:#F47067"> \</span></span>
|
|
417
|
-
<span class="line"><span style="color:#6CB6FF"> --file</span><span style="color:#96D0FF"> docs/architecture.md</span><span style="color:#96D0FF"> docs/decisions.md</span></span></code></pre>
|
|
418
|
-
<p>This command uses browser automation but does not select a model, start a consult, or send a prompt. It only opens the Project Sources surface, lists existing files, or appends new files. Destructive operations such as delete, replace, and sync are intentionally left out until the UI path is safer and better covered by live tests.</p>
|
|
419
|
-
<h3 id="multi-turn-browser-consults"><a class="anchor" href="#multi-turn-browser-consults" aria-label="Anchor link">#</a>Multi-turn browser consults</h3>
|
|
420
|
-
<p>Use browser follow-ups when a one-shot review would be too easy for the model to answer shallowly. Oracle keeps the same ChatGPT conversation open, waits for each answer, then submits the next follow-up:</p>
|
|
421
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#F69D50">oracle</span><span style="color:#6CB6FF"> --engine</span><span style="color:#96D0FF"> browser</span><span style="color:#F47067"> \</span></span>
|
|
422
|
-
<span class="line"><span style="color:#6CB6FF"> --model</span><span style="color:#96D0FF"> gpt-5.5-pro</span><span style="color:#F47067"> \</span></span>
|
|
423
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-thinking-time</span><span style="color:#96D0FF"> extended</span><span style="color:#F47067"> \</span></span>
|
|
424
|
-
<span class="line"><span style="color:#6CB6FF"> -p</span><span style="color:#96D0FF"> "Review this migration plan and identify the top risks."</span><span style="color:#F47067"> \</span></span>
|
|
425
|
-
<span class="line"><span style="color:#6CB6FF"> --file</span><span style="color:#96D0FF"> docs/migration-plan.md</span><span style="color:#F47067"> \</span></span>
|
|
426
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-follow-up</span><span style="color:#96D0FF"> "Challenge your previous recommendation. What would fail in production?"</span><span style="color:#F47067"> \</span></span>
|
|
427
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-follow-up</span><span style="color:#96D0FF"> "Now give the final decision with the smallest safe next step."</span></span></code></pre>
|
|
428
|
-
<p>The CLI output and saved <code>transcript.md</code> include each captured turn. For PR validation, compare a one-shot run with the same initial prompt against a two-turn run that asks the model to challenge itself; record concrete differences such as additional failure modes, test cases, or rollback steps rather than claiming a fixed quality percentage.</p>
|
|
429
|
-
<p>Guardrails for agents:</p>
|
|
430
|
-
<ul>
|
|
431
|
-
<li>Use one-shot browser runs for narrow bugs, exact file sets, quick code review, or when the expected answer is a short decision.</li>
|
|
432
|
-
<li>Use explicit follow-ups for ambiguous architecture, competing options, product tradeoffs, or review flows where a challenge pass and final recommendation are useful.</li>
|
|
433
|
-
<li>Use Deep Research for broad public-web research that needs citations; Deep Research has its own lifecycle and is not combined with browser follow-ups.</li>
|
|
434
|
-
<li>Oracle never invents follow-ups automatically. Agents may suggest a short follow-up sequence, but the caller must pass each prompt explicitly with <code>--browser-follow-up</code> or <code>browserFollowUps</code>.</li>
|
|
435
|
-
</ul>
|
|
436
|
-
<h3 id="chatgpt-generated-images"><a class="anchor" href="#chatgpt-generated-images" aria-label="Anchor link">#</a>ChatGPT generated images</h3>
|
|
437
|
-
<p>When ChatGPT returns downloadable generated images in browser mode, Oracle downloads them using the active browser cookies and records them as session artifacts. To choose an output path, pass <code>--generate-image <file></code>:</p>
|
|
438
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#F69D50">oracle</span><span style="color:#6CB6FF"> --engine</span><span style="color:#96D0FF"> browser</span><span style="color:#F47067"> \</span></span>
|
|
439
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-manual-login</span><span style="color:#F47067"> \</span></span>
|
|
440
|
-
<span class="line"><span style="color:#6CB6FF"> --model</span><span style="color:#96D0FF"> "GPT-5.5 Pro"</span><span style="color:#F47067"> \</span></span>
|
|
441
|
-
<span class="line"><span style="color:#6CB6FF"> --generate-image</span><span style="color:#96D0FF"> /tmp/oracle-image.png</span><span style="color:#F47067"> \</span></span>
|
|
442
|
-
<span class="line"><span style="color:#6CB6FF"> -p</span><span style="color:#96D0FF"> "Create a simple product icon on a transparent background."</span></span></code></pre>
|
|
443
|
-
<p>If ChatGPT returns multiple images, the first image saves to the requested path and the rest save as numbered siblings. Without <code>--generate-image</code>, Oracle writes images to the session <code>artifacts/</code> directory.</p>
|
|
444
|
-
<p>MCP agents should prefer the <code>chatgpt_image</code> tool. It wraps the same behavior with a smaller input shape, uploads reference files by default, and returns saved files in <code>structuredContent.images</code>. Advanced callers can still pass <code>generateImage</code> to <code>consult</code> directly.</p>
|
|
445
|
-
<h3 id="manual-login-mode-persistent-profile-no-cookie-copy"><a class="anchor" href="#manual-login-mode-persistent-profile-no-cookie-copy" aria-label="Anchor link">#</a>Manual login mode (persistent profile, no cookie copy)</h3>
|
|
446
|
-
<p>Use <code>--browser-manual-login</code> when cookie decrypt is blocked (e.g., Windows app-bound cookies) or you prefer to sign in explicitly. You can also make it the default via <code>browser.manualLogin</code> in <code>~/.oracle/config.json</code>.</p>
|
|
447
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#F69D50">oracle</span><span style="color:#6CB6FF"> --engine</span><span style="color:#96D0FF"> browser</span><span style="color:#F47067"> \</span></span>
|
|
448
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-manual-login</span><span style="color:#F47067"> \</span></span>
|
|
449
|
-
<span class="line"><span style="color:#6CB6FF"> --browser-keep-browser</span><span style="color:#F47067"> \</span></span>
|
|
450
|
-
<span class="line"><span style="color:#6CB6FF"> --model</span><span style="color:#96D0FF"> "GPT-5.5 Pro"</span><span style="color:#F47067"> \</span></span>
|
|
451
|
-
<span class="line"><span style="color:#6CB6FF"> -p</span><span style="color:#96D0FF"> "Say hi"</span></span></code></pre>
|
|
452
|
-
<ul>
|
|
453
|
-
<li>Oracle launches Chrome headful with a persistent automation profile at <code>~/.oracle/browser-profile</code> (override with <code>ORACLE_BROWSER_PROFILE_DIR</code> or <code>browser.manualLoginProfileDir</code> in <code>~/.oracle/config.json</code>).</li>
|
|
454
|
-
<li>Log into chatgpt.com in that window the first time; Oracle polls until the session is active, then proceeds.</li>
|
|
455
|
-
<li>Reuse the same profile on subsequent runs (no re-login unless the session expires).</li>
|
|
456
|
-
<li>Add <code>--browser-keep-browser</code> (or config <code>browser.keepBrowser=true</code>) when doing the initial login/setup or debugging so the Chrome window stays open after the run. When omitted, Oracle closes Chrome but preserves the profile on disk.</li>
|
|
457
|
-
<li>Cookie copy is skipped by default in this mode. To seed the persistent profile from your existing Chrome cookies despite the token-rotation risk, set <code>browser.manualLoginCookieSync=true</code> in <code>~/.oracle/config.json</code>; explicit inline cookies can also seed it without reading live Chrome.</li>
|
|
458
|
-
<li>If Chrome is already running with that profile and DevTools remote debugging enabled (see <code>DevToolsActivePort</code> in the profile dir), you can reuse it instead of relaunching by pointing Oracle at it with <code>--remote-chrome <host:port></code>.</li>
|
|
459
|
-
<li>Remote Chrome runs also participate in tab-slot coordination when paired with <code>--browser-manual-login</code> and a shared manual-login profile.</li>
|
|
460
|
-
</ul>
|
|
461
|
-
<h3 id="concurrent-agents-and-long-pro-runs"><a class="anchor" href="#concurrent-agents-and-long-pro-runs" aria-label="Anchor link">#</a>Concurrent agents and long Pro runs</h3>
|
|
462
|
-
<p>When Codex, Claude Code, or another Oracle caller share the same manual-login profile, each browser run now acquires a tab slot before opening a ChatGPT tab. The default allows three simultaneous ChatGPT tabs; the fourth caller waits instead of failing because another agent is already using the browser. This is most useful for long Pro/Thinking runs where one agent may wait for a response while another agent needs to start a separate consult.</p>
|
|
463
|
-
<p>Use <code>--browser-max-concurrent-tabs <n></code>, <code>browser.maxConcurrentTabs</code>, or <code>ORACLE_BROWSER_MAX_CONCURRENT_TABS</code> to tune the soft limit. Precedence is explicit CLI/config value, then environment, then the default of <code>3</code>; invalid or non-positive environment values fall back instead of disabling the cap. Keep the value modest: too many concurrent ChatGPT tabs can make the UI unstable or trigger account-side throttling. Oracle also serializes manual-login Chrome startup for the shared profile, then reuses the first reachable DevTools session instead of racing multiple Chrome launches against the same <code>user-data-dir</code>. The short profile lock still serializes the send/upload moment so separate agents do not type into the same composer.</p>
|
|
464
|
-
<p>For live concurrency smoke, the most stable path is one already-running signed-in Chrome with remote debugging enabled, plus <code>--remote-chrome <host:port></code>. Direct parallel launch is supported defensively, but a persistent shared Chrome gives clearer ownership and avoids account/login churn across agents.</p>
|
|
465
|
-
<h2 id="remote-chrome-sessions-headless-server-workflows"><a class="anchor" href="#remote-chrome-sessions-headless-server-workflows" aria-label="Anchor link">#</a>Remote Chrome Sessions (headless/server workflows)</h2>
|
|
466
|
-
<p>Oracle can reuse an already-running Chrome/Edge instance on another machine by tunneling over the Chrome DevTools Protocol. This is handy when:</p>
|
|
467
|
-
<ul>
|
|
468
|
-
<li>Your CLI runs on a headless server (Linux/macOS CI, remote mac minis, etc.) but you want the browser UI to live on a desktop where you can see uploads or respond to Captcha challenges.</li>
|
|
469
|
-
<li>You want to keep a single signed-in profile open (e.g., Windows VM with company SSO) while sending prompts from other hosts.</li>
|
|
470
|
-
</ul>
|
|
471
|
-
<h3 id="1-start-chrome-with-remote-debugging-enabled"><a class="anchor" href="#1-start-chrome-with-remote-debugging-enabled" aria-label="Anchor link">#</a>1. Start Chrome with remote debugging enabled</h3>
|
|
472
|
-
<p>On the machine that should host the browser window:</p>
|
|
473
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#F69D50">google-chrome</span><span style="color:#F47067"> \</span></span>
|
|
474
|
-
<span class="line"><span style="color:#6CB6FF"> --remote-debugging-port=9222</span><span style="color:#F47067"> \</span></span>
|
|
475
|
-
<span class="line"><span style="color:#6CB6FF"> --remote-debugging-address=0.0.0.0</span><span style="color:#F47067"> \</span></span>
|
|
476
|
-
<span class="line"><span style="color:#6CB6FF"> --user-data-dir=/path/to/profile</span><span style="color:#F47067"> \</span></span>
|
|
477
|
-
<span class="line"><span style="color:#6CB6FF"> --profile-directory=</span><span style="color:#96D0FF">'Default'</span></span></code></pre>
|
|
478
|
-
<p>Notes:</p>
|
|
479
|
-
<ul>
|
|
480
|
-
<li>Any Chromium flavor works (Chrome, Edge, Vivaldi, etc.)—just ensure CDP is exposed on a reachable host:port. Linux distributions often call the binary <code>google-chrome-stable</code>. On macOS you can run <code>/Applications/Google Chrome.app/Contents/MacOS/Google Chrome</code>.</li>
|
|
481
|
-
<li><code>--remote-debugging-address=0.0.0.0</code> is required if the CLI connects from another machine. Lock it down behind a VPN or SSH tunnel if the network is untrusted.</li>
|
|
482
|
-
<li>Keep this browser window open and signed into ChatGPT; Oracle will reuse that session and <strong>will not</strong> copy cookies over the wire.</li>
|
|
483
|
-
</ul>
|
|
484
|
-
<h3 id="2-point-oracle-at-the-remote-browser"><a class="anchor" href="#2-point-oracle-at-the-remote-browser" aria-label="Anchor link">#</a>2. Point Oracle at the remote browser</h3>
|
|
485
|
-
<p>From the machine running <code>oracle</code>:</p>
|
|
486
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#F69D50">oracle</span><span style="color:#6CB6FF"> --engine</span><span style="color:#96D0FF"> browser</span><span style="color:#F47067"> \</span></span>
|
|
487
|
-
<span class="line"><span style="color:#6CB6FF"> --remote-chrome</span><span style="color:#96D0FF"> 192.168.1.10:9222</span><span style="color:#F47067"> \</span></span>
|
|
488
|
-
<span class="line"><span style="color:#6CB6FF"> --prompt</span><span style="color:#96D0FF"> "Summarize the latest incident doc"</span><span style="color:#F47067"> \</span></span>
|
|
489
|
-
<span class="line"><span style="color:#6CB6FF"> --file</span><span style="color:#96D0FF"> docs/incidents/latest.md</span></span></code></pre>
|
|
490
|
-
<p>Key behavior:</p>
|
|
491
|
-
<ul>
|
|
492
|
-
<li>Use IPv6 by wrapping the host in brackets, e.g. <code>--remote-chrome "[2001:db8::1]:9222"</code>.</li>
|
|
493
|
-
<li>Local-only flags like <code>--browser-headless</code>, <code>--browser-hide-window</code>, <code>--browser-keep-browser</code>, and <code>--browser-chrome-path</code> are ignored because Oracle no longer launches Chrome. You still get verbose logging, model switching, attachment uploads, and markdown capture.</li>
|
|
494
|
-
<li>Cookie sync is skipped automatically (the remote browser already has cookies). If you need inline cookies, use them on the machine that’s actually running Chrome.</li>
|
|
495
|
-
<li>Oracle opens a dedicated CDP target (new tab) for each run and closes it afterward so your existing tabs stay untouched.</li>
|
|
496
|
-
<li>When remote runs are served by an Oracle host with a manual-login profile, the host-side tab lease registry applies the same concurrent tab limit.</li>
|
|
497
|
-
<li>Attachments are transferred via CDP: Oracle reads each file locally, base64-encodes it, and uses <code>DataTransfer</code> inside the remote browser to populate the upload field. Files larger than 20 MB are rejected to keep CDP messages reasonable.</li>
|
|
498
|
-
<li>When the remote WebSocket disconnects, Oracle errors with “Remote Chrome connection lost…” so you can re-run after restarting the browser.</li>
|
|
499
|
-
</ul>
|
|
500
|
-
<h3 id="3-troubleshooting"><a class="anchor" href="#3-troubleshooting" aria-label="Anchor link">#</a>3. Troubleshooting</h3>
|
|
501
|
-
<ul>
|
|
502
|
-
<li>Run <code>scripts/test-remote-chrome.ts <host> [port]</code> to sanity-check connectivity (<code>npx tsx scripts/test-remote-chrome.ts my-host 9222</code>).</li>
|
|
503
|
-
<li>If you target IPv6 without brackets (e.g., <code>2001:db8::1:9222</code>), the CLI rejects it—wrap the address like <code>[2001:db8::1]:9222</code>.</li>
|
|
504
|
-
<li>Ensure firewalls allow inbound TCP to the debugging port and that you’re not behind a captive proxy stripping WebSocket upgrades.</li>
|
|
505
|
-
<li>Because we do not control the remote lifecycle, Chrome stays running after the session. Shut it down manually when you’re done or remove <code>--remote-debugging-port</code> to stop exposing CDP.</li>
|
|
506
|
-
</ul>
|
|
507
|
-
<h3 id="remote-service-mode-oracle-serve"><a class="anchor" href="#remote-service-mode-oracle-serve" aria-label="Anchor link">#</a>Remote Service Mode (<code>oracle serve</code>)</h3>
|
|
508
|
-
<p>To host requests through an already-running signed-in Chrome, start the service with:</p>
|
|
509
|
-
<pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-bash"><span class="line"><span style="color:#F69D50">oracle</span><span style="color:#96D0FF"> serve</span><span style="color:#6CB6FF"> --host</span><span style="color:#6CB6FF"> 127.0.0.1</span><span style="color:#6CB6FF"> --browser-attach-running</span><span style="color:#6CB6FF"> --remote-chrome</span><span style="color:#96D0FF"> 127.0.0.1:9222</span><span style="color:#6CB6FF"> --browser-approval-wait</span><span style="color:#96D0FF"> 5m</span></span></code></pre>
|
|
510
|
-
<p>These are <strong>host settings</strong>: <code>browser.attachRunning</code>, <code>browser.remoteChrome</code>, and <code>browser.approvalWaitMs</code> in the service host configuration also apply. Explicit flags override configuration; <code>ORACLE_BROWSER_APPROVAL_WAIT</code> overrides the configured wait unless the flag is supplied. Attach-running mode (or a standalone <code>--remote-chrome</code> endpoint for classic DevTools HTTP) skips cookie extraction and manual-login Chrome startup. Each run uses the selected browser; service shutdown leaves that browser running. With no attachment settings, the existing dedicated manual-login default remains. Clients cannot override the host endpoint, attach mode, or approval wait. Add <code>--max-concurrent-runs 2 --max-queued-runs 8</code> to opt into bounded admission.</p>
|
|
511
|
-
<p>Prefer to keep Chrome entirely on the remote Mac (no DevTools tunneling, no manual cookie shuffling)? Use the built-in service:</p>
|
|
512
|
-
<ol>
|
|
513
|
-
<li><strong>Start the host</strong></li>
|
|
514
|
-
</ol>
|
|
515
|
-
<p>``<code>bash oracle serve </code>``</p>
|
|
516
|
-
<p>Oracle picks a free port, launches Chrome, starts an HTTP/SSE API, and prints:</p>
|
|
517
|
-
<p>``<code> Listening at 0.0.0.0:9473 Access token: c4e5f9... </code>``</p>
|
|
518
|
-
<p>Use <code>--host</code>, <code>--port</code>, or <code>--token</code> to override the defaults if needed. On first use, sign in to ChatGPT in the dedicated automation Chrome window. The service keeps that profile for later runs.</p>
|
|
519
|
-
<ol>
|
|
520
|
-
<li><strong>Run from your laptop</strong></li>
|
|
521
|
-
</ol>
|
|
522
|
-
<p>``<code>bash oracle --engine browser \ --remote-host 192.168.64.2:9473 \ --remote-token c4e5f9... \ --prompt "Summarize the incident doc" \ --file docs/incidents/latest.md </code>``</p>
|
|
523
|
-
<ul>
|
|
524
|
-
<li><code>--remote-host</code> points the CLI at the VM.</li>
|
|
525
|
-
<li><code>--remote-token</code> matches the token printed by <code>oracle serve</code> (set <code>ORACLE_REMOTE_TOKEN</code> to avoid repeating it).</li>
|
|
526
|
-
<li>You can also set defaults in <code>~/.oracle/config.json</code> (<code>browser.remoteHost</code>, <code>browser.remoteToken</code>) so you don’t need the flags; env vars still override those when present.</li>
|
|
527
|
-
<li>Cookies are <strong>not</strong> transferred from your laptop. The service reuses the dedicated automation profile on the host.</li>
|
|
528
|
-
</ul>
|
|
529
|
-
<ol>
|
|
530
|
-
<li><strong>What happens</strong></li>
|
|
531
|
-
</ol>
|
|
532
|
-
<ul>
|
|
533
|
-
<li>The CLI assembles the composed prompt + file bundle locally, sends them to the VM, and streams log lines/answer text back through the same HTTP connection.</li>
|
|
534
|
-
<li>The remote host uses a dedicated persistent automation profile by default. Sign in once in the Chrome window it opens, then leave that profile isolated from your interactive Chrome session.</li>
|
|
535
|
-
<li><code>oracle serve --browser-cookie-sync</code> restores the old behavior of copying cookies from the host's live Chrome profile. This is an explicit fallback: ChatGPT token rotation in the service browser can invalidate the host's interactive session.</li>
|
|
536
|
-
<li>Background/detached sessions (<code>--no-wait</code>) are disabled in remote mode so the CLI can keep streaming output.</li>
|
|
537
|
-
<li><code>oracle serve</code> logs the DevTools port of the manual-login Chrome (e.g., <code>Manual-login Chrome DevTools port: 54371</code>). Runs automatically attach to that logged-in Chrome; you can use the printed port/JSON URL for debugging if needed.</li>
|
|
538
|
-
</ul>
|
|
539
|
-
<ol>
|
|
540
|
-
<li><strong>Stop the host</strong></li>
|
|
541
|
-
</ol>
|
|
542
|
-
<ul>
|
|
543
|
-
<li><code>Ctrl+C</code> on the VM shuts down the HTTP server. Shared manual-login Chrome can remain available for reuse. Restart <code>oracle serve</code> whenever you need a new session; omit <code>--token</code> to let it rotate automatically.</li>
|
|
544
|
-
</ul>
|
|
545
|
-
<p>This mode is ideal when you have a macOS VM (or spare Mac mini) logged into ChatGPT and you just want to run the CLI from another machine without ever copying profiles or keeping Chrome visible locally.</p>
|
|
546
|
-
<h4 id="optional-concurrent-admission"><a class="anchor" href="#optional-concurrent-admission" aria-label="Anchor link">#</a>Optional concurrent admission</h4>
|
|
547
|
-
<p>Plain <code>oracle serve</code> retains single-flight admission and HTTP 409 <code>busy</code>. To opt into FIFO queueing, use <code>oracle serve --max-concurrent-runs 2 --max-queued-runs 8</code>. The queue defaults to eight waiting requests; zero disables waiting. Active capacity is clamped to the host's browser tab limit, resolved from host configuration, then <code>ORACLE_BROWSER_MAX_CONCURRENT_TABS</code>, then the existing default of three. Client settings cannot raise that limit. <code>/health</code> reports the effective active/queued counts and limits. A full opt-in queue returns HTTP 503 <code>queue_full</code> with <code>Retry-After: 60</code>.</p>
|
|
548
|
-
<p>In queue mode, a disconnected caller gives up its waiting position or cancels its active automation. Owned targets are closed unless the caller explicitly requested they remain open; borrowed tabs and the shared Chrome process are preserved. Cancellation stops further automation and cleans up resources that arrive late, but does not undo an already submitted prompt or attest that ChatGPT stopped backend generation. Host artifact sessions receive a sanitized per-run namespace, so clients with the same slug do not share files.</p>
|
|
549
|
-
<p>Programmatic <code>BrowserRunOptions.signal</code> requests cancellation explicitly even on a host using legacy admission. The client checks the host's <code>runCancellation</code> capability before sending such a run; older hosts remain usable without an AbortSignal. Plain clients on a legacy host retain their existing disconnect behavior.</p>
|
|
550
|
-
<h2 id="limitations-follow-up-plan"><a class="anchor" href="#limitations-follow-up-plan" aria-label="Anchor link">#</a>Limitations / Follow-Up Plan</h2>
|
|
551
|
-
<ul>
|
|
552
|
-
<li><strong>Attachment lifecycle</strong> – in <code>auto</code> mode we prefer inlining small text inputs into the composer. When uploads are selected, one text/source file stays native and multiple text/source files become one bundle. Text-only <code>auto</code> bundles stay flattened text so existing workflows keep direct text ingestion; <code>--browser-bundle-format zip</code> (or mixed raw inputs) creates a ZIP plus an extract instruction. Images, PDFs, archives, and other native attachments stay separate unless <code>--browser-bundle-files</code> is set or the upload cap requires a single archive. <code>--browser-bundle-files</code> selects the upload plan even for small auto inputs. Fallback bundles are created only if ChatGPT rejects the inline paste on compatible remote hosts. Clients probe the host capability before deferring; older hosts receive a prebuilt fallback so their attachment limits remain intact. Generated bundle directories are removed after the run. The automation waits for uploads to finish (send button enabled, upload chips visible) before submitting.</li>
|
|
553
|
-
<li><strong>Model picker drift</strong> – we rely on heuristics to pick GPT-5.6 / GPT-5.5 / GPT-5.4 / GPT-5.2 variants. If OpenAI changes the DOM we need to refresh the selectors quickly. Consider snapshot tests or a small “self check” command.</li>
|
|
554
|
-
<li><strong>Non-mac platforms</strong> – window hiding uses AppleScript today; Linux/Windows just ignore the flag. We should detect platforms explicitly and document the behavior.</li>
|
|
555
|
-
<li><strong>Streaming UX</strong> – browser runs cannot stream tokens, so we emit heartbeat/status logs while waiting. Investigate whether we can stream clipboard deltas via mutation observers for a closer UX.</li>
|
|
556
|
-
</ul>
|
|
557
|
-
<h2 id="testing-notes"><a class="anchor" href="#testing-notes" aria-label="Anchor link">#</a>Testing Notes</h2>
|
|
558
|
-
<ul>
|
|
559
|
-
<li>ChatGPT automation smoke: <code>pnpm test:browser</code></li>
|
|
560
|
-
<li>Gemini web (cookie) smoke: <code>ORACLE_LIVE_TEST=1 pnpm vitest run tests/live/gemini-web-live.test.ts</code> (requires a signed-in Chrome profile at <code>gemini.google.com</code>)</li>
|
|
561
|
-
<li><code>pnpm test --filter browser</code> does not exist yet; manual runs with <code>--engine browser -v</code> are the current validation path.</li>
|
|
562
|
-
<li>Most of the heavy lifting lives in <code>src/browserMode.ts</code>. If you change selectors or the mutation observer logic, run a local <code>oracle --engine browser --browser-keep-browser</code> session so you can inspect DevTools before cleanup.</li>
|
|
563
|
-
</ul>
|
|
564
|
-
<h3 id="shared-profile-lifecycle"><a class="anchor" href="#shared-profile-lifecycle" aria-label="Anchor link">#</a>Shared-profile lifecycle</h3>
|
|
565
|
-
<p>Controllers keep independent leases while sharing a manual-login Chrome process. A completing controller releases only its own lease; the verified final owner performs process cleanup while holding the registry lock. Unknown ownership, malformed owner records, and transient liveness failures preserve the browser. Owner records are published atomically, so a crash during initialization leaves an ownerless lock that can be reclaimed after five minutes. If external corruption leaves a malformed <code>oracle-tab-leases.lock/owner.json</code>, stop every Oracle controller using that profile before removing that profile's <code>oracle-tab-leases.lock</code> directory; then restart the controllers. Do not remove the lock while any controller is active. Restart all browser controllers together after upgrading: older live controllers used a different lock-timeout recovery rule. Existing stored lease records remain readable. Native Windows shared-profile Chrome is detached from its launching controller; this does not change temporary or copied-profile launch policy.</p>
|
|
566
|
-
<h3 id="provider-native-conversation-evidence"><a class="anchor" href="#provider-native-conversation-evidence" aria-label="Anchor link">#</a>Provider-native conversation evidence</h3>
|
|
567
|
-
<p><code>--browser-capture-provider-native</code> additionally saves ChatGPT's full conversation JSON, verbatim, and an evidence JSON file in the session's <code>artifacts/</code> directory. It is off by default. Set <code>browser.captureProviderNative: true</code> in your user config to enable it; <code>--no-browser-capture-provider-native</code> overrides that preference. Project configs and remote bridge clients cannot enable this export. Direct remote-Chrome runs use the same capture path as local Chrome.</p>
|
|
568
|
-
<p>The raw record may include prior turns, alternate branches, attachments, and provider metadata, beyond the current answer. Files use owner-only permissions on POSIX and follow normal session retention/cleanup. <code>--write-artifacts</code> can export them with other session artifacts; copies have their own retention. Treat the full raw record as conversation data when sharing it.</p>
|
|
569
|
-
<p>Capture uses ChatGPT's undocumented conversation endpoint from the authenticated page and reuses Oracle's existing Chrome connection. Two independent fetches produce the raw record and in-page SHA-256 digests. The second body never crosses the browser boundary. Document hashes may differ because provider metadata changes; this alone is not an answer-fidelity failure.</p>
|
|
570
|
-
<p>The evidence format is <code>oracle.provider-native-capture-evidence/v1</code>, with <code>text-fields-v1</code> normalization: string-only text parts and thought contents join with two newlines; code/execution output use <code>text</code>; reasoning recaps use <code>content</code>. Mixed multimodal and unknown content have null digests, while their original bytes remain in the raw record. This format does not claim compatibility with external Python JSON normalization.</p>
|
|
571
|
-
<p><code>browser.providerNativeCapture</code> in session metadata records <code>matched</code>, <code>divergent</code>, or <code>unknown</code>. A match requires the captured assistant's message ID on the active provider branch and exact UTF-8 text, optionally trimming Oracle's surrounding whitespace. User turns, earlier answers, and alternate branches cannot substitute for that message. Deep Research reports without an assistant message ID, unsupported content, missing IDs, and failed evidence fetches report <code>unknown</code>.</p>
|
|
572
|
-
<p>The existing copy-button/DOM answer is still returned. Capture is optional evidence and never fails the answer: temporary chats, bot challenges, invalid responses, disconnects, and write failures record a typed reason. Fetching/draining has a 30-second total budget and an 8 MiB limit per document. Tokens stay in the page; logs and failure summaries contain fixed reasons rather than response bodies or exception details. The raw artifact is unchanged provider data, not a redacted transcript.</p><nav class="page-nav" aria-label="Pager"><a class="page-nav-prev" href="grok.html"><small>Previous</small><span>Grok 4.1 (xAI) Support</span></a><a class="page-nav-next" href="chromium-forks.html"><small>Next</small><span>Chromium-based browsers (Chromium, Edge, Brave variants)</span></a></nav></article>
|
|
573
|
-
<nav class="toc" aria-label="On this page"><h2>On this page</h2><a class="toc-l2" href="#quick-example-browser-mode-with-custom-cookies">Quick example: browser mode with custom cookies</a><a class="toc-l2" href="#quick-example-attach-to-your-running-chrome">Quick example: attach to your running Chrome</a><a class="toc-l2" href="#current-pipeline">Current Pipeline</a><a class="toc-l3" href="#cli-options">CLI Options</a><a class="toc-l3" href="#web-search">Web Search</a><a class="toc-l3" href="#deep-research-mode">Deep Research mode</a><a class="toc-l3" href="#conversation-archiving">Conversation archiving</a><a class="toc-l3" href="#chatgpt-project-sources">ChatGPT Project Sources</a><a class="toc-l3" href="#multi-turn-browser-consults">Multi-turn browser consults</a><a class="toc-l3" href="#chatgpt-generated-images">ChatGPT generated images</a><a class="toc-l3" href="#manual-login-mode-persistent-profile-no-cookie-copy">Manual login mode (persistent profile, no cookie copy)</a><a class="toc-l3" href="#concurrent-agents-and-long-pro-runs">Concurrent agents and long Pro runs</a><a class="toc-l2" href="#remote-chrome-sessions-headless-server-workflows">Remote Chrome Sessions (headless/server workflows)</a><a class="toc-l3" href="#1-start-chrome-with-remote-debugging-enabled">1. Start Chrome with remote debugging enabled</a><a class="toc-l3" href="#2-point-oracle-at-the-remote-browser">2. Point Oracle at the remote browser</a><a class="toc-l3" href="#3-troubleshooting">3. Troubleshooting</a><a class="toc-l3" href="#remote-service-mode-oracle-serve">Remote Service Mode (oracle serve)</a><a class="toc-l2" href="#limitations-follow-up-plan">Limitations / Follow-Up Plan</a><a class="toc-l2" href="#testing-notes">Testing Notes</a><a class="toc-l3" href="#shared-profile-lifecycle">Shared-profile lifecycle</a><a class="toc-l3" href="#provider-native-conversation-evidence">Provider-native conversation evidence</a></nav>
|
|
574
|
-
</div>
|
|
575
|
-
</main>
|
|
576
|
-
</div>
|
|
577
|
-
<script>
|
|
578
|
-
const themeRoot=document.documentElement;
|
|
579
|
-
function applyTheme(mode){themeRoot.dataset.theme=mode;document.querySelectorAll('[data-theme-toggle]').forEach(b=>b.setAttribute('aria-pressed',mode==='dark'?'true':'false'))}
|
|
580
|
-
function storedTheme(){try{return localStorage.getItem('theme')}catch(e){return null}}
|
|
581
|
-
function persistTheme(mode){try{localStorage.setItem('theme',mode)}catch(e){}}
|
|
582
|
-
applyTheme(themeRoot.dataset.theme==='dark'?'dark':'light');
|
|
583
|
-
document.querySelectorAll('[data-theme-toggle]').forEach(btn=>{btn.addEventListener('click',()=>{const next=themeRoot.dataset.theme==='dark'?'light':'dark';applyTheme(next);persistTheme(next)})});
|
|
584
|
-
const systemDark=window.matchMedia&&matchMedia('(prefers-color-scheme: dark)');
|
|
585
|
-
function onSystemChange(e){if(storedTheme())return;applyTheme(e.matches?'dark':'light')}
|
|
586
|
-
if(systemDark){if(systemDark.addEventListener)systemDark.addEventListener('change',onSystemChange);else if(systemDark.addListener)systemDark.addListener(onSystemChange)}
|
|
587
|
-
const sidebar=document.querySelector('.sidebar');
|
|
588
|
-
const toggle=document.querySelector('.nav-toggle');
|
|
589
|
-
const mobileNav=window.matchMedia('(max-width: 900px)');
|
|
590
|
-
const sidebarFocusable='a[href],button,input,select,textarea,[tabindex]';
|
|
591
|
-
function setSidebarFocusable(enabled){
|
|
592
|
-
sidebar?.querySelectorAll(sidebarFocusable).forEach((el)=>{
|
|
593
|
-
if(enabled){
|
|
594
|
-
if(el.dataset.sidebarTabindex!==undefined){
|
|
595
|
-
if(el.dataset.sidebarTabindex)el.setAttribute('tabindex',el.dataset.sidebarTabindex);
|
|
596
|
-
else el.removeAttribute('tabindex');
|
|
597
|
-
delete el.dataset.sidebarTabindex;
|
|
598
|
-
}
|
|
599
|
-
}else if(el.dataset.sidebarTabindex===undefined){
|
|
600
|
-
el.dataset.sidebarTabindex=el.getAttribute('tabindex')??'';
|
|
601
|
-
el.setAttribute('tabindex','-1');
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
function setSidebarOpen(open){
|
|
606
|
-
if(!sidebar||!toggle)return;
|
|
607
|
-
sidebar.classList.toggle('open',open);
|
|
608
|
-
toggle.setAttribute('aria-expanded',open?'true':'false');
|
|
609
|
-
if(mobileNav.matches){
|
|
610
|
-
sidebar.inert=!open;
|
|
611
|
-
if(open)sidebar.removeAttribute('aria-hidden');
|
|
612
|
-
else sidebar.setAttribute('aria-hidden','true');
|
|
613
|
-
setSidebarFocusable(open);
|
|
614
|
-
}else{
|
|
615
|
-
sidebar.inert=false;
|
|
616
|
-
sidebar.removeAttribute('aria-hidden');
|
|
617
|
-
setSidebarFocusable(true);
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
setSidebarOpen(false);
|
|
621
|
-
toggle?.addEventListener('click',()=>setSidebarOpen(!sidebar?.classList.contains('open')));
|
|
622
|
-
document.addEventListener('click',(e)=>{if(!sidebar?.classList.contains('open'))return;if(sidebar.contains(e.target)||toggle?.contains(e.target))return;setSidebarOpen(false)});
|
|
623
|
-
document.addEventListener('keydown',(e)=>{if(e.key==='Escape')setSidebarOpen(false)});
|
|
624
|
-
const syncSidebarForViewport=()=>setSidebarOpen(sidebar?.classList.contains('open')??false);
|
|
625
|
-
if(mobileNav.addEventListener)mobileNav.addEventListener('change',syncSidebarForViewport);
|
|
626
|
-
else mobileNav.addListener?.(syncSidebarForViewport);
|
|
627
|
-
const input=document.getElementById('doc-search');
|
|
628
|
-
input?.addEventListener('input',()=>{const q=input.value.trim().toLowerCase();document.querySelectorAll('nav section').forEach(sec=>{let any=false;sec.querySelectorAll('.nav-link').forEach(a=>{const m=!q||a.textContent.toLowerCase().includes(q);a.style.display=m?'block':'none';if(m)any=true});sec.style.display=any?'block':'none'})});
|
|
629
|
-
function attachCopy(target,getText){const btn=document.createElement('button');btn.type='button';btn.className='copy';btn.textContent='Copy';btn.addEventListener('click',async()=>{try{await navigator.clipboard.writeText(getText());btn.textContent='Copied';btn.classList.add('copied');setTimeout(()=>{btn.textContent='Copy';btn.classList.remove('copied')},1400)}catch{btn.textContent='Failed';setTimeout(()=>{btn.textContent='Copy'},1400)}});target.appendChild(btn)}
|
|
630
|
-
document.querySelectorAll('.doc pre').forEach(pre=>attachCopy(pre,()=>pre.querySelector('code')?.textContent??''));
|
|
631
|
-
document.querySelectorAll('.home-install').forEach(el=>attachCopy(el,()=>el.querySelector('code')?.textContent??''));
|
|
632
|
-
const tocLinks=document.querySelectorAll('.toc a');
|
|
633
|
-
if(tocLinks.length){const map=new Map();tocLinks.forEach(a=>{const id=a.getAttribute('href').slice(1);const el=document.getElementById(id);if(el)map.set(el,a)});const setActive=l=>{tocLinks.forEach(x=>x.classList.remove('active'));l.classList.add('active')};const obs=new IntersectionObserver(entries=>{const visible=entries.filter(e=>e.isIntersecting).sort((a,b)=>a.boundingClientRect.top-b.boundingClientRect.top);if(visible.length){const link=map.get(visible[0].target);if(link)setActive(link)}},{rootMargin:'-15% 0px -65% 0px',threshold:0});map.forEach((_,el)=>obs.observe(el))}
|
|
634
|
-
</script>
|
|
635
|
-
</body>
|
|
636
|
-
</html>
|