@steipete/oracle 0.21.1 → 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 +6 -10
- package/dist/src/browser/profileState.js +2 -0
- package/package.json +10 -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 -637
- 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 -388
- 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,621 +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>Manual Test Suite (Browser Mode + Live API) — oracle</title>
|
|
7
|
-
<meta name="description" content="Manual Test Suite (Browser Mode + Live API) — oracle CLI documentation.">
|
|
8
|
-
<link rel="canonical" href="https://askoracle.sh/manual-tests.html">
|
|
9
|
-
<meta property="og:type" content="website">
|
|
10
|
-
<meta property="og:site_name" content="oracle">
|
|
11
|
-
<meta property="og:title" content="Manual Test Suite (Browser Mode + Live API) — oracle">
|
|
12
|
-
<meta property="og:description" content="Manual Test Suite (Browser Mode + Live API) — oracle CLI documentation.">
|
|
13
|
-
<meta property="og:url" content="https://askoracle.sh/manual-tests.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="Manual Test Suite (Browser Mode + Live API) — oracle">
|
|
19
|
-
<meta name="twitter:description" content="Manual Test Suite (Browser Mode + Live API) — 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" 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 active" 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">Reference</p>
|
|
239
|
-
<h1>Manual Test Suite (Browser Mode + Live API)</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/manual-tests.md" rel="noopener">Edit page</a>
|
|
244
|
-
</div>
|
|
245
|
-
</header>
|
|
246
|
-
<div class="doc-grid">
|
|
247
|
-
<article class="doc"><h1 id="manual-test-suite-browser-mode-live-api">Manual Test Suite (Browser Mode + Live API)</h1>
|
|
248
|
-
<p>These checks validate the real Chrome automation path and the optional live Responses API smoke suite. Run the browser steps whenever you touch Chrome automation (lifecycle, cookie sync, prompt injection, Markdown capture, etc.), and run the live API suite before shipping major transport changes.</p>
|
|
249
|
-
<h2 id="prerequisites"><a class="anchor" href="#prerequisites" aria-label="Anchor link">#</a>Prerequisites</h2>
|
|
250
|
-
<ul>
|
|
251
|
-
<li>macOS with Chrome installed (default profile signed in to ChatGPT Pro).</li>
|
|
252
|
-
<li>Node 24+ and <code>pnpm install</code> already completed.</li>
|
|
253
|
-
<li>Headful display access (no <code>--browser-headless</code>).</li>
|
|
254
|
-
<li>When debugging, add <code>--browser-keep-browser</code> so Chrome stays open after Oracle exits, then connect with <code>pnpm exec tsx scripts/browser-tools.ts ...</code> (screenshot, eval, DOM picker, etc.).</li>
|
|
255
|
-
<li>Ensure no Chrome instances are force-terminated mid-run; let Oracle clean up once you’re done capturing state.</li>
|
|
256
|
-
<li>Clipboard checks (<code>browser-tools.ts eval "navigator.clipboard.readText()"</code>) trigger a permission dialog in Chrome—approve it for debugging, but remember that we can’t rely on readText in unattended runs.</li>
|
|
257
|
-
</ul>
|
|
258
|
-
<h2 id="test-cases"><a class="anchor" href="#test-cases" aria-label="Anchor link">#</a>Test Cases</h2>
|
|
259
|
-
<h3 id="recovered-tab-retirement"><a class="anchor" href="#recovered-tab-retirement" aria-label="Anchor link">#</a>Recovered tab retirement</h3>
|
|
260
|
-
<p>Run <code>pnpm build && node scripts/recovery-retirement-proof.mjs</code> for built-CLI harvests against isolated Chrome. The synthetic matrix checks full-answer persistence before owned-tab retirement and preservation of a peer, borrowed/kept targets, active controllers, and the current generation stop control.</p>
|
|
261
|
-
<p>For signed-in proof, run a Pro consultation with a short response timeout and automatic reattach disabled, then let the controller exit. Confirm the tab remains available, reattach after completion, and verify the complete answer is saved before only that owned target closes. Use <code>ORACLE_NO_DETACH=1</code> when exercising the foreground controller. Never click <strong>Answer now</strong>.</p>
|
|
262
|
-
<h3 id="attachment-evidence-and-single-send-regression-no-login"><a class="anchor" href="#attachment-evidence-and-single-send-regression-no-login" aria-label="Anchor link">#</a>Attachment evidence and single-send regression (no login)</h3>
|
|
263
|
-
<p>Run <code>pnpm build && node scripts/attachment-send-proof.mjs</code> with Chrome installed (<code>CHROME_PATH</code> can select Chromium on Linux). This uses a disposable profile and a controlled local page, not a signed-in consultation. It exercises local and remote three-file uploads, a filename-less JPEG with a consumed FileList, sidebar-count rejection, byte integrity, delayed commitment, exact-button keyboard activation for attachment sends, and offscreen button recovery. Each send must produce exactly one trusted button activation, zero editor-Enter submissions, and one committed turn. The Linux Chrome CI job runs it too.</p>
|
|
264
|
-
<p>The disposable profile and fixtures live in a temporary, non-hidden directory under your home directory and are removed afterward. This lets Snap Chromium read the same files as Node instead of looking in its private <code>/tmp</code>. An optional directory argument retains the fixtures for manual testing; that directory must also be readable by the selected browser.</p>
|
|
265
|
-
<p>The attachment proof also holds composer upload progress active for longer than three seconds inside a non-editable attachment widget nested in a rich-text editor, verifies completion and send both refuse it without input, then clears it and verifies one successful send despite unrelated page progress. Readiness uses explicit loading/busy state and native/ARIA progress controls; filenames and status prose alone cannot establish an active transfer.</p>
|
|
266
|
-
<h3 id="browser-artifact-export"><a class="anchor" href="#browser-artifact-export" aria-label="Anchor link">#</a>Browser artifact export</h3>
|
|
267
|
-
<p>For browser file export, run <code>pnpm build && node scripts/artifact-export-proof.mjs</code>. It uses the actual CLI and isolated Chrome with synthetic sandbox-download responses, checking answer-only defaults, opt-in binary exports, collision preservation, recorded hashes, and copy-failure warnings. This does not establish current signed-in ChatGPT download or authentication behavior.</p>
|
|
268
|
-
<h3 id="signed-in-attachment-work-mode-guard"><a class="anchor" href="#signed-in-attachment-work-mode-guard" aria-label="Anchor link">#</a>Signed-in attachment / Work-mode guard</h3>
|
|
269
|
-
<p>Before the signed-in smoke, run <code>pnpm build && node scripts/attachment-cli-proof.mjs</code> for the actual CLI against isolated local and remote Chrome fixtures. It checks per-file bytes, filename-less image evidence, upload progress, final focus/readiness, canonical conversation identity, Work refusal, missing exact send controls, and single submission. Optional <code>--baseline-cli <path></code> demonstrates the older CLI sending after a project-context switch. These synthetic pages do not establish current signed-in ChatGPT behavior.</p>
|
|
270
|
-
<p>Run this after changing attachment-menu activation or Chat/Work detection. Use a signed-in persistent profile, one small attachment, and <code>--browser-keep-browser</code>; do not use <strong>Answer now</strong> to complete the response.</p>
|
|
271
|
-
<ol>
|
|
272
|
-
<li>Record the newest sidebar Chat and Work entries, then start an attachment consultation from the Chat landing page.</li>
|
|
273
|
-
<li>Verify the prompt becomes a committed user turn in an ordinary <code>/c/<id></code> Chat conversation. A project rewrite such as <code>/c/<id></code> to <code>/g/<project>/.../c/<id></code> is allowed only when the conversation id is unchanged. A delayed Work/conversation navigation or switch between non-conversation landing/project paths injected after upload readiness but before final dispatch must fail without keyboard or mouse send events; query, hash, and trailing-slash-only rewrites remain allowed.</li>
|
|
274
|
-
<li>Verify no new Work task was created, the session records <code>promptSubmitted=true</code>, and the attachment appears in the committed user turn.</li>
|
|
275
|
-
<li>Repeat from an already selected Work composer. Oracle must fail before file assignment or prompt submission with an attachment Work-mode error.</li>
|
|
276
|
-
<li>For image generation, also require terminal completion and decode the downloaded image from the configured output path; <code>running</code>, a visible upload, or an enabled send button is not completion evidence.</li>
|
|
277
|
-
</ol>
|
|
278
|
-
<h3 id="quick-browser-port-smoke"><a class="anchor" href="#quick-browser-port-smoke" aria-label="Anchor link">#</a>Quick browser port smoke</h3>
|
|
279
|
-
<ul>
|
|
280
|
-
<li><code>pnpm test:browser</code> — launches headful Chrome and checks the DevTools endpoint is reachable. Set <code>ORACLE_BROWSER_PORT</code> (or <code>ORACLE_BROWSER_DEBUG_PORT</code>) to reuse a fixed port when you’ve already opened a firewall rule.</li>
|
|
281
|
-
</ul>
|
|
282
|
-
<h3 id="gemini-browser-mode-gemini-web-cookies"><a class="anchor" href="#gemini-browser-mode-gemini-web-cookies" aria-label="Anchor link">#</a>Gemini browser mode (Gemini web / cookies)</h3>
|
|
283
|
-
<p>Run this whenever you touch the Gemini web client or the <code>--generate-image</code> / <code>--edit-image</code> plumbing.</p>
|
|
284
|
-
<p>Prereqs:</p>
|
|
285
|
-
<ul>
|
|
286
|
-
<li>Chrome profile is signed into <code>gemini.google.com</code>.</li>
|
|
287
|
-
</ul>
|
|
288
|
-
<ol>
|
|
289
|
-
<li>Generate an image:</li>
|
|
290
|
-
<p><code>pnpm run oracle -- --engine browser --model gemini-3-pro --prompt "a cute robot holding a banana" --generate-image /tmp/gemini-gen.jpg --aspect 1:1 --wait --verbose</code></p>
|
|
291
|
-
</ol>
|
|
292
|
-
<ul>
|
|
293
|
-
<li>Confirm the output file exists and is a real image (<code>file /tmp/gemini-gen.jpg</code>).</li>
|
|
294
|
-
</ul>
|
|
295
|
-
<ol>
|
|
296
|
-
<li>Edit an image:</li>
|
|
297
|
-
<p><code>pnpm run oracle -- --engine browser --model gemini-3-pro --prompt "add sunglasses" --edit-image /tmp/gemini-gen.jpg --output /tmp/gemini-edit.jpg --wait --verbose</code></p>
|
|
298
|
-
</ol>
|
|
299
|
-
<ul>
|
|
300
|
-
<li>Confirm <code>/tmp/gemini-edit.jpg</code> exists.</li>
|
|
301
|
-
</ul>
|
|
302
|
-
<h3 id="multi-model-cli-fan-out"><a class="anchor" href="#multi-model-cli-fan-out" aria-label="Anchor link">#</a>Multi-Model CLI fan-out</h3>
|
|
303
|
-
<p>Run this whenever you touch the session store, CLI session views, or TUI wiring for multi-model runs.</p>
|
|
304
|
-
<ol>
|
|
305
|
-
<li>Kick off an API multi-run:</li>
|
|
306
|
-
<p><code>pnpm run oracle -- --models "gpt-5.1-pro,gemini-3-pro" --prompt "Compare the moon & sun."</code></p>
|
|
307
|
-
</ol>
|
|
308
|
-
<ul>
|
|
309
|
-
<li>Expect stdout to print sequential sections, one per model (<code>[gpt-5.1-pro] …</code> followed by <code>[gemini-3-pro] …</code>). No interleaved tokens.</li>
|
|
310
|
-
</ul>
|
|
311
|
-
<ol>
|
|
312
|
-
<li>Capture the session ID from the summary line. Run <code>oracle session --status --model gpt-5.1-pro</code>.</li>
|
|
313
|
-
</ol>
|
|
314
|
-
<ul>
|
|
315
|
-
<li>Table should collapse to sessions that include GPT-5.1 Pro and show status icons (✓/⌛/✖) per model.</li>
|
|
316
|
-
</ul>
|
|
317
|
-
<ol>
|
|
318
|
-
<li>Inspect detailed logs: <code>oracle session <id></code></li>
|
|
319
|
-
</ol>
|
|
320
|
-
<ul>
|
|
321
|
-
<li>The metadata header now includes a <code>Models:</code> block with one line per model plus token counts.</li>
|
|
322
|
-
<li>When prompted, pick <code>View gemini-3-pro log</code> and confirm only that model’s stream renders. Refresh should keep completed models intact even if others still run.</li>
|
|
323
|
-
</ul>
|
|
324
|
-
<ol>
|
|
325
|
-
<li>Model filter path: <code>oracle session <id> --model gemini-3-pro</code></li>
|
|
326
|
-
</ol>
|
|
327
|
-
<ul>
|
|
328
|
-
<li>Attach mode should error if that model is missing (double-check by filtering for a bogus model), otherwise it should render the prompt + single-model log only.</li>
|
|
329
|
-
</ul>
|
|
330
|
-
<h3 id="write-output-export-api"><a class="anchor" href="#write-output-export-api" aria-label="Anchor link">#</a>Write-output export (API)</h3>
|
|
331
|
-
<p>Run this when touching session serialization, file IO helpers, or CLI flag plumbing.</p>
|
|
332
|
-
<ol>
|
|
333
|
-
<li><code>ORACLE_LIVE_TEST=1 OPENAI_API_KEY=<real key> pnpm vitest run tests/live/write-output-live.test.ts --runInBand</code></li>
|
|
334
|
-
</ol>
|
|
335
|
-
<ul>
|
|
336
|
-
<li>Expect the test to create a temp <code>write-output-live.md</code> file containing <code>write-output e2e</code>.</li>
|
|
337
|
-
</ul>
|
|
338
|
-
<ol>
|
|
339
|
-
<li>Manual spot-check: <code>oracle --prompt "answer file smoke" --write-output /tmp/out.md --wait</code></li>
|
|
340
|
-
</ol>
|
|
341
|
-
<ul>
|
|
342
|
-
<li>Confirm <code>/tmp/out.md</code> exists with the answer text and a trailing newline.</li>
|
|
343
|
-
</ul>
|
|
344
|
-
<ol>
|
|
345
|
-
<li>Multi-model spot-check: <code>oracle --models "gpt-5.1-pro,gemini-3-pro" --prompt "two files" --write-output /tmp/out.md --wait</code></li>
|
|
346
|
-
</ol>
|
|
347
|
-
<ul>
|
|
348
|
-
<li>Confirm <code>/tmp/out.gpt-5.1-pro.md</code> and <code>/tmp/out.gemini-3-pro.md</code> exist with distinct content.</li>
|
|
349
|
-
</ul>
|
|
350
|
-
<h3 id="cli-guardrails-and-perf-traces"><a class="anchor" href="#cli-guardrails-and-perf-traces" aria-label="Anchor link">#</a>CLI guardrails and perf traces</h3>
|
|
351
|
-
<p>Run this when touching top-level CLI startup, option parsing, signal handling, or trace output.</p>
|
|
352
|
-
<ol>
|
|
353
|
-
<li>Missing prompt:</li>
|
|
354
|
-
<p><code>pnpm run oracle -- --engine api</code></p>
|
|
355
|
-
</ol>
|
|
356
|
-
<ul>
|
|
357
|
-
<li>Expect help plus a nonzero exit code.</li>
|
|
358
|
-
</ul>
|
|
359
|
-
<ol>
|
|
360
|
-
<li>Preview conflict:</li>
|
|
361
|
-
<p><code>pnpm run oracle -- --dry-run summary --render --prompt "conflict"</code></p>
|
|
362
|
-
</ol>
|
|
363
|
-
<ul>
|
|
364
|
-
<li>Expect a clear conflict error and nonzero exit.</li>
|
|
365
|
-
</ul>
|
|
366
|
-
<ol>
|
|
367
|
-
<li>Perf trace:</li>
|
|
368
|
-
<p><code>pnpm run oracle -- --perf-trace --perf-trace-path /tmp/oracle-perf.json --dry-run summary --prompt "trace smoke"</code></p>
|
|
369
|
-
</ol>
|
|
370
|
-
<ul>
|
|
371
|
-
<li>Confirm the JSON contains <code>cli-module-ready</code>, <code>root-command-start</code>, <code>first-output</code>, and <code>exit</code>, and prompt/key-like argv values are redacted.</li>
|
|
372
|
-
</ul>
|
|
373
|
-
<h3 id="thinking-effort-evidence"><a class="anchor" href="#thinking-effort-evidence" aria-label="Anchor link">#</a>Thinking effort evidence</h3>
|
|
374
|
-
<p><code>node scripts/effort-readiness-proof.mjs</code> also checks persisted and displayed effort evidence for switched, already-selected, unverified best-effort, and refused strict selections. Its bridge case runs both built CLI processes against isolated Chrome and verifies structured effort evidence survives without host PID/profile fields. The page is synthetic; fresh signed-in selection and backend effort remain separate checks.</p>
|
|
375
|
-
<h3 id="lightweight-browser-cli-manual-exploration"><a class="anchor" href="#lightweight-browser-cli-manual-exploration" aria-label="Anchor link">#</a>Lightweight Browser CLI (manual exploration)</h3>
|
|
376
|
-
<p>Before running any agent-driven debugging, you can rely on the TypeScript CLI in <code>scripts/browser-tools.ts</code>:</p>
|
|
377
|
-
<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"># Show help / available commands</span></span>
|
|
378
|
-
<span class="line"><span style="color:#F69D50">pnpm</span><span style="color:#96D0FF"> tsx</span><span style="color:#96D0FF"> scripts/browser-tools.ts</span><span style="color:#6CB6FF"> --help</span></span>
|
|
379
|
-
<span class="line"></span>
|
|
380
|
-
<span class="line"><span style="color:#768390"># Launch Chrome with your normal profile so you stay logged in</span></span>
|
|
381
|
-
<span class="line"><span style="color:#F69D50">pnpm</span><span style="color:#96D0FF"> tsx</span><span style="color:#96D0FF"> scripts/browser-tools.ts</span><span style="color:#96D0FF"> start</span><span style="color:#6CB6FF"> --profile</span></span>
|
|
382
|
-
<span class="line"></span>
|
|
383
|
-
<span class="line"><span style="color:#768390"># Drive the active tab</span></span>
|
|
384
|
-
<span class="line"><span style="color:#F69D50">pnpm</span><span style="color:#96D0FF"> tsx</span><span style="color:#96D0FF"> scripts/browser-tools.ts</span><span style="color:#96D0FF"> nav</span><span style="color:#96D0FF"> https://example.com</span></span>
|
|
385
|
-
<span class="line"><span style="color:#F69D50">pnpm</span><span style="color:#96D0FF"> tsx</span><span style="color:#96D0FF"> scripts/browser-tools.ts</span><span style="color:#96D0FF"> eval</span><span style="color:#96D0FF"> 'document.title'</span></span>
|
|
386
|
-
<span class="line"><span style="color:#F69D50">pnpm</span><span style="color:#96D0FF"> tsx</span><span style="color:#96D0FF"> scripts/browser-tools.ts</span><span style="color:#96D0FF"> screenshot</span></span>
|
|
387
|
-
<span class="line"><span style="color:#F69D50">pnpm</span><span style="color:#96D0FF"> tsx</span><span style="color:#96D0FF"> scripts/browser-tools.ts</span><span style="color:#96D0FF"> pick</span><span style="color:#96D0FF"> "Select checkout button"</span></span>
|
|
388
|
-
<span class="line"><span style="color:#F69D50">pnpm</span><span style="color:#96D0FF"> tsx</span><span style="color:#96D0FF"> scripts/browser-tools.ts</span><span style="color:#96D0FF"> cookies</span></span>
|
|
389
|
-
<span class="line"><span style="color:#F69D50">pnpm</span><span style="color:#96D0FF"> tsx</span><span style="color:#96D0FF"> scripts/browser-tools.ts</span><span style="color:#96D0FF"> inspect</span><span style="color:#768390"> # show DevTools-enabled Chrome PIDs/ports/tabs</span></span>
|
|
390
|
-
<span class="line"><span style="color:#F69D50">pnpm</span><span style="color:#96D0FF"> tsx</span><span style="color:#96D0FF"> scripts/browser-tools.ts</span><span style="color:#96D0FF"> kill</span><span style="color:#6CB6FF"> --all</span><span style="color:#6CB6FF"> --force</span><span style="color:#768390"> # tear down straggler DevTools sessions</span></span></code></pre>
|
|
391
|
-
<p>This mirrors Mario Zechner’s “What if you don’t need MCP?” technique and is handy when you just need a few quick interactions without spinning up additional tooling.</p>
|
|
392
|
-
<p>Debug note: when you have a live ChatGPT tab open under a DevTools port and need a quick DOM dump of the last assistant turn, run <code>pnpm tsx scripts/debug/extract-chatgpt-response.ts <port></code>.</p>
|
|
393
|
-
<ol>
|
|
394
|
-
<li><strong>Prompt Submission & Model Switching</strong></li>
|
|
395
|
-
</ol>
|
|
396
|
-
<ul>
|
|
397
|
-
<li>With Chrome signed in and cookie sync enabled, run</li>
|
|
398
|
-
<p>``<code>bash pnpm run oracle -- --engine browser --browser-cookie-sync --model gpt-5.5 \ --prompt "Line 1\nLine 2\nLine 3" </code>``</p>
|
|
399
|
-
<li>Observe logs for:</li>
|
|
400
|
-
<li><code>Prompt textarea ready (xxx chars queued)</code> (twice: initial + after model switch).</li>
|
|
401
|
-
<li><code>Model picker: ... Thinking ...</code> or the current GPT-5.5 picker label.</li>
|
|
402
|
-
<li><code>Clicked send button</code> (or Enter fallback).</li>
|
|
403
|
-
<li>In the attached Chrome window, verify the multi-line prompt appears exactly as sent.</li>
|
|
404
|
-
</ul>
|
|
405
|
-
<ol>
|
|
406
|
-
<li><strong>Markdown Capture</strong></li>
|
|
407
|
-
</ol>
|
|
408
|
-
<ul>
|
|
409
|
-
<li>Prompt:</li>
|
|
410
|
-
<p>``<code>bash pnpm run oracle -- --engine browser --browser-cookie-sync --model gpt-5.5 \ --prompt "Produce a short bullet list with code fencing." </code>``</p>
|
|
411
|
-
<li>Expected CLI output:</li>
|
|
412
|
-
<li><code>Answer:</code> section containing bullet list with Markdown preserved (e.g., <code>- item</code>, fenced code).</li>
|
|
413
|
-
<li>Session log (<code>oracle session <id></code>) should show the assistant markdown (confirm via <code>grep -n '</code>`<code>' ~/.oracle/sessions/<id>/output.log</code>).</li>
|
|
414
|
-
</ul>
|
|
415
|
-
<ol>
|
|
416
|
-
<li><strong>Stop Button Handling</strong></li>
|
|
417
|
-
</ol>
|
|
418
|
-
<ul>
|
|
419
|
-
<li>Start a long prompt (<code>"Write a detailed essay about browsers"</code>) and once ChatGPT responds, manually click “Stop generating” inside Chrome.</li>
|
|
420
|
-
<li>Oracle should detect the assistant message (partial) and still store the markdown.</li>
|
|
421
|
-
</ul>
|
|
422
|
-
<ol>
|
|
423
|
-
<li><strong>Override Flag</strong></li>
|
|
424
|
-
</ol>
|
|
425
|
-
<ul>
|
|
426
|
-
<li>Run with <code>--browser-allow-cookie-errors</code> while intentionally breaking bindings.</li>
|
|
427
|
-
<li>Confirm log shows <code>Cookie sync failed (continuing with override)</code> and the run proceeds headless/logged-out.</li>
|
|
428
|
-
<li>Remember: the browser composer now pastes only the user prompt (plus any inline file blocks). If you see the default “You are Oracle…” text or other system-prefixed content in the ChatGPT composer, something regressed in <code>assembleBrowserPrompt</code> and you should stop and file a bug.</li>
|
|
429
|
-
<li>Heartbeats: Browser runs emit <code>--heartbeat</code> status while waiting. Long Thinking/Pro runs should show <code>[browser] ChatGPT thinking ...</code> or <code>[browser] Waiting for ChatGPT response ...</code>; the log must not include reasoning text from the side panel.</li>
|
|
430
|
-
</ul>
|
|
431
|
-
<h3 id="service-admission-and-cancellation"><a class="anchor" href="#service-admission-and-cancellation" aria-label="Anchor link">#</a>Service admission and cancellation</h3>
|
|
432
|
-
<p>For service admission and cancellation, run <code>pnpm build && node scripts/serve-queue-proof.mjs</code>. It drives the built service and CLI clients against real isolated Chrome with synthetic pages: default 409, host-cap clamping, FIFO waiting, 503 overflow, queued/active cancellation, and distinct host sessions. Additional compiled integration runs cover lease/profile-lock waits, borrowed targets, delayed CDP replies, Chrome acquisition, and temporary-launch cleanup. <code>--baseline-cli <path></code> uses an older client for one queued completion. This does not prove signed-in ChatGPT behavior or backend generation cancellation.</p>
|
|
433
|
-
<h2 id="post-run-validation"><a class="anchor" href="#post-run-validation" aria-label="Anchor link">#</a>Post-Run Validation</h2>
|
|
434
|
-
<ul>
|
|
435
|
-
<li><code>oracle session <id></code> should replay the transcript with markdown.</li>
|
|
436
|
-
<li><code>~/.oracle/sessions/<id>/meta.json</code> must include <code>browser.config</code> metadata (model label, cookie settings) and <code>browser.runtime</code> (PID/port).</li>
|
|
437
|
-
</ul>
|
|
438
|
-
<p>Document results (pass/fail, session IDs) in PR descriptions so reviewers can audit real-world behavior.</p>
|
|
439
|
-
<h2 id="recent-smoke-runs"><a class="anchor" href="#recent-smoke-runs" aria-label="Anchor link">#</a>Recent Smoke Runs</h2>
|
|
440
|
-
<ul>
|
|
441
|
-
<li>2025-11-18 — API gpt-5.1 (<code>api-smoke-give-two-words</code>): returned “blue sky” in 2.5s.</li>
|
|
442
|
-
<li>2025-11-18 — API gpt-5.1-pro (<code>api-smoke-pro-three-words</code>): completed in 3m08s with “Fast API verification”.</li>
|
|
443
|
-
<li>2025-11-18 — Browser gpt-5.1 Instant (<code>browser-smoke-instant-two-words</code>): completed in ~10s; replied with a clarification prompt.</li>
|
|
444
|
-
<li>2025-11-18 — Browser gpt-5.1-pro (<code>browser-smoke-pro-three-words</code>): completed in ~1m33s; response noted “Search tool used.”.</li>
|
|
445
|
-
<li>2025-11-18 (rerun) — API gpt-5.1 (<code>api-smoke-give-two-words</code>): reconfirmed OK; same answer + cost bracket.</li>
|
|
446
|
-
<li>2025-11-18 (rerun) — Browser gpt-5.1-pro (<code>browser-smoke-pro-three-words</code>): reconfirmed OK; included heartbeat progress and search tool note.</li>
|
|
447
|
-
<li>2025-11-20 — Browser gpt-5.1 via <code>oracle serve</code> (remote host on same Mac): fetched https://example.com; title “Example Domain”; first sentence “This domain is for use in documentation examples without needing permission.” (ran via tmux sessions <code>oracle-serve</code> and <code>oracle-client</code>).</li>
|
|
448
|
-
</ul>
|
|
449
|
-
<h2 id="browser-regression-checklist-manual"><a class="anchor" href="#browser-regression-checklist-manual" aria-label="Anchor link">#</a>Browser Regression Checklist (manual)</h2>
|
|
450
|
-
<p>Run these four smoke tests whenever we touch browser automation:</p>
|
|
451
|
-
<ol>
|
|
452
|
-
<li><strong>GPT-5.5 simple prompt</strong></li>
|
|
453
|
-
<p><code>pnpm run oracle -- --engine browser --browser-manual-login --model gpt-5.5 --prompt "Give me two short markdown bullet points about tables"</code> Expect two markdown bullets, no files/search referenced. Note the session ID (e.g., <code>give-me-two-short-markdown</code>).</p>
|
|
454
|
-
</ol>
|
|
455
|
-
<ol>
|
|
456
|
-
<li><strong>GPT-5.5 simple prompt</strong></li>
|
|
457
|
-
<p><code>pnpm run oracle -- --engine browser --browser-manual-login --model gpt-5.5 --prompt "List two reasons Markdown is handy"</code> Confirm the answer arrives (and only once) even if it takes ~2–3 minutes.</p>
|
|
458
|
-
</ol>
|
|
459
|
-
<p>2b. <strong>GPT-5.5 Instant smoke</strong> <code>pnpm run oracle -- --engine browser --browser-manual-login --model gpt-5.5-instant --prompt "Give me two short markdown bullet points about tables"</code> Expect a near-instant response (no Thinking spinner) and confirm the composer pill shows the "Instant" row, not "Thinking 5.5" or "Pro". Run after any change to the 5.5 picker tokens.</p>
|
|
460
|
-
<p>2c. <strong>GPT-5.5 Pro effort through the unified picker</strong> <code>pnpm run oracle -- --engine browser --browser-manual-login --model gpt-5.5-pro --write-output response.txt --prompt "Say Hi!"</code> Confirm the logs report a verified GPT-5.5 model followed by <code>Thinking time: Pro</code>, and <code>response.txt</code> contains the captured answer. Exercise both a tab starting on another model and a retained tab where GPT-5.5 is already selected. Never click ChatGPT's "Answer now" shortcut while the Pro response is thinking.</p>
|
|
461
|
-
<ol>
|
|
462
|
-
<li><strong>GPT-5.5 + attachment</strong></li>
|
|
463
|
-
<p>Prepare <code>/tmp/browser-md.txt</code> with a short note, then run <code>pnpm run oracle -- --engine browser --browser-manual-login --model gpt-5.5 --prompt "Summarize the key idea from the attached note" --file /tmp/browser-md.txt</code> Ensure upload logs show “Attachment queued” and the answer references the file contents explicitly.</p>
|
|
464
|
-
</ol>
|
|
465
|
-
<p>3b. <strong>GPT-5.5 + multi-file ZIP</strong> Create <code>/tmp/oracle-zip-smoke/src/one.txt</code> and <code>/tmp/oracle-zip-smoke/src/two.txt</code> with distinct sentinel text, then run <code>pnpm run oracle -- --engine browser --browser-manual-login --model gpt-5.5 --browser-attachments always --browser-bundle-format zip --prompt "Extract the attached bundle, report both relative paths, and quote each sentinel." --file /tmp/oracle-zip-smoke/src</code> Confirm Oracle uploads one <code>attachments-bundle.zip</code>, the submitted composer text includes the extraction instruction, and the answer reports both paths and sentinels from the extracted tree.</p>
|
|
466
|
-
<ol>
|
|
467
|
-
<li><strong>GPT-5.5 + attachment (verbose)</strong></li>
|
|
468
|
-
<p>Prepare <code>/tmp/browser-report.txt</code> with faux metrics, then run <code>pnpm run oracle -- --engine browser --browser-manual-login --model gpt-5.5 --prompt "Use the attachment to report current CPU and memory figures" --file /tmp/browser-report.txt --verbose</code> Verify verbose logs show attachment upload and the final answer matches the file data.</p>
|
|
469
|
-
</ol>
|
|
470
|
-
<ol>
|
|
471
|
-
<li><strong>Deep Research smoke</strong></li>
|
|
472
|
-
<p><code>pnpm run oracle -- --engine browser --browser-manual-login --browser-research deep --prompt "Research one current public source about WebGPU browser support and cite it"</code> Confirm the logs show Deep Research activation/progress and the final report includes citations or source links. Do not use connected apps or private data.</p>
|
|
473
|
-
</ol>
|
|
474
|
-
<ol>
|
|
475
|
-
<li><strong>Multi-turn browser consult smoke</strong></li>
|
|
476
|
-
<p><code>pnpm run oracle -- --engine browser --browser-manual-login --model gpt-5.5-pro --browser-thinking-time extended --prompt "Give one architectural recommendation for a tiny CLI cache." --browser-follow-up "Challenge your previous recommendation with one concrete failure mode." --browser-follow-up "Now return the final recommendation in one sentence, starting with CHECK_MULTI_TURN_OK."</code> Confirm the output contains all captured turns, includes <code>CHECK_MULTI_TURN_OK</code>, and the saved <code>transcript.md</code> records both follow-up prompts.</p>
|
|
477
|
-
</ol>
|
|
478
|
-
<ol>
|
|
479
|
-
<li><strong>Multi-turn value check</strong></li>
|
|
480
|
-
<p>Run the same initial prompt once without follow-ups and once with the challenge/final-decision follow-ups above. In the PR notes, record concrete differences such as extra failure modes, sharper rollback steps, or test cases. Do not claim a fixed quality percentage.</p>
|
|
481
|
-
</ol>
|
|
482
|
-
<ol>
|
|
483
|
-
<li><strong>Auto-archive smoke</strong></li>
|
|
484
|
-
<p><code>pnpm run oracle -- --engine browser --browser-manual-login --model gpt-5.5-pro --browser-thinking-time extended --browser-archive always --prompt "Reply exactly CHECK_ARCHIVE_OK."</code> Confirm the output contains <code>CHECK_ARCHIVE_OK</code>, <code>oracle session <id> --render</code> still shows the transcript, and ChatGPT shows the conversation under archived chats rather than the active sidebar. Also confirm a default <code>--browser-archive auto</code> run with Deep Research or follow-ups is not archived.</p>
|
|
485
|
-
</ol>
|
|
486
|
-
<p>Record session IDs and outcomes in the PR description (pass/fail, notable delays). This ensures reviewers can audit real runs.</p>
|
|
487
|
-
<h3 id="remote-chrome-smoke-test-cdp"><a class="anchor" href="#remote-chrome-smoke-test-cdp" aria-label="Anchor link">#</a>Remote Chrome smoke test (CDP)</h3>
|
|
488
|
-
<p>Run this whenever you touch CDP connection logic (remote chrome lifecycle, attachment transfer) or before executing remote sessions in CI.</p>
|
|
489
|
-
<ol>
|
|
490
|
-
<li>Launch a throwaway Chrome instance with remote debugging enabled (adjust the path per OS):</li>
|
|
491
|
-
<p>``<code>bash REMOTE_PROFILE=/tmp/oracle-remote-test-profile rm -rf "$REMOTE_PROFILE" "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ --headless=new \ --disable-gpu \ --remote-debugging-port=9333 \ --remote-allow-origins=* \ --user-data-dir="$REMOTE_PROFILE" \ >/tmp/oracle-remote-chrome.log 2>&1 & export REMOTE_CHROME_PID=$! sleep 3 </code>``</p>
|
|
492
|
-
<li>Run the helper to verify CDP connectivity:</li>
|
|
493
|
-
<p>``<code>bash pnpm tsx scripts/test-remote-chrome.ts localhost 9333 </code>`` Expect ✓ logs for connection, protocol info, navigation to https://chatgpt.com/, and the final “POC successful!” line.</p>
|
|
494
|
-
<li>Tear down the temporary browser:</li>
|
|
495
|
-
<p>``<code>bash kill "$REMOTE_CHROME_PID" rm -rf "$REMOTE_PROFILE" </code>`<code> Use </code>pkill -f oracle-remote-test-profile` if Chrome refuses to exit cleanly.</p>
|
|
496
|
-
</ol>
|
|
497
|
-
<p>Capture the pass/fail result (include the helper’s log snippet) in your PR description alongside other manual browser tests.</p>
|
|
498
|
-
<h3 id="attach-running-smoke-test"><a class="anchor" href="#attach-running-smoke-test" aria-label="Anchor link">#</a>Attach-running smoke test</h3>
|
|
499
|
-
<p>Run this whenever you touch the local attach path (<code>--browser-attach-running</code>) or the direct browser websocket bootstrap.</p>
|
|
500
|
-
<ol>
|
|
501
|
-
<li>Start or reuse a local signed-in Chrome with DevTools access available. If you want an explicit local endpoint, launch Chrome with <code>--remote-debugging-port=9222</code>.</li>
|
|
502
|
-
<li>Run Oracle against the running browser:</li>
|
|
503
|
-
<p>``<code>bash pnpm run oracle -- --engine browser \ --browser-attach-running \ --model gpt-5.5 \ --prompt "Give me two short markdown bullets about browser tabs" </code>`<code> If the browser’s remote-debugging UI shows a different local port, rerun with </code>--remote-chrome <host:port><code> in addition to </code>--browser-attach-running`.</p>
|
|
504
|
-
<li>Verify Oracle opens a fresh tab in the existing browser, returns the answer, and closes only that Oracle-owned tab afterward.</li>
|
|
505
|
-
<li>Reattach sanity check: repeat with a very short timeout if needed, then run <code>oracle session <id></code> and confirm Oracle can reconnect to the saved tab/conversation.</li>
|
|
506
|
-
</ol>
|
|
507
|
-
<h2 id="chrome-devtools-mcp-debugging"><a class="anchor" href="#chrome-devtools-mcp-debugging" aria-label="Anchor link">#</a>Chrome DevTools / MCP Debugging</h2>
|
|
508
|
-
<p>Use this when you need to inspect the live ChatGPT composer (DOM state, markdown text, screenshots, etc.). For smaller ad‑hoc pokes, you can often rely on <code>pnpm tsx scripts/browser-tools.ts …</code> instead.</p>
|
|
509
|
-
<ol>
|
|
510
|
-
<li><strong>Launch within tmux</strong></li>
|
|
511
|
-
</ol>
|
|
512
|
-
<p>``<code>bash tmux new -d -s oracle-browser \\ "pnpm run oracle -- --engine browser --browser-manual-login --browser-keep-browser \\ --model gpt-5.5 --browser-thinking-time pro --prompt 'Debug via DevTools.'" </code>``</p>
|
|
513
|
-
<p>Keeping the run in tmux prevents your shell from blocking and ensures Chrome stays open afterward.</p>
|
|
514
|
-
<ol>
|
|
515
|
-
<li><strong>Grab the DevTools port</strong></li>
|
|
516
|
-
</ol>
|
|
517
|
-
<ul>
|
|
518
|
-
<li><code>tmux capture-pane -pt oracle-browser</code> to read the logs (<code>Launched Chrome … on port 56663</code>).</li>
|
|
519
|
-
<li>Verify the endpoint:</li>
|
|
520
|
-
<p>``<code>bash curl http://127.0.0.1:<PORT>/json/version </code>`<code> Note the </code>webSocketDebuggerUrl` for reference.</p>
|
|
521
|
-
</ul>
|
|
522
|
-
<ol>
|
|
523
|
-
<li><strong>Attach Chrome DevTools MCP</strong></li>
|
|
524
|
-
</ol>
|
|
525
|
-
<ul>
|
|
526
|
-
<li>One-off: <code>CHROME_DEVTOOLS_URL=http://127.0.0.1:<PORT> npx -y chrome-devtools-mcp@latest</code></li>
|
|
527
|
-
<li><code>mcporter</code> config snippet:</li>
|
|
528
|
-
<p>``<code>json { "chrome-devtools": { "command": "npx", "args": ["-y", "chrome-devtools-mcp@latest", "--browserUrl", "http://127.0.0.1:<PORT>"] } } </code>``</p>
|
|
529
|
-
<li>Once the server prints <code>chrome-devtools-mcp exposes…</code>, you can list/call tools via <code>mcporter</code>.</li>
|
|
530
|
-
<li>Oracle’s attach-running mode no longer depends on MCP at runtime; <code>mcporter</code> remains useful here for manual inspection only.</li>
|
|
531
|
-
</ul>
|
|
532
|
-
<ol>
|
|
533
|
-
<li><strong>Interact & capture</strong></li>
|
|
534
|
-
</ol>
|
|
535
|
-
<ul>
|
|
536
|
-
<li>Use MCP tools (<code>click</code>, <code>evaluate_js</code>, <code>screenshot</code>, etc.) to debug the composer contents.</li>
|
|
537
|
-
<li>Record any manual actions you take (e.g., “fired evaluate_js to dump #prompt-textarea.innerText”).</li>
|
|
538
|
-
</ul>
|
|
539
|
-
<ol>
|
|
540
|
-
<li><strong>Cleanup</strong></li>
|
|
541
|
-
</ol>
|
|
542
|
-
<ul>
|
|
543
|
-
<li><code>tmux kill-session -t oracle-browser</code></li>
|
|
544
|
-
<li><code>pkill -f oracle-browser-<slug></code> if Chrome is still running.</li>
|
|
545
|
-
</ul>
|
|
546
|
-
<blockquote><p><strong>Tip:</strong> Running <code>npx chrome-devtools-mcp@latest --help</code> lists additional switches (custom Chrome binary, headless, viewport, etc.).</p></blockquote>
|
|
547
|
-
<h2 id="responses-api-live-smoke-tests"><a class="anchor" href="#responses-api-live-smoke-tests" aria-label="Anchor link">#</a>Responses API Live Smoke Tests</h2>
|
|
548
|
-
<p>These Vitest cases hit the real OpenAI API to exercise both transports:</p>
|
|
549
|
-
<ol>
|
|
550
|
-
<li>Export a real key and explicitly opt in (default runs stay fast):</li>
|
|
551
|
-
<p>``<code>bash export OPENAI_API_KEY=sk-... export ORACLE_LIVE_TEST=1 pnpm vitest run tests/live/openai-live.test.ts </code>``</p>
|
|
552
|
-
<li>The first two tests target the standard GPT-5 (<code>gpt-5.1</code> / <code>gpt-5.2</code>) foreground</li>
|
|
553
|
-
<p>streaming paths. The later background tests send <code>gpt-5.5-pro</code> and GPT-5.6 Sol with Pro mode and max reasoning effort prompts and expect the CLI to stay in background mode until OpenAI finishes (up to 30 minutes).</p>
|
|
554
|
-
<li>Watch the console for <code>Reconnected to OpenAI background response...</code> if</li>
|
|
555
|
-
<p>you're debugging transport flakiness; the test will fail if the response status isn't <code>completed</code> or if the text doesn't contain the hard-coded smoke strings.</p>
|
|
556
|
-
</ol>
|
|
557
|
-
<p>Skip these unless you're intentionally validating the production API; they are fully gated behind <code>ORACLE_LIVE_TEST=1</code> to avoid accidental CI runs.</p><nav class="page-nav" aria-label="Pager"><a class="page-nav-prev" href="tui-debug.html"><small>Previous</small><span>TUI navigation crash notes (2025-11-19)</span></a><a class="page-nav-next" href="testing.html"><small>Next</small><span>Testing quickstart</span></a></nav></article>
|
|
558
|
-
<nav class="toc" aria-label="On this page"><h2>On this page</h2><a class="toc-l2" href="#prerequisites">Prerequisites</a><a class="toc-l2" href="#test-cases">Test Cases</a><a class="toc-l3" href="#recovered-tab-retirement">Recovered tab retirement</a><a class="toc-l3" href="#attachment-evidence-and-single-send-regression-no-login">Attachment evidence and single-send regression (no login)</a><a class="toc-l3" href="#browser-artifact-export">Browser artifact export</a><a class="toc-l3" href="#signed-in-attachment-work-mode-guard">Signed-in attachment / Work-mode guard</a><a class="toc-l3" href="#quick-browser-port-smoke">Quick browser port smoke</a><a class="toc-l3" href="#gemini-browser-mode-gemini-web-cookies">Gemini browser mode (Gemini web / cookies)</a><a class="toc-l3" href="#multi-model-cli-fan-out">Multi-Model CLI fan-out</a><a class="toc-l3" href="#write-output-export-api">Write-output export (API)</a><a class="toc-l3" href="#cli-guardrails-and-perf-traces">CLI guardrails and perf traces</a><a class="toc-l3" href="#thinking-effort-evidence">Thinking effort evidence</a><a class="toc-l3" href="#lightweight-browser-cli-manual-exploration">Lightweight Browser CLI (manual exploration)</a><a class="toc-l3" href="#service-admission-and-cancellation">Service admission and cancellation</a><a class="toc-l2" href="#post-run-validation">Post-Run Validation</a><a class="toc-l2" href="#recent-smoke-runs">Recent Smoke Runs</a><a class="toc-l2" href="#browser-regression-checklist-manual">Browser Regression Checklist (manual)</a><a class="toc-l3" href="#remote-chrome-smoke-test-cdp">Remote Chrome smoke test (CDP)</a><a class="toc-l3" href="#attach-running-smoke-test">Attach-running smoke test</a><a class="toc-l2" href="#chrome-devtools-mcp-debugging">Chrome DevTools / MCP Debugging</a><a class="toc-l2" href="#responses-api-live-smoke-tests">Responses API Live Smoke Tests</a></nav>
|
|
559
|
-
</div>
|
|
560
|
-
</main>
|
|
561
|
-
</div>
|
|
562
|
-
<script>
|
|
563
|
-
const themeRoot=document.documentElement;
|
|
564
|
-
function applyTheme(mode){themeRoot.dataset.theme=mode;document.querySelectorAll('[data-theme-toggle]').forEach(b=>b.setAttribute('aria-pressed',mode==='dark'?'true':'false'))}
|
|
565
|
-
function storedTheme(){try{return localStorage.getItem('theme')}catch(e){return null}}
|
|
566
|
-
function persistTheme(mode){try{localStorage.setItem('theme',mode)}catch(e){}}
|
|
567
|
-
applyTheme(themeRoot.dataset.theme==='dark'?'dark':'light');
|
|
568
|
-
document.querySelectorAll('[data-theme-toggle]').forEach(btn=>{btn.addEventListener('click',()=>{const next=themeRoot.dataset.theme==='dark'?'light':'dark';applyTheme(next);persistTheme(next)})});
|
|
569
|
-
const systemDark=window.matchMedia&&matchMedia('(prefers-color-scheme: dark)');
|
|
570
|
-
function onSystemChange(e){if(storedTheme())return;applyTheme(e.matches?'dark':'light')}
|
|
571
|
-
if(systemDark){if(systemDark.addEventListener)systemDark.addEventListener('change',onSystemChange);else if(systemDark.addListener)systemDark.addListener(onSystemChange)}
|
|
572
|
-
const sidebar=document.querySelector('.sidebar');
|
|
573
|
-
const toggle=document.querySelector('.nav-toggle');
|
|
574
|
-
const mobileNav=window.matchMedia('(max-width: 900px)');
|
|
575
|
-
const sidebarFocusable='a[href],button,input,select,textarea,[tabindex]';
|
|
576
|
-
function setSidebarFocusable(enabled){
|
|
577
|
-
sidebar?.querySelectorAll(sidebarFocusable).forEach((el)=>{
|
|
578
|
-
if(enabled){
|
|
579
|
-
if(el.dataset.sidebarTabindex!==undefined){
|
|
580
|
-
if(el.dataset.sidebarTabindex)el.setAttribute('tabindex',el.dataset.sidebarTabindex);
|
|
581
|
-
else el.removeAttribute('tabindex');
|
|
582
|
-
delete el.dataset.sidebarTabindex;
|
|
583
|
-
}
|
|
584
|
-
}else if(el.dataset.sidebarTabindex===undefined){
|
|
585
|
-
el.dataset.sidebarTabindex=el.getAttribute('tabindex')??'';
|
|
586
|
-
el.setAttribute('tabindex','-1');
|
|
587
|
-
}
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
function setSidebarOpen(open){
|
|
591
|
-
if(!sidebar||!toggle)return;
|
|
592
|
-
sidebar.classList.toggle('open',open);
|
|
593
|
-
toggle.setAttribute('aria-expanded',open?'true':'false');
|
|
594
|
-
if(mobileNav.matches){
|
|
595
|
-
sidebar.inert=!open;
|
|
596
|
-
if(open)sidebar.removeAttribute('aria-hidden');
|
|
597
|
-
else sidebar.setAttribute('aria-hidden','true');
|
|
598
|
-
setSidebarFocusable(open);
|
|
599
|
-
}else{
|
|
600
|
-
sidebar.inert=false;
|
|
601
|
-
sidebar.removeAttribute('aria-hidden');
|
|
602
|
-
setSidebarFocusable(true);
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
setSidebarOpen(false);
|
|
606
|
-
toggle?.addEventListener('click',()=>setSidebarOpen(!sidebar?.classList.contains('open')));
|
|
607
|
-
document.addEventListener('click',(e)=>{if(!sidebar?.classList.contains('open'))return;if(sidebar.contains(e.target)||toggle?.contains(e.target))return;setSidebarOpen(false)});
|
|
608
|
-
document.addEventListener('keydown',(e)=>{if(e.key==='Escape')setSidebarOpen(false)});
|
|
609
|
-
const syncSidebarForViewport=()=>setSidebarOpen(sidebar?.classList.contains('open')??false);
|
|
610
|
-
if(mobileNav.addEventListener)mobileNav.addEventListener('change',syncSidebarForViewport);
|
|
611
|
-
else mobileNav.addListener?.(syncSidebarForViewport);
|
|
612
|
-
const input=document.getElementById('doc-search');
|
|
613
|
-
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'})});
|
|
614
|
-
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)}
|
|
615
|
-
document.querySelectorAll('.doc pre').forEach(pre=>attachCopy(pre,()=>pre.querySelector('code')?.textContent??''));
|
|
616
|
-
document.querySelectorAll('.home-install').forEach(el=>attachCopy(el,()=>el.querySelector('code')?.textContent??''));
|
|
617
|
-
const tocLinks=document.querySelectorAll('.toc a');
|
|
618
|
-
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))}
|
|
619
|
-
</script>
|
|
620
|
-
</body>
|
|
621
|
-
</html>
|