@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.
Files changed (47) hide show
  1. package/dist/bin/oracle-cli.js +14 -15
  2. package/dist/src/browser/executor.js +9 -4
  3. package/dist/src/browser/profileState.js +2 -0
  4. package/dist/src/browser/provider.js +15 -1
  5. package/dist/src/browser/sessionRunner.js +2 -2
  6. package/dist/src/gemini-web/browserSessionManager.js +15 -2
  7. package/dist/src/gemini-web/executor.js +1 -1
  8. package/dist/src/gemini-web/http.js +11 -2
  9. package/dist/src/remote/client.js +25 -9
  10. package/dist/src/remote/server.js +19 -5
  11. package/package.json +11 -10
  12. package/dist/docs-site/.nojekyll +0 -0
  13. package/dist/docs-site/CNAME +0 -1
  14. package/dist/docs-site/RELEASING.html +0 -403
  15. package/dist/docs-site/advisor.html +0 -317
  16. package/dist/docs-site/agents.html +0 -375
  17. package/dist/docs-site/anthropic.html +0 -368
  18. package/dist/docs-site/bridge.html +0 -421
  19. package/dist/docs-site/browser-mode.html +0 -636
  20. package/dist/docs-site/chromium-forks.html +0 -355
  21. package/dist/docs-site/cli-reference.html +0 -347
  22. package/dist/docs-site/configuration.html +0 -464
  23. package/dist/docs-site/favicon.svg +0 -14
  24. package/dist/docs-site/followup.html +0 -375
  25. package/dist/docs-site/gemini.html +0 -387
  26. package/dist/docs-site/grok.html +0 -325
  27. package/dist/docs-site/index.html +0 -360
  28. package/dist/docs-site/install.html +0 -335
  29. package/dist/docs-site/linux.html +0 -321
  30. package/dist/docs-site/llms.txt +0 -44
  31. package/dist/docs-site/manual-tests.html +0 -621
  32. package/dist/docs-site/mcp.html +0 -412
  33. package/dist/docs-site/multimodel.html +0 -364
  34. package/dist/docs-site/mythical-pro-agents.html +0 -360
  35. package/dist/docs-site/notifier.html +0 -338
  36. package/dist/docs-site/openai-endpoints.html +0 -417
  37. package/dist/docs-site/openrouter.html +0 -344
  38. package/dist/docs-site/quickstart.html +0 -369
  39. package/dist/docs-site/refactor/ux.html +0 -321
  40. package/dist/docs-site/sessions.html +0 -397
  41. package/dist/docs-site/social-card.png +0 -0
  42. package/dist/docs-site/social-card.svg +0 -79
  43. package/dist/docs-site/spec.html +0 -363
  44. package/dist/docs-site/testing.html +0 -323
  45. package/dist/docs-site/tui-debug.html +0 -326
  46. package/dist/docs-site/windows-work.html +0 -348
  47. package/dist/docs-site/windows.html +0 -320
