@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,412 +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>MCP Server — oracle</title>
7
- <meta name="description" content="MCP Server — oracle CLI documentation.">
8
- <link rel="canonical" href="https://askoracle.sh/mcp.html">
9
- <meta property="og:type" content="website">
10
- <meta property="og:site_name" content="oracle">
11
- <meta property="og:title" content="MCP Server — oracle">
12
- <meta property="og:description" content="MCP Server — oracle CLI documentation.">
13
- <meta property="og:url" content="https://askoracle.sh/mcp.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="MCP Server — oracle">
19
- <meta name="twitter:description" content="MCP Server — 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 &amp; MCP</h2><a class="nav-link" href="agents.html">Coding Agents</a><a class="nav-link active" 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">Agents &amp; MCP</p>
239
- <h1>MCP Server</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/mcp.md" rel="noopener">Edit page</a>
244
- </div>
245
- </header>
246
- <div class="doc-grid">
247
- <article class="doc"><h1 id="mcp-server">MCP Server</h1>
248
- <p><code>oracle-mcp</code> is a minimal MCP stdio server that mirrors the Oracle CLI. It shares session storage with the CLI (<code>~/.oracle/sessions</code> or <code>ORACLE_HOME_DIR</code>) so you can mix and match: run with the CLI, inspect or re-run via MCP, or vice versa.</p>
249
- <p>The server uses MCP SDK v2 and serves both modern and legacy protocol clients over stdio. Existing tool inputs, defaults, structured outputs, and <code>oracle-session://</code> resources are preserved. The SDK owns protocol negotiation and transport shutdown; the server definition is shared between protocol generations. HTTP transport, authentication, subscriptions, and protocol task APIs remain separate from this migration.</p>
250
- <h2 id="let-them-fight"><a class="anchor" href="#let-them-fight" aria-label="Anchor link">#</a>Let Them Fight</h2>
251
- <p>Claude Code can call <code>oracle-mcp</code> and ask a subscription-backed ChatGPT browser session for a second opinion. Use the <code>chatgpt-pro-heavy</code> preset when you want a compact MCP request that targets ChatGPT browser mode, the current Pro picker alias, and Pro Extended thinking time. The preset is intentionally boring at the API layer: it is a shortcut for existing browser-mode fields, not a new model id.</p>
252
- <h2 id="tools"><a class="anchor" href="#tools" aria-label="Anchor link">#</a>Tools</h2>
253
- <h3 id="chatgpt-image"><a class="anchor" href="#chatgpt-image" aria-label="Anchor link">#</a><code>chatgpt_image</code></h3>
254
- <ul>
255
- <li>Inputs: <code>prompt</code> (required), <code>files?: string[]</code> for reference images/assets, <code>outputPath?: string</code>, <code>aspectRatio?: string</code>, <code>model?: string</code>, plus browser controls such as <code>browserThinkingTime</code>, <code>browserModelLabel</code>, <code>browserModelStrategy</code>, <code>browserArchive</code>, <code>browserKeepBrowser</code>, and <code>dryRun</code>.</li>
256
- <li>Behavior: convenience wrapper for ChatGPT browser image generation. It forces <code>engine:&quot;browser&quot;</code>, sets <code>generateImage</code> for the existing image-aware wait/download path, and defaults <code>browserAttachments:&quot;always&quot;</code> when files are provided so reference images are uploaded instead of pasted.</li>
257
- <li>Output: returns the normal session metadata plus <code>requestedOutputPath</code> and <code>structuredContent.images[]</code> with saved local paths, MIME type, size, dimensions, and ChatGPT file id when available. Signed source/download URLs are not returned. If <code>outputPath</code> is omitted, Oracle picks a unique file under <code>ORACLE_HOME_DIR/generated/</code>.</li>
258
- <li>Output path safety: agent-supplied <code>outputPath</code> must resolve under <code>ORACLE_HOME_DIR/generated</code> by default; traversal and symlink escapes are rejected. This keeps MCP writes away from Oracle config, session metadata, and browser profile state. Set <code>ORACLE_MCP_ALLOW_EXTERNAL_OUTPUT=1</code> to allow writing elsewhere as an explicit operator decision. Omit <code>outputPath</code> to use the safe default.</li>
259
- <li>Remote browser services: image output requires the host&#39;s <code>generatedImages: true</code> capability with artifact protocol v1. Current clients send image intent without exposing their filesystem path to the host; the host captures into its own session directory, then the client transfers the image to the requested local output path. Clients reject image requests before sending prompts or attachments to older hosts and report that the host needs an upgrade; text-only calls remain compatible.</li>
260
- </ul>
261
- <pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-json"><span class="line"><span style="color:#ADBAC7">{</span></span>
262
- <span class="line"><span style="color:#8DDB8C"> "prompt"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"Create a 9:16 App Store screenshot background for a focus timer."</span><span style="color:#ADBAC7">,</span></span>
263
- <span class="line"><span style="color:#8DDB8C"> "files"</span><span style="color:#ADBAC7">: [</span><span style="color:#96D0FF">"./reference-screen.png"</span><span style="color:#ADBAC7">],</span></span>
264
- <span class="line"><span style="color:#8DDB8C"> "aspectRatio"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"9:16"</span></span>
265
- <span class="line"><span style="color:#ADBAC7">}</span></span></code></pre>
266
- <h3 id="consult"><a class="anchor" href="#consult" aria-label="Anchor link">#</a><code>consult</code></h3>
267
- <ul>
268
- <li>Inputs: <code>prompt</code> (required), <code>files?: string[]</code> (globs), <code>model?: string</code> (defaults to CLI), <code>engine?: &quot;api&quot; | &quot;browser&quot;</code> (optional; Oracle follows CLI defaults: <code>ORACLE_ENGINE</code> and the effective config first, then API when <code>OPENAI_API_KEY</code> is set, otherwise browser), <code>waitForCompletion?: boolean</code>, <code>slug?: string</code>.</li>
269
- <li>Presets: <code>preset?: &quot;chatgpt-pro-heavy&quot;</code> applies browser mode + current Pro model alias + extended thinking, unless the request overrides those fields.</li>
270
- <li>Browser-only extras: <code>browserAttachments?: &quot;auto&quot;|&quot;never&quot;|&quot;always&quot;</code>, <code>browserBundleFiles?: boolean</code>, <code>browserBundleFormat?: &quot;auto&quot;|&quot;text&quot;|&quot;zip&quot;</code>, <code>browserThinkingTime?: &quot;light&quot;|&quot;standard&quot;|&quot;extended&quot;|&quot;extra-high&quot;|&quot;pro&quot;|&quot;heavy&quot;</code>, <code>browserResearchMode?: &quot;deep&quot;</code>, <code>browserFollowUps?: string[]</code>, <code>browserArchive?: &quot;auto&quot;|&quot;always&quot;|&quot;never&quot;</code>, <code>browserKeepBrowser?: boolean</code>, <code>browserModelLabel?: string</code>, <code>browserModelStrategy?: &quot;select&quot;|&quot;current&quot;|&quot;ignore&quot;</code>, <code>generateImage?: string</code>, <code>outputPath?: string</code>.</li>
271
- <li>Browser file uploads: one text/source file stays native, while multiple text/source files default to one bundle. <code>browserBundleFormat:&quot;auto&quot;</code> keeps flattened text for text-only uploads and uses ZIP when raw files are present. Set <code>browserBundleFormat:&quot;zip&quot;</code> for a filesystem tree, or <code>browserBundleFiles:true</code> to force one all-file bundle.</li>
272
- <li>Dry runs: set <code>dryRun: true</code> to preview the resolved request without creating a session or touching the browser.</li>
273
- <li>Behavior: starts a session and runs it with the chosen engine. The compatibility default is <code>waitForCompletion:true</code>, which returns final output + metadata in the same call. Set <code>waitForCompletion:false</code> to launch a local detached worker and return a durable <code>sessionId</code> immediately. If API mode fails because <code>OPENAI_API_KEY</code> is missing and you have ChatGPT Pro, retry with <code>engine: &quot;browser&quot;</code> or <code>preset: &quot;chatgpt-pro-heavy&quot;</code> to use your signed-in ChatGPT session instead of an API key.</li>
274
- <li>Local browser consultations select ChatGPT or Gemini from the model, including detached workers. Remote browser services support ChatGPT only; Gemini requests fail before submission.</li>
275
- <li>Logging: emits MCP logs (<code>info</code> per line, <code>debug</code> for streamed chunks with byte sizes). If browser prerequisites are missing, returns an error payload instead of running.</li>
276
- <li>Research mode: set <code>browserResearchMode:&quot;deep&quot;</code> for broad public-web research and cited reports. Use normal browser runs with <code>gpt-5.5-pro</code> + <code>browserThinkingTime:&quot;extended&quot;</code> for legacy Pro Extended code review, <code>gpt-5.6-sol</code> + <code>browserThinkingTime:&quot;extra-high&quot;</code> for Extra High, or <code>gpt-5.6-sol</code> + <code>browserThinkingTime:&quot;pro&quot;</code> when you explicitly want the current Pro effort tier.</li>
277
- <li>Multi-turn consults: set <code>browserFollowUps:[&quot;Challenge your recommendation&quot;, &quot;Give the final decision&quot;]</code> to keep one ChatGPT browser conversation open and ask sequential follow-up prompts. Use one-shot calls for narrow bugs and exact file-set reviews; use multi-turn for ambiguous architecture/product decisions where a challenge pass and final recommendation are useful; use Deep Research for broad public-web work with citations. Oracle never invents follow-ups automatically.</li>
278
- <li>Archiving: set <code>browserArchive:&quot;auto&quot;|&quot;always&quot;|&quot;never&quot;</code> to control ChatGPT conversation cleanup. <code>auto</code> archives only successful browser one-shots after local artifacts are saved, and skips project, Deep Research, multi-turn, failed, and incomplete sessions.</li>
279
- <li>Web Search: set <code>engine:&quot;browser&quot;, browserResearchMode:&quot;search&quot;</code> to explicitly select the English ChatGPT Web Search control. Selection and the staged prompt must be verified before submission. This pilot uses locally controlled Chrome, including attach-running/direct remote Chrome; remote browser-service execution is refused until capability negotiation is available.</li>
280
- <li>ChatGPT image generation: set <code>engine:&quot;browser&quot;</code> and <code>generateImage</code> to a path under <code>ORACLE_HOME_DIR/generated</code> to use the same image-aware wait/download path as CLI <code>--generate-image</code>. Saved files are returned in <code>structuredContent.images</code> and recorded as session artifacts; multiple images save as numbered siblings. Agent-supplied <code>generateImage</code> / <code>outputPath</code> are constrained to that generated-output directory by default (set <code>ORACLE_MCP_ALLOW_EXTERNAL_OUTPUT=1</code> to allow external paths).</li>
281
- </ul>
282
- <h4 id="long-browser-consults-from-agents"><a class="anchor" href="#long-browser-consults-from-agents" aria-label="Anchor link">#</a>Long browser consults from agents</h4>
283
- <p>Browser-backed GPT-5.5 Pro and Deep Research consults can legitimately run for many minutes. Start them with <code>waitForCompletion:false</code>, then call <code>wait</code> with the returned <code>sessionId</code>; this keeps the run alive independently of either MCP request and avoids agent-side polling. Start with <code>dryRun:true</code> when configuring a new agent, prefer <code>preset:&quot;chatgpt-pro-heavy&quot;</code> or <code>engine:&quot;browser&quot;</code> explicitly, and inspect the shared session store before retrying a prompt. Detached consult launch currently requires local execution; remote browser-service callers should keep <code>waitForCompletion:true</code>. If the browser control plan says Oracle will launch visible Chrome, use attach/remote Chrome when the operator is actively using the computer.</p>
284
- <pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-json"><span class="line"><span style="color:#ADBAC7">{</span></span>
285
- <span class="line"><span style="color:#8DDB8C"> "prompt"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"Review this architecture"</span><span style="color:#ADBAC7">,</span></span>
286
- <span class="line"><span style="color:#8DDB8C"> "files"</span><span style="color:#ADBAC7">: [</span><span style="color:#96D0FF">"src/**"</span><span style="color:#ADBAC7">],</span></span>
287
- <span class="line"><span style="color:#8DDB8C"> "preset"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"chatgpt-pro-heavy"</span><span style="color:#ADBAC7">,</span></span>
288
- <span class="line"><span style="color:#8DDB8C"> "waitForCompletion"</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">false</span></span>
289
- <span class="line"><span style="color:#ADBAC7">}</span></span></code></pre>
290
- <p>Then wait without polling:</p>
291
- <pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-json"><span class="line"><span style="color:#ADBAC7">{ </span><span style="color:#8DDB8C">"id"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"&#x3C;sessionId from consult>"</span><span style="color:#ADBAC7">, </span><span style="color:#8DDB8C">"timeoutMs"</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">900000</span><span style="color:#ADBAC7"> }</span></span></code></pre>
292
- <h4 id="chatgpt-images-from-agents"><a class="anchor" href="#chatgpt-images-from-agents" aria-label="Anchor link">#</a>ChatGPT images from agents</h4>
293
- <p>For generated images, pass an explicit <code>generateImage</code> path. That opt-in is important because it switches the browser wait loop to watch for ChatGPT image artifacts instead of only assistant text. The path must resolve under <code>ORACLE_HOME_DIR/generated</code> unless <code>ORACLE_MCP_ALLOW_EXTERNAL_OUTPUT=1</code> is set.</p>
294
- <pre class="shiki github-dark-dimmed" style="background-color:var(--code-bg);color:var(--code-fg)" tabindex="0"><code class="language-json"><span class="line"><span style="color:#ADBAC7">{</span></span>
295
- <span class="line"><span style="color:#8DDB8C"> "engine"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"browser"</span><span style="color:#ADBAC7">,</span></span>
296
- <span class="line"><span style="color:#8DDB8C"> "model"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"gpt-5.5-pro"</span><span style="color:#ADBAC7">,</span></span>
297
- <span class="line"><span style="color:#8DDB8C"> "prompt"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"Create a 9:16 App Store screenshot background for a focus timer."</span><span style="color:#ADBAC7">,</span></span>
298
- <span class="line"><span style="color:#8DDB8C"> "generateImage"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"${ORACLE_HOME_DIR}/generated/focus-timer-bg.png"</span></span>
299
- <span class="line"><span style="color:#ADBAC7">}</span></span></code></pre>
300
- <p>The MCP response includes <code>structuredContent.images[]</code> with the saved file path, MIME type, size, dimensions, and ChatGPT file id when available. Signed source/download URLs remain internal.</p>
301
- <h3 id="sessions"><a class="anchor" href="#sessions" aria-label="Anchor link">#</a><code>sessions</code></h3>
302
- <ul>
303
- <li>Inputs: <code>{id?, hours?, limit?, includeAll?, detail?}</code> mirroring <code>oracle status</code> / <code>oracle session</code>.</li>
304
- <li>Behavior: without <code>id</code>, returns a bounded list of recent sessions. With <code>id</code>/slug, returns a summary row; set <code>detail: true</code> to fetch full metadata, log, and stored request body.</li>
305
- </ul>
306
- <h3 id="wait"><a class="anchor" href="#wait" aria-label="Anchor link">#</a><code>wait</code></h3>
307
- <ul>
308
- <li>Inputs: <code>id</code> (required session id or slug), <code>timeoutMs?: number</code>.</li>
309
- <li>Behavior: blocks until the durable session status becomes <code>completed</code>, <code>partial</code>, <code>error</code>, or <code>cancelled</code>, then returns the final log tail and artifact/model/image summaries. It uses filesystem notifications with a low-frequency fallback and rereads session metadata after every wakeup.</li>
310
- <li>Timeout semantics: omit <code>timeoutMs</code> to wait indefinitely, set a positive value to bound only this MCP call, or set <code>0</code> for an immediate snapshot. A timeout returns <code>waitStatus:&quot;timed_out&quot;</code>; caller cancellation, transport closure, host-imposed request deadlines, or timeout never cancels the Oracle worker. Call <code>wait</code> again with the same <code>id</code> to continue.</li>
311
- </ul>
312
- <h3 id="project-sources"><a class="anchor" href="#project-sources" aria-label="Anchor link">#</a><code>project_sources</code></h3>
313
- <ul>
314
- <li>Inputs: <code>operation: &quot;list&quot;|&quot;add&quot;</code>, <code>chatgptUrl?: string</code>, <code>files?: string[]</code>, <code>dryRun?: boolean</code>, <code>confirmMutation?: boolean</code>, <code>browserKeepBrowser?: boolean</code>.</li>
315
- <li>Behavior: manages the ChatGPT Project Sources tab through local browser automation. v1 is intentionally append-only: it can list existing sources and add files, but it cannot delete, replace, or sync.</li>
316
- <li>Safety: <code>add</code> requires <code>confirmMutation: true</code> unless <code>dryRun: true</code>. This keeps agent callers from mutating a persistent ChatGPT Project by accident.</li>
317
- <li>Workflow: use this when Claude Code, Codex, or another MCP host needs a durable shared context file in a ChatGPT Project. Use <code>consult</code> when you want an actual model answer.</li>
318
- </ul>
319
- <h2 id="resources"><a class="anchor" href="#resources" aria-label="Anchor link">#</a>Resources</h2>
320
- <ul>
321
- <li><code>oracle-session://{id}/{metadata|log|request}</code> — read-only resources that surface stored session artifacts via MCP resource reads.</li>
322
- </ul>
323
- <h2 id="background-detach-behavior"><a class="anchor" href="#background-detach-behavior" aria-label="Anchor link">#</a>Background / detach behavior</h2>
324
- <ul>
325
- <li><code>consult</code> remains synchronous by default for compatibility. Set <code>waitForCompletion:false</code> to detach any local API or browser run explicitly, then use <code>wait</code> to attach a bounded or unbounded waiter to its durable session state.</li>
326
- <li>The detached worker owns the run. Ending or timing out a <code>wait</code> call only releases that waiter; it does not stop the worker. CLI inspection and reattachment remain available through <code>oracle session &lt;id&gt;</code> / <code>oracle status</code>.</li>
327
- </ul>
328
- <h2 id="launching-usage"><a class="anchor" href="#launching-usage" aria-label="Anchor link">#</a>Launching &amp; usage</h2>
329
- <ul>
330
- <li>Installed from npm:</li>
331
- <li>One-off: <code>npx @steipete/oracle oracle-mcp</code></li>
332
- <li>Global: <code>oracle-mcp</code></li>
333
- <li>From the repo (contributors):</li>
334
- <li><code>pnpm build</code></li>
335
- <li><code>pnpm mcp</code> (or <code>oracle-mcp</code> in the repo root)</li>
336
- <li>mcporter example (stdio):</li>
337
- <p>``<code>json { &quot;name&quot;: &quot;oracle&quot;, &quot;type&quot;: &quot;stdio&quot;, &quot;command&quot;: &quot;npx&quot;, &quot;args&quot;: [&quot;@steipete/oracle&quot;, &quot;oracle-mcp&quot;] } </code>``</p>
338
- <li>Project-scoped Claude (.mcp.json) example:</li>
339
- <p>``<code>json { &quot;mcpServers&quot;: { &quot;oracle&quot;: { &quot;type&quot;: &quot;stdio&quot;, &quot;command&quot;: &quot;npx&quot;, &quot;args&quot;: [&quot;@steipete/oracle&quot;, &quot;oracle-mcp&quot;] } } } </code>``</p>
340
- <li>Bridge helper snippets:</li>
341
- <li>Codex CLI: <code>oracle bridge codex-config</code></li>
342
- <li>Claude Code: <code>oracle bridge claude-config</code></li>
343
- <li>Claude Code with local macOS Chrome: <code>oracle bridge claude-config --local-browser &gt; .mcp.json</code></li>
344
- <li>Tools and resources operate on the same session store as <code>oracle status|session</code>.</li>
345
- <li>Defaults (model/engine/etc.) come from the effective Oracle CLI config; see <code>docs/configuration.md</code>, <code>~/.oracle/config.json</code>, and project <code>.oracle/config.json</code> files.</li>
346
- </ul>
347
- <h3 id="lifecycle-compatibility-check"><a class="anchor" href="#lifecycle-compatibility-check" aria-label="Anchor link">#</a>Lifecycle compatibility check</h3>
348
- <p>After building, run <code>node scripts/mcp-lifecycle-proof.mjs</code> to exercise SDK v1, SDK v2 legacy, and SDK v2 modern clients through both executable entrypoints. It starts real detached CLI workers against a local API fixture and checks caller timeouts, request cancellation, transport reconnects, durable completion, and a single provider submission. The standard test suite also runs this matrix. For a real OpenAI run, add <code>--live-key-file &lt;private-key-file&gt;</code>; the harness uses an authenticated upstream request and delays its reply until the lifecycle assertions finish. This does not exercise signed-in browser execution.</p><nav class="page-nav" aria-label="Pager"><a class="page-nav-prev" href="agents.html"><small>Previous</small><span>Coding Agents</span></a><a class="page-nav-next" href="sessions.html"><small>Next</small><span>Sessions</span></a></nav></article>
349
- <nav class="toc" aria-label="On this page"><h2>On this page</h2><a class="toc-l2" href="#let-them-fight">Let Them Fight</a><a class="toc-l2" href="#tools">Tools</a><a class="toc-l3" href="#chatgpt-image">chatgpt_image</a><a class="toc-l3" href="#consult">consult</a><a class="toc-l3" href="#sessions">sessions</a><a class="toc-l3" href="#wait">wait</a><a class="toc-l3" href="#project-sources">project_sources</a><a class="toc-l2" href="#resources">Resources</a><a class="toc-l2" href="#background-detach-behavior">Background / detach behavior</a><a class="toc-l2" href="#launching-usage">Launching &amp;amp; usage</a><a class="toc-l3" href="#lifecycle-compatibility-check">Lifecycle compatibility check</a></nav>
350
- </div>
351
- </main>
352
- </div>
353
- <script>
354
- const themeRoot=document.documentElement;
355
- function applyTheme(mode){themeRoot.dataset.theme=mode;document.querySelectorAll('[data-theme-toggle]').forEach(b=>b.setAttribute('aria-pressed',mode==='dark'?'true':'false'))}
356
- function storedTheme(){try{return localStorage.getItem('theme')}catch(e){return null}}
357
- function persistTheme(mode){try{localStorage.setItem('theme',mode)}catch(e){}}
358
- applyTheme(themeRoot.dataset.theme==='dark'?'dark':'light');
359
- document.querySelectorAll('[data-theme-toggle]').forEach(btn=>{btn.addEventListener('click',()=>{const next=themeRoot.dataset.theme==='dark'?'light':'dark';applyTheme(next);persistTheme(next)})});
360
- const systemDark=window.matchMedia&&matchMedia('(prefers-color-scheme: dark)');
361
- function onSystemChange(e){if(storedTheme())return;applyTheme(e.matches?'dark':'light')}
362
- if(systemDark){if(systemDark.addEventListener)systemDark.addEventListener('change',onSystemChange);else if(systemDark.addListener)systemDark.addListener(onSystemChange)}
363
- const sidebar=document.querySelector('.sidebar');
364
- const toggle=document.querySelector('.nav-toggle');
365
- const mobileNav=window.matchMedia('(max-width: 900px)');
366
- const sidebarFocusable='a[href],button,input,select,textarea,[tabindex]';
367
- function setSidebarFocusable(enabled){
368
- sidebar?.querySelectorAll(sidebarFocusable).forEach((el)=>{
369
- if(enabled){
370
- if(el.dataset.sidebarTabindex!==undefined){
371
- if(el.dataset.sidebarTabindex)el.setAttribute('tabindex',el.dataset.sidebarTabindex);
372
- else el.removeAttribute('tabindex');
373
- delete el.dataset.sidebarTabindex;
374
- }
375
- }else if(el.dataset.sidebarTabindex===undefined){
376
- el.dataset.sidebarTabindex=el.getAttribute('tabindex')??'';
377
- el.setAttribute('tabindex','-1');
378
- }
379
- });
380
- }
381
- function setSidebarOpen(open){
382
- if(!sidebar||!toggle)return;
383
- sidebar.classList.toggle('open',open);
384
- toggle.setAttribute('aria-expanded',open?'true':'false');
385
- if(mobileNav.matches){
386
- sidebar.inert=!open;
387
- if(open)sidebar.removeAttribute('aria-hidden');
388
- else sidebar.setAttribute('aria-hidden','true');
389
- setSidebarFocusable(open);
390
- }else{
391
- sidebar.inert=false;
392
- sidebar.removeAttribute('aria-hidden');
393
- setSidebarFocusable(true);
394
- }
395
- }
396
- setSidebarOpen(false);
397
- toggle?.addEventListener('click',()=>setSidebarOpen(!sidebar?.classList.contains('open')));
398
- document.addEventListener('click',(e)=>{if(!sidebar?.classList.contains('open'))return;if(sidebar.contains(e.target)||toggle?.contains(e.target))return;setSidebarOpen(false)});
399
- document.addEventListener('keydown',(e)=>{if(e.key==='Escape')setSidebarOpen(false)});
400
- const syncSidebarForViewport=()=>setSidebarOpen(sidebar?.classList.contains('open')??false);
401
- if(mobileNav.addEventListener)mobileNav.addEventListener('change',syncSidebarForViewport);
402
- else mobileNav.addListener?.(syncSidebarForViewport);
403
- const input=document.getElementById('doc-search');
404
- 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'})});
405
- 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)}
406
- document.querySelectorAll('.doc pre').forEach(pre=>attachCopy(pre,()=>pre.querySelector('code')?.textContent??''));
407
- document.querySelectorAll('.home-install').forEach(el=>attachCopy(el,()=>el.querySelector('code')?.textContent??''));
408
- const tocLinks=document.querySelectorAll('.toc a');
409
- 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))}
410
- </script>
411
- </body>
412
- </html>