@@ -1,348 +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>Windows Work — oracle</title>
7
- <meta name="description" content="Windows Work — oracle CLI documentation.">
8
- <link rel="canonical" href="https://askoracle.sh/windows-work.html">
9
- <meta property="og:type" content="website">
10
- <meta property="og:site_name" content="oracle">
11
- <meta property="og:title" content="Windows Work — oracle">
12
- <meta property="og:description" content="Windows Work — oracle CLI documentation.">
13
- <meta property="og:url" content="https://askoracle.sh/windows-work.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="Windows Work — oracle">
19
- <meta name="twitter:description" content="Windows Work — 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 active" 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 &amp; 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 &amp; 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>Windows Work</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/windows-work.md" rel="noopener">Edit page</a>
244
- </div>
245
- </header>
246
- <div class="doc-grid">
247
- <article class="doc"><p># Windows work notes</p>
248
- <p>Read this file whenever you&#39;re working from Windows and add new findings so the next agent can stay unblocked.</p>
249
- <ul>
250
- <li>Browser engine now allowed on Windows; expect more flakiness. If automation fails, rerun with <code>--engine api --wait</code> or point <code>--remote-chrome</code> to a running Chrome with remote debugging.</li>
251
- <li>Chrome DevTools via mcporter: <code>chrome-devtools</code> server needs <code>CHROME_DEVTOOLS_URL</code> from a live session; without it <code>mcporter call chrome-devtools.*</code> fails. Expect this to be unset on Windows unless you bring your own Chrome session/URL.</li>
252
- <li>The agent-scripts <code>runner</code> helper can fail under PowerShell/CMD because of CRLF and bash expectations. If it explodes, run commands directly (<code>pnpm ...</code>, <code>git add/commit</code>) instead.</li>
253
- <li>browser-tools binary: not built in <code>agent-scripts/bin</code> on Windows; <code>pnpm tsx scripts/browser-tools.ts</code> also fails there (no package manifest). Use a macOS-built binary or run from macOS if you need it.</li>
254
- <li>Prefer PowerShell + pnpm directly; watch for CRLF warnings when touching tracked files.</li>
255
- <li>WSL browser launch host detection: a systemd-resolved stub such as <code>nameserver 127.0.0.53</code> is guest loopback, not the Windows host. Keep resolver-derived non-loopback hosts for Windows Chrome compatibility, but route resolver-derived <code>127/8</code> values to the standard local Chrome launcher.</li>
256
- <li>Detached session workers launched by either CLI or MCP must use the shared launcher with <code>windowsHide: true</code>; a bounded MCP <code>wait</code> releases only the waiter and leaves that hidden worker running.</li>
257
- <li>A waiter can read <code>meta.json</code> while the detached worker atomically replaces it. Windows may transiently reject that replacement with <code>EPERM</code>, <code>EBUSY</code>, or <code>EACCES</code>; retry only those lock-like errors with a short bounded backoff.</li>
258
- <li>Resolve the session directory with <code>realpathSync.native</code> before <code>fs.watch</code>; Windows short-path aliases can otherwise hit a native libuv path-prefix assertion instead of a catchable watcher error.</li>
259
- </ul>
260
- <p>Future Windows gotchas belong here. Update this doc when you learn something new.</p>
261
- <ul>
262
- <li>Tab-lease tests run real PowerShell process-identity probes (up to five seconds each). Their Windows test budget must cover multiple probes and registry cleanup. Failed self-identity probes are retried on the next lookup; only a successful identity is cached for the controller lifetime.</li>
263
- </ul>
264
- <ul>
265
- <li>Detached-worker proofs must wait for the worker PID to exit before deleting its temporary working directory. Sending SIGTERM alone races Windows handle release and can fail cleanup with EBUSY; use a bounded exit wait and bounded filesystem retries without skipping the lifecycle assertions.</li>
266
- </ul>
267
- <ul>
268
- <li>A fresh Windows worktree with <code>core.autocrlf=true</code> can make <code>oxfmt --check</code> flag otherwise unchanged files. Use LF checkout contents for validation and inspect the staged diff to keep checkout-only line-ending changes out of the PR.</li>
269
- </ul>
270
- <ul>
271
- <li>ChatGPT sidebar/history labels can include phrases like &quot;Login setup instruction&quot;; login probes must match exact auth CTAs, not any visible text starting with login, or manual-login automation loops forever before typing.</li>
272
- <li>For Windows PR refreshes, use <code>git -c core.autocrlf=false</code> for merge and review commands; preserve untracked <code>.codex-tmp/</code> handoff state and leave it out of commits.</li>
273
- <li>ChatGPT&#39;s composer plus button can sit close to Work suggestions. A coordinate click observed on Windows entered a new <code>/c/WEB:...</code> Work task even though the attachment tile later appeared. Activate only <code>#composer-plus-btn</code> / <code>button[data-testid=&quot;composer-plus-btn&quot;]</code>, then fail closed if the conversation id changes or Work becomes selected before file assignment. Preserve that page identity through upload and check it again at final dispatch. After upload, close an expanded plus menu and keyboard-activate only the exact <code>button[data-testid=&quot;send-button&quot;]</code>; a trusted coordinate click was observed dismissing UI without committing the staged attachment prompt.</li>
274
- <li><code>scripts/browser-tools.ts</code> may attach its &quot;active page&quot; command to an <code>about:blank</code> target when several DevTools targets exist. For signed-in evidence, select the exact target id recorded by the Oracle session and verify its URL and composer state directly.</li>
275
- </ul>
276
- <ul>
277
- <li>Shared manual-login Chrome is detached from its native Windows controller and launched with <code>windowsHide</code>; temporary and copied profiles retain their existing process lifecycle. The final verified lease owner terminates the matching Chrome PID/profile.</li>
278
- <li>After upgrading this lease protocol, restart all Oracle browser controllers before sharing a profile. Older live controllers can forcibly remove a registry lock after their timeout; stored legacy records remain readable, but simultaneous mixed-version controllers are not a safe upgrade path.</li>
279
- <li>Run <code>node scripts/shared-chrome-lifecycle-proof.mjs</code> after building for the native two-controller check. It uses a freshly initialized, signed-out profile and locally supplied pages, verifies peer CDP access after the owner exits, then checks final registry/process/endpoint cleanup. It does not prove signed-in ChatGPT concurrency or backend model identity.</li>
280
- </ul>
281
- <ul>
282
- <li>After merging a dependency update that changes oxfmt, CRLF checkouts may fail format checks across otherwise unchanged files. Normalize tracked text working copies to LF and use <code>git -c core.autocrlf=false</code> for staging; verify the resulting diff contains only intended changes.</li>
283
- </ul>
284
- <p>Provider-native conversation evidence uses the existing browser connection on Windows too. Files follow the account/directory ACLs; the POSIX owner-only file mode assertion is skipped on Windows. Capture failures leave the normal answer available.</p><nav class="page-nav" aria-label="Pager"><a class="page-nav-prev" href="windows.html"><small>Previous</small><span>Windows compatibility notes</span></a><a class="page-nav-next" href="bridge.html"><small>Next</small><span>Bridge (Windows-hosted ChatGPT session → Linux clients)</span></a></nav></article>
285
-
286
- </div>
287
- </main>
288
- </div>
289
- <script>
290
- const themeRoot=document.documentElement;
291
- function applyTheme(mode){themeRoot.dataset.theme=mode;document.querySelectorAll('[data-theme-toggle]').forEach(b=>b.setAttribute('aria-pressed',mode==='dark'?'true':'false'))}
292
- function storedTheme(){try{return localStorage.getItem('theme')}catch(e){return null}}
293
- function persistTheme(mode){try{localStorage.setItem('theme',mode)}catch(e){}}
294
- applyTheme(themeRoot.dataset.theme==='dark'?'dark':'light');
295
- document.querySelectorAll('[data-theme-toggle]').forEach(btn=>{btn.addEventListener('click',()=>{const next=themeRoot.dataset.theme==='dark'?'light':'dark';applyTheme(next);persistTheme(next)})});
296
- const systemDark=window.matchMedia&&matchMedia('(prefers-color-scheme: dark)');
297
- function onSystemChange(e){if(storedTheme())return;applyTheme(e.matches?'dark':'light')}
298
- if(systemDark){if(systemDark.addEventListener)systemDark.addEventListener('change',onSystemChange);else if(systemDark.addListener)systemDark.addListener(onSystemChange)}
299
- const sidebar=document.querySelector('.sidebar');
300
- const toggle=document.querySelector('.nav-toggle');
301
- const mobileNav=window.matchMedia('(max-width: 900px)');
302
- const sidebarFocusable='a[href],button,input,select,textarea,[tabindex]';
303
- function setSidebarFocusable(enabled){
304
- sidebar?.querySelectorAll(sidebarFocusable).forEach((el)=>{
305
- if(enabled){
306
- if(el.dataset.sidebarTabindex!==undefined){
307
- if(el.dataset.sidebarTabindex)el.setAttribute('tabindex',el.dataset.sidebarTabindex);
308
- else el.removeAttribute('tabindex');
309
- delete el.dataset.sidebarTabindex;
310
- }
311
- }else if(el.dataset.sidebarTabindex===undefined){
312
- el.dataset.sidebarTabindex=el.getAttribute('tabindex')??'';
313
- el.setAttribute('tabindex','-1');
314
- }
315
- });
316
- }
317
- function setSidebarOpen(open){
318
- if(!sidebar||!toggle)return;
319
- sidebar.classList.toggle('open',open);
320
- toggle.setAttribute('aria-expanded',open?'true':'false');
321
- if(mobileNav.matches){
322
- sidebar.inert=!open;
323
- if(open)sidebar.removeAttribute('aria-hidden');
324
- else sidebar.setAttribute('aria-hidden','true');
325
- setSidebarFocusable(open);
326
- }else{
327
- sidebar.inert=false;
328
- sidebar.removeAttribute('aria-hidden');
329
- setSidebarFocusable(true);
330
- }
331
- }
332
- setSidebarOpen(false);
333
- toggle?.addEventListener('click',()=>setSidebarOpen(!sidebar?.classList.contains('open')));
334
- document.addEventListener('click',(e)=>{if(!sidebar?.classList.contains('open'))return;if(sidebar.contains(e.target)||toggle?.contains(e.target))return;setSidebarOpen(false)});
335
- document.addEventListener('keydown',(e)=>{if(e.key==='Escape')setSidebarOpen(false)});
336
- const syncSidebarForViewport=()=>setSidebarOpen(sidebar?.classList.contains('open')??false);
337
- if(mobileNav.addEventListener)mobileNav.addEventListener('change',syncSidebarForViewport);
338
- else mobileNav.addListener?.(syncSidebarForViewport);
339
- const input=document.getElementById('doc-search');
340
- 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'})});
341
- 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)}
342
- document.querySelectorAll('.doc pre').forEach(pre=>attachCopy(pre,()=>pre.querySelector('code')?.textContent??''));
343
- document.querySelectorAll('.home-install').forEach(el=>attachCopy(el,()=>el.querySelector('code')?.textContent??''));
344
- const tocLinks=document.querySelectorAll('.toc a');
345
- 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))}
346
- </script>
347
- </body>
348
- </html>