@capagents/forgeqe 1.1.2 → 1.1.4
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/HOW_TO_USE.md +5 -5
- package/README.md +8 -4
- package/browserstack.example.yaml +14 -0
- package/docs/security-data-flow.html +154 -86
- package/docs/user-guide.html +305 -131
- package/forgeqe.example.yaml +12 -6
- package/package.json +4 -2
- package/py/forgeqe_engine/browser.py +78 -11
- package/py/forgeqe_engine/service.py +13 -0
- package/src/auth/signin.ts +2 -2
- package/src/bi.ts +338 -243
- package/src/capabilities/guide.ts +322 -140
- package/src/capabilities/registry.ts +3 -3
- package/src/cli/help.ts +16 -7
- package/src/cli/index.ts +51 -9
- package/src/config.ts +115 -12
- package/src/heal/loop.ts +3 -1
- package/src/init.ts +18 -0
- package/src/mcp/tools.ts +26 -4
- package/src/monitor/run.ts +3 -1
- package/src/run.ts +9 -2
- package/src/suite/run.ts +3 -1
- package/testmu.example.yaml +13 -0
|
@@ -15,6 +15,9 @@ import { describeRequirement } from "./status.ts"
|
|
|
15
15
|
const root = path.resolve(import.meta.dir, "..", "..")
|
|
16
16
|
export const GUIDE_FILE = path.join(root, "docs", "user-guide.html")
|
|
17
17
|
const THEME_SOURCE = path.join(root, "docs", "security-data-flow.html")
|
|
18
|
+
const GUIDE_LOGO_LIGHT_FILE = path.join(root, "assets", "forgeqe-logo.png")
|
|
19
|
+
const GUIDE_LOGO_DARK_FILE = path.join(root, "assets", "forgeqe-logo-white.png")
|
|
20
|
+
const PARTNER_LOGO_FILE = path.join(root, "assets", "capgemini-logo.svg")
|
|
18
21
|
|
|
19
22
|
/** Chapters that are not a capability area: which HOW_TO_USE sections they hold, in order. */
|
|
20
23
|
const START: DocRef[] = ["What you need to run", "Quick start", "1. Install", "2. Scaffold config"].map((heading) => ({ doc: "HOW_TO_USE.md", heading }))
|
|
@@ -44,9 +47,11 @@ function sharedLook() {
|
|
|
44
47
|
const page = readFileSync(THEME_SOURCE, "utf8")
|
|
45
48
|
const tokens = page.match(/\/\* =+ tokens =+ \*\/[\s\S]*?(?=\/\* =+ base =+ \*\/)/)?.[0]
|
|
46
49
|
const favicon = page.match(/<link rel="icon"[^>]*>/)?.[0]
|
|
47
|
-
const logo =
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
const logo = `data:image/png;base64,${readFileSync(GUIDE_LOGO_LIGHT_FILE).toString("base64")}`
|
|
51
|
+
const logoDark = `data:image/png;base64,${readFileSync(GUIDE_LOGO_DARK_FILE).toString("base64")}`
|
|
52
|
+
const partnerLogo = `data:image/svg+xml;base64,${Buffer.from(readFileSync(PARTNER_LOGO_FILE, "utf8")).toString("base64")}`
|
|
53
|
+
if (!tokens || !favicon) throw new Error(`${THEME_SOURCE} no longer has its tokens block or favicon where the guide reads them.`)
|
|
54
|
+
return { tokens: tokens.trim(), favicon, logo, logoDark, partnerLogo }
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
/** Which section renders where: the first place that names it; later places link to it. */
|
|
@@ -175,8 +180,25 @@ export function renderGuide(): string {
|
|
|
175
180
|
{ id: "reference", title: "Reference", note: "MCP, tuning, logs, environment variables, and every command", body: ids(REFERENCE).map((id) => docBlock(id, sections, placement, 3)).join("\n") },
|
|
176
181
|
]
|
|
177
182
|
|
|
178
|
-
const
|
|
179
|
-
.
|
|
183
|
+
const railGroups = [
|
|
184
|
+
{ label: "Guide", items: chapters.filter((c) => ["overview", "get-started", "using"].includes(c.id)) },
|
|
185
|
+
{ label: "Capability areas", items: chapters.filter((c) => c.id.startsWith("area-")) },
|
|
186
|
+
{ label: "Reference", items: chapters.filter((c) => c.id === "reference") },
|
|
187
|
+
]
|
|
188
|
+
.filter((g) => g.items.length > 0)
|
|
189
|
+
.map((g) => [
|
|
190
|
+
`<section class="rail-group">`,
|
|
191
|
+
`<h2 class="rail-title mono">${esc(g.label)}</h2>`,
|
|
192
|
+
`<ol class="chapters">`,
|
|
193
|
+
g.items
|
|
194
|
+
.map((c) => {
|
|
195
|
+
const n = String(chapters.indexOf(c) + 1).padStart(2, "0")
|
|
196
|
+
return `<li><a href="#${c.id}"><span class="n">${n}</span><span class="t">${esc(c.title)}</span><span class="d">${esc(c.note)}</span></a></li>`
|
|
197
|
+
})
|
|
198
|
+
.join("\n"),
|
|
199
|
+
`</ol>`,
|
|
200
|
+
`</section>`,
|
|
201
|
+
].join("\n"))
|
|
180
202
|
.join("\n")
|
|
181
203
|
|
|
182
204
|
return `<!DOCTYPE html>
|
|
@@ -191,7 +213,7 @@ export function renderGuide(): string {
|
|
|
191
213
|
${look.favicon}
|
|
192
214
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
193
215
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
194
|
-
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=
|
|
216
|
+
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
|
195
217
|
<style>
|
|
196
218
|
${look.tokens}
|
|
197
219
|
${GUIDE_CSS}
|
|
@@ -200,23 +222,39 @@ ${GUIDE_CSS}
|
|
|
200
222
|
<body>
|
|
201
223
|
<a class="skip" href="#panel">Skip to the guide</a>
|
|
202
224
|
<div id="app">
|
|
203
|
-
<
|
|
204
|
-
<div class="mark"><img src="${look.logo}" alt=""><b>ForgeQE</b></div>
|
|
205
|
-
<span class="sep" aria-hidden="true"></span>
|
|
206
|
-
<div class="ttl"><h1>User guide</h1><span class="sub">How to use ForgeQE, and every feature in detail</span></div>
|
|
207
|
-
<div class="right"><button class="theme" type="button" aria-label="Switch theme" title="Switch theme">${SUN}${MOON}</button></div>
|
|
208
|
-
</header>
|
|
225
|
+
<div class="shell">
|
|
209
226
|
<nav class="rail" aria-label="Chapters">
|
|
210
|
-
<div class="
|
|
211
|
-
<
|
|
212
|
-
${
|
|
213
|
-
|
|
227
|
+
<div class="rail-inner">
|
|
228
|
+
<div class="side-brand">
|
|
229
|
+
<div class="mark"><img class="logo light" src="${look.logo}" alt="ForgeQE AI"><img class="logo dark" src="${look.logoDark}" alt="" aria-hidden="true"></div>
|
|
230
|
+
<label class="search-wrap" for="rail-search"><span class="search-icon" aria-hidden="true">⌕</span><input id="rail-search" class="rail-search" type="search" placeholder="Search sections" aria-label="Search sections"></label>
|
|
231
|
+
</div>
|
|
232
|
+
${railGroups}
|
|
233
|
+
</div>
|
|
214
234
|
</nav>
|
|
235
|
+
<header class="mast">
|
|
236
|
+
<nav class="tabs" aria-label="Guide views"><span class="tab is-active" aria-current="page">Docs</span><button class="tab" type="button" disabled>Changelog</button></nav>
|
|
237
|
+
<div class="right"><img class="partner-logo" src="${look.partnerLogo}" alt="Capgemini"><button class="theme" type="button" aria-label="Switch theme" title="Switch theme">${SUN}${MOON}</button></div>
|
|
238
|
+
</header>
|
|
215
239
|
<main class="panel" id="panel" tabindex="-1">
|
|
216
240
|
<div class="page">
|
|
241
|
+
<header class="pagehead">
|
|
242
|
+
<nav class="crumbs" aria-label="Breadcrumb"><a href="#overview">Docs</a><span aria-hidden="true">/</span><span aria-current="page">User guide</span></nav>
|
|
243
|
+
<span class="kicker mono">ForgeQE guide</span>
|
|
244
|
+
<h1>User guide</h1>
|
|
245
|
+
<p>Install ForgeQE, learn the shell, and find every capability with its requirements, prompts, and limits in one place.</p>
|
|
246
|
+
</header>
|
|
217
247
|
${chapters.map((c, i) => chapter(i + 1, c)).join("\n")}
|
|
218
248
|
</div>
|
|
219
249
|
</main>
|
|
250
|
+
<aside class="toc" aria-label="On this page">
|
|
251
|
+
<div class="toc-box">
|
|
252
|
+
<span class="toc-kicker mono">On this page</span>
|
|
253
|
+
<p class="toc-current" id="toc-current">Overview</p>
|
|
254
|
+
<ol class="toc-links" id="toc-links"></ol>
|
|
255
|
+
</div>
|
|
256
|
+
</aside>
|
|
257
|
+
</div>
|
|
220
258
|
</div>
|
|
221
259
|
<script>
|
|
222
260
|
${GUIDE_JS}
|
|
@@ -229,175 +267,248 @@ ${GUIDE_JS}
|
|
|
229
267
|
const SUN = `<svg class="sun" viewBox="0 0 16 16" aria-hidden="true"><circle cx="8" cy="8" r="3" fill="none" stroke="currentColor" stroke-width="1.4"/><path d="M8 1v2M8 13v2M1 8h2M13 8h2M3 3l1.4 1.4M11.6 11.6 13 13M3 13l1.4-1.4M11.6 4.4 13 3" stroke="currentColor" stroke-width="1.4"/></svg>`
|
|
230
268
|
const MOON = `<svg class="moon" viewBox="0 0 16 16" aria-hidden="true"><path d="M13 10.2A5.5 5.5 0 0 1 5.8 3a5.5 5.5 0 1 0 7.2 7.2Z" fill="none" stroke="currentColor" stroke-width="1.4"/></svg>`
|
|
231
269
|
|
|
232
|
-
/**
|
|
270
|
+
/** A docs-style shell for the generated guide, using the shared documentation tokens and logo. */
|
|
233
271
|
const GUIDE_CSS = `
|
|
234
272
|
/* ============ base ============ */
|
|
235
273
|
*{box-sizing:border-box}
|
|
236
274
|
html,body{height:100%}
|
|
237
275
|
html{-webkit-text-size-adjust:100%}
|
|
238
|
-
|
|
276
|
+
:root{
|
|
277
|
+
--sans:'Plus Jakarta Sans',ui-sans-serif,'Segoe UI',Arial,sans-serif;
|
|
278
|
+
--display:'Plus Jakarta Sans',ui-sans-serif,'Segoe UI',Arial,sans-serif;
|
|
279
|
+
--mono:'Plus Jakarta Sans',ui-sans-serif,'Segoe UI',Arial,sans-serif;
|
|
280
|
+
--guide-bg:#F8FAFC;
|
|
281
|
+
--guide-panel:#FFFFFF;
|
|
282
|
+
--guide-panel-2:#FCFDFE;
|
|
283
|
+
--guide-line:#E2E8F0;
|
|
284
|
+
--guide-text:#020617;
|
|
285
|
+
--guide-muted:#475569;
|
|
286
|
+
--guide-soft:#F1F5F9;
|
|
287
|
+
--guide-accent:#0369A1;
|
|
288
|
+
}
|
|
289
|
+
:root[data-theme="dark"]{
|
|
290
|
+
--guide-bg:#08111F;
|
|
291
|
+
--guide-panel:#0E1726;
|
|
292
|
+
--guide-panel-2:#101B2C;
|
|
293
|
+
--guide-line:#22324A;
|
|
294
|
+
--guide-text:#E8EEF8;
|
|
295
|
+
--guide-muted:#9FB0C7;
|
|
296
|
+
--guide-soft:#132034;
|
|
297
|
+
--guide-accent:#60A5FA;
|
|
298
|
+
}
|
|
299
|
+
@media (prefers-color-scheme:dark){
|
|
300
|
+
:root:not([data-theme="light"]){
|
|
301
|
+
--guide-bg:#08111F;
|
|
302
|
+
--guide-panel:#0E1726;
|
|
303
|
+
--guide-panel-2:#101B2C;
|
|
304
|
+
--guide-line:#22324A;
|
|
305
|
+
--guide-text:#E8EEF8;
|
|
306
|
+
--guide-muted:#9FB0C7;
|
|
307
|
+
--guide-soft:#132034;
|
|
308
|
+
--guide-accent:#60A5FA;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
body{margin:0;background:var(--guide-bg);color:var(--guide-text);font-family:var(--sans);font-size:13.5px;line-height:1.65;-webkit-font-smoothing:antialiased}
|
|
239
312
|
button{font:inherit;color:inherit}
|
|
240
|
-
:focus-visible{outline:2px solid var(--
|
|
241
|
-
code{font-family:var(--codefont);font-size:.
|
|
313
|
+
:focus-visible{outline:2px solid var(--guide-accent);outline-offset:2px}
|
|
314
|
+
code{font-family:var(--codefont);font-size:.92em;font-weight:500;background:var(--guide-panel);color:var(--guide-text);padding:2px 7px;border:1px solid var(--guide-line);border-radius:8px;white-space:nowrap}
|
|
242
315
|
p{margin:0}
|
|
243
|
-
h2,h3{margin:0}
|
|
244
|
-
a{color:var(--
|
|
245
|
-
a:hover{text-decoration-color:var(--
|
|
246
|
-
.muted{color:var(--muted)}
|
|
247
|
-
.mono{font-family:var(--mono);font-size:10px;letter-spacing:.09em;text-transform:uppercase;font-weight:
|
|
248
|
-
.skip{position:absolute;left:-9999px;top:8px;z-index:20;background:var(--
|
|
316
|
+
h1,h2,h3{margin:0}
|
|
317
|
+
a{color:var(--guide-accent);text-decoration:underline;text-decoration-color:color-mix(in srgb,var(--guide-accent) 35%,transparent);text-underline-offset:2px}
|
|
318
|
+
a:hover{text-decoration-color:var(--guide-accent)}
|
|
319
|
+
.muted{color:var(--guide-muted)}
|
|
320
|
+
.mono{font-family:var(--mono);font-size:10px;letter-spacing:.09em;text-transform:uppercase;font-weight:700}
|
|
321
|
+
.skip{position:absolute;left:-9999px;top:8px;z-index:20;background:var(--guide-panel);color:var(--guide-text);padding:6px 10px;border:1px solid var(--guide-line)}
|
|
249
322
|
.skip:focus{left:8px}
|
|
250
323
|
|
|
251
324
|
/* ============ shell ============ */
|
|
252
|
-
#app{height:100vh;height:100dvh
|
|
253
|
-
.mast{grid-column:1
|
|
254
|
-
.mark{display:flex;align-items:center;
|
|
255
|
-
.mark
|
|
256
|
-
.mark
|
|
257
|
-
.
|
|
258
|
-
.
|
|
259
|
-
.
|
|
260
|
-
.
|
|
325
|
+
#app{height:100vh;height:100dvh}
|
|
326
|
+
.mast{grid-column:2 / 4;grid-row:1;display:flex;align-items:center;justify-content:space-between;gap:18px;height:52px;padding:0 24px;background:var(--guide-panel);border-bottom:1px solid var(--guide-line)}
|
|
327
|
+
.mark{display:flex;align-items:center;flex:none}
|
|
328
|
+
.mark .logo{display:block;height:36px;width:auto;max-width:196px}
|
|
329
|
+
.mark .logo.dark{display:none}
|
|
330
|
+
.tabs{display:flex;align-items:center;gap:16px}
|
|
331
|
+
.tab{border:0;background:transparent;color:var(--guide-muted);padding:0 0 12px;border-radius:0;font-size:12px;font-weight:600;line-height:1;cursor:default;border-bottom:1px solid transparent}
|
|
332
|
+
.tab.is-active{color:var(--guide-text);box-shadow:none;border-bottom-color:var(--guide-accent)}
|
|
333
|
+
.tab:disabled{opacity:.7}
|
|
261
334
|
.mast .right{margin-left:auto;display:flex;align-items:center;gap:14px;flex:none}
|
|
262
|
-
.
|
|
263
|
-
.theme
|
|
264
|
-
.
|
|
335
|
+
.partner-logo{display:block;height:20px;width:auto;opacity:.98}
|
|
336
|
+
.theme{display:grid;place-items:center;width:34px;height:34px;border:1px solid var(--guide-line);background:var(--guide-panel);cursor:pointer;border-radius:12px;color:var(--guide-text)}
|
|
337
|
+
.theme:hover{border-color:color-mix(in srgb,var(--guide-accent) 35%,var(--guide-line));background:var(--guide-soft)}
|
|
265
338
|
.theme svg{width:14px;height:14px}
|
|
266
339
|
.theme .sun{display:none}
|
|
340
|
+
:root[data-theme="dark"] .mark .logo.light{display:none}
|
|
341
|
+
:root[data-theme="dark"] .mark .logo.dark{display:block}
|
|
267
342
|
:root[data-theme="dark"] .theme .sun{display:block}
|
|
268
343
|
:root[data-theme="dark"] .theme .moon{display:none}
|
|
269
344
|
@media (prefers-color-scheme:dark){
|
|
345
|
+
:root:not([data-theme="light"]) .mark .logo.light{display:none}
|
|
346
|
+
:root:not([data-theme="light"]) .mark .logo.dark{display:block}
|
|
270
347
|
:root:not([data-theme="light"]) .theme .sun{display:block}
|
|
271
348
|
:root:not([data-theme="light"]) .theme .moon{display:none}
|
|
272
349
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
.rail
|
|
277
|
-
.
|
|
278
|
-
.
|
|
279
|
-
.
|
|
280
|
-
.
|
|
281
|
-
.
|
|
282
|
-
.
|
|
283
|
-
.
|
|
284
|
-
.
|
|
285
|
-
.
|
|
286
|
-
.
|
|
287
|
-
.
|
|
350
|
+
.shell{height:100%;min-height:0;display:grid;grid-template-columns:214px minmax(0,1fr) 188px;grid-template-rows:auto minmax(0,1fr);gap:0}
|
|
351
|
+
|
|
352
|
+
/* left rail */
|
|
353
|
+
.rail,.toc{min-height:0;overflow:auto}
|
|
354
|
+
.rail{grid-column:1;grid-row:1 / 3;background:var(--guide-panel);border-right:1px solid var(--guide-line)}
|
|
355
|
+
.rail-inner{padding:14px 14px 28px}
|
|
356
|
+
.side-brand{display:flex;flex-direction:column;gap:18px;margin-bottom:18px;padding:8px 6px 4px}
|
|
357
|
+
.side-brand-copy .eyebrow{color:var(--guide-accent)}
|
|
358
|
+
.search-wrap{display:flex;align-items:center;gap:8px;height:36px;padding:0 10px;background:var(--guide-panel);border:1px solid var(--guide-line);border-radius:10px}
|
|
359
|
+
.search-icon{font-size:14px;line-height:1;color:#94A3B8}
|
|
360
|
+
.rail-search{width:100%;border:0;background:transparent;padding:0;font:inherit;color:var(--guide-text)}
|
|
361
|
+
.rail-search::placeholder{color:#94A3B8}
|
|
362
|
+
.rail-search:focus{outline:0}
|
|
363
|
+
.rail-group+.rail-group{margin-top:20px}
|
|
364
|
+
.rail-title{margin:0 0 10px;color:var(--guide-muted);font-size:9.5px}
|
|
365
|
+
.chapters{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
|
|
366
|
+
.chapters li+li{margin-top:2px}
|
|
367
|
+
.chapters a{position:relative;display:grid;grid-template-columns:22px minmax(0,1fr);gap:0 8px;padding:6px 8px 6px 12px;border-radius:8px;text-decoration:none;color:var(--guide-muted);transition:background-color .18s ease}
|
|
368
|
+
.chapters .n{font-family:var(--mono);font-size:10px;padding-top:2px;color:#94A3B8}
|
|
369
|
+
.chapters .t{font-weight:500;font-size:12px;line-height:1.35;color:var(--guide-muted)}
|
|
370
|
+
.chapters .d{display:none}
|
|
371
|
+
.chapters a::before{content:"";position:absolute;left:0;top:7px;bottom:7px;width:2px;border-radius:999px;background:var(--guide-accent);transform:scaleY(0);transform-origin:top;transition:transform .18s ease}
|
|
372
|
+
.chapters a:hover{background:var(--guide-panel-2)}
|
|
373
|
+
.chapters a:hover .t{color:var(--guide-text)}
|
|
374
|
+
.chapters a[aria-current]{background:transparent;box-shadow:none}
|
|
375
|
+
.chapters a[aria-current] .t,.chapters a[aria-current] .n{color:var(--guide-text);font-weight:600}
|
|
288
376
|
.chapters a[aria-current]::before{transform:scaleY(1)}
|
|
289
|
-
|
|
377
|
+
|
|
378
|
+
/* right toc */
|
|
379
|
+
.toc{grid-column:3;grid-row:2;padding:14px 16px 20px;background:transparent;border-left:1px solid var(--guide-line)}
|
|
380
|
+
.toc-box{position:sticky;top:0;display:flex;flex-direction:column;gap:10px;padding:6px 0 0;background:transparent;border:0;border-radius:0;box-shadow:none}
|
|
381
|
+
.toc-kicker{color:var(--guide-muted)}
|
|
382
|
+
.toc-current{font-weight:700;font-size:13px;line-height:1.35;color:var(--guide-text)}
|
|
383
|
+
.toc-links{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
|
|
384
|
+
.toc-links a{display:block;padding:4px 0 4px 10px;border-left:2px solid transparent;font-size:11.5px;line-height:1.45;color:var(--guide-muted);text-decoration:none}
|
|
385
|
+
.toc-links a:hover{color:var(--guide-text)}
|
|
386
|
+
.toc-links a[aria-current]{border-left-color:var(--guide-accent);color:var(--guide-text);font-weight:600}
|
|
290
387
|
|
|
291
388
|
/* content */
|
|
292
|
-
.panel{grid-row:2;min-width:0;min-height:0;overflow:auto;padding:
|
|
293
|
-
.page{max-width:
|
|
294
|
-
.
|
|
295
|
-
.
|
|
296
|
-
.
|
|
297
|
-
.
|
|
298
|
-
.
|
|
389
|
+
.panel{grid-column:2;grid-row:2;min-width:0;min-height:0;overflow:auto;padding:0 16px 40px;scroll-behavior:smooth}
|
|
390
|
+
.page{max-width:980px;margin:0 auto;display:flex;flex-direction:column;gap:56px;padding:28px 24px 28vh;background:transparent;border:0;border-radius:0;box-shadow:none}
|
|
391
|
+
.pagehead{display:flex;flex-direction:column;gap:12px;padding:2px 0 4px}
|
|
392
|
+
.crumbs{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--guide-muted)}
|
|
393
|
+
.crumbs a{text-decoration:none;color:var(--guide-accent);font-weight:600}
|
|
394
|
+
.crumbs span[aria-current="page"]{color:var(--guide-muted)}
|
|
395
|
+
.pagehead .kicker{color:var(--guide-accent)}
|
|
396
|
+
.pagehead h1{font-family:var(--display);font-weight:800;font-size:clamp(34px,3.2vw,46px);line-height:1;letter-spacing:-.035em;color:var(--guide-text)}
|
|
397
|
+
.pagehead p{max-width:60ch;color:var(--guide-muted);font-size:15px;line-height:1.72}
|
|
398
|
+
.chapter{display:flex;flex-direction:column;gap:28px;scroll-margin-top:20px}
|
|
399
|
+
.chead{display:flex;flex-direction:column;gap:7px;padding-bottom:16px;border-bottom:1px solid var(--guide-line)}
|
|
400
|
+
.chead .mono{color:var(--guide-accent)}
|
|
401
|
+
.chead h2{font-family:var(--display);font-weight:750;font-size:30px;line-height:1.06;letter-spacing:-.03em;color:var(--guide-text)}
|
|
402
|
+
.chead p{color:var(--guide-muted);font-size:14.5px;max-width:58ch}
|
|
299
403
|
|
|
300
404
|
/* overview */
|
|
301
|
-
.lead{font-size:
|
|
302
|
-
.band-title{font-family:var(--display);font-weight:700;font-size:
|
|
303
|
-
.area{display:grid;grid-template-columns:
|
|
304
|
-
.area-name{text-decoration:none;color
|
|
405
|
+
.lead{font-size:14.75px;line-height:1.78;color:var(--guide-muted)}
|
|
406
|
+
.band-title{font-family:var(--display);font-weight:700;font-size:19px;line-height:1.15;margin-top:12px;color:var(--guide-text)}
|
|
407
|
+
.area{display:grid;grid-template-columns:150px minmax(0,1fr);gap:12px 18px;border-top:1px solid var(--guide-line);padding-top:16px}
|
|
408
|
+
.area-name{text-decoration:none;color:#0F766E;padding-top:4px}
|
|
305
409
|
.area-name:hover{text-decoration:underline;text-underline-offset:3px}
|
|
306
|
-
.tiles{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:
|
|
307
|
-
.tile{display:flex;flex-direction:column;gap:
|
|
308
|
-
.tile b{font-size:
|
|
309
|
-
.tile span{color:var(--muted);font-size:
|
|
310
|
-
.tile:hover{border-color:var(--
|
|
311
|
-
|
|
312
|
-
/* feature
|
|
313
|
-
.spec{background:var(--
|
|
314
|
-
.spec>.hd{display:flex;align-items:
|
|
315
|
-
.spec>.hd .mono{color
|
|
316
|
-
.spec>.hd h3{font-family:var(--display);font-weight:700;font-size:
|
|
317
|
-
.spec>.ds{padding:
|
|
318
|
-
.facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:
|
|
410
|
+
.tiles{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:10px}
|
|
411
|
+
.tile{display:flex;flex-direction:column;gap:4px;height:100%;background:var(--guide-panel);border:1px solid var(--guide-line);border-radius:16px;padding:14px 15px;text-decoration:none;color:var(--guide-text);box-shadow:0 10px 26px rgba(15,23,42,.04)}
|
|
412
|
+
.tile b{font-size:13px;font-weight:700}
|
|
413
|
+
.tile span{color:var(--guide-muted);font-size:12px;line-height:1.45}
|
|
414
|
+
.tile:hover{border-color:color-mix(in srgb,var(--guide-accent) 22%,var(--guide-line));background:var(--guide-panel-2)}
|
|
415
|
+
|
|
416
|
+
/* feature cards */
|
|
417
|
+
.spec{background:var(--guide-panel);border:1px solid var(--guide-line);border-radius:18px;display:flex;flex-direction:column;scroll-margin-top:16px;overflow:hidden;box-shadow:0 12px 32px rgba(15,23,42,.05)}
|
|
418
|
+
.spec>.hd{display:flex;align-items:center;gap:10px;padding:16px 20px 12px;border-bottom:1px solid var(--guide-line)}
|
|
419
|
+
.spec>.hd .mono{color:#0F766E}
|
|
420
|
+
.spec>.hd h3{font-family:var(--display);font-weight:700;font-size:18px;line-height:1.15;color:var(--guide-text)}
|
|
421
|
+
.spec>.ds{padding:12px 22px 16px;color:var(--guide-muted);font-size:14px;line-height:1.7}
|
|
422
|
+
.facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px 28px;padding:18px 22px 20px;border-top:1px solid var(--guide-line);background:var(--guide-panel-2)}
|
|
319
423
|
.fact{display:flex;flex-direction:column;gap:6px;min-width:0}
|
|
320
|
-
.fact>.mono{color:var(--muted)}
|
|
424
|
+
.fact>.mono{color:var(--guide-muted);font-size:9.5px}
|
|
321
425
|
.asks,.needs,.plainlist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}
|
|
322
|
-
.asks li{border-left:
|
|
323
|
-
.needs li{display:grid;grid-template-columns:
|
|
324
|
-
.need{justify-self:start;display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;padding:1px
|
|
426
|
+
.asks li{border-left:2px solid var(--guide-accent);padding:4px 0 4px 10px;font-size:13px;color:var(--guide-text);line-height:1.6}
|
|
427
|
+
.needs li{display:grid;grid-template-columns:92px minmax(0,1fr);gap:10px;align-items:baseline;font-size:12.75px;line-height:1.6}
|
|
428
|
+
.need{justify-self:start;display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);font-size:9.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;padding:1px 7px 1px 6px;border:1px solid currentColor;border-radius:999px;line-height:1.5;white-space:nowrap;color:var(--guide-muted);background:var(--guide-panel)}
|
|
325
429
|
.need::before{content:"";width:5px;height:5px;background:currentColor;flex:none}
|
|
326
|
-
.need.opt{border-style:dashed;color:var(--muted)}
|
|
430
|
+
.need.opt{border-style:dashed;color:var(--guide-muted)}
|
|
327
431
|
.need.opt::before{background:none;border:1px solid currentColor;width:4px;height:4px}
|
|
328
|
-
.need.input{color:var(--muted);background:var(--
|
|
329
|
-
.plainlist li{font-size:12.
|
|
432
|
+
.need.input{color:var(--guide-muted);background:var(--guide-soft)}
|
|
433
|
+
.plainlist li{font-size:12.4px}
|
|
330
434
|
.tools{display:flex;flex-wrap:wrap;gap:6px}
|
|
331
|
-
.detail{padding:
|
|
332
|
-
.detail>.mono{color:var(--muted)}
|
|
333
|
-
|
|
334
|
-
/*
|
|
335
|
-
.doc{display:flex;flex-direction:column;gap:
|
|
336
|
-
.doc>:is(h3,h4){font-family:var(--display);font-weight:700;font-size:
|
|
337
|
-
.doc.sub{margin-top:8px;padding-top:
|
|
338
|
-
.doc.sub>:is(h4,h5){font-family:var(--display);font-weight:700;font-size:
|
|
339
|
-
.chapter>.doc+.doc{padding-top:
|
|
340
|
-
.see{color:var(--muted);font-size:12.25px}
|
|
341
|
-
.prose{font-size:
|
|
435
|
+
.detail{padding:20px 22px 22px;border-top:1px solid var(--guide-line);display:flex;flex-direction:column;gap:20px}
|
|
436
|
+
.detail>.mono{color:var(--guide-muted)}
|
|
437
|
+
|
|
438
|
+
/* prose */
|
|
439
|
+
.doc{display:flex;flex-direction:column;gap:12px;scroll-margin-top:16px}
|
|
440
|
+
.doc>:is(h3,h4){font-family:var(--display);font-weight:700;font-size:21px;line-height:1.15;margin:0;letter-spacing:-.02em;color:var(--guide-text)}
|
|
441
|
+
.doc.sub{margin-top:8px;padding-top:12px;border-top:1px dashed var(--guide-line)}
|
|
442
|
+
.doc.sub>:is(h4,h5){font-family:var(--display);font-weight:700;font-size:16px;margin:0;color:var(--guide-text)}
|
|
443
|
+
.chapter>.doc+.doc{padding-top:28px;border-top:1px solid var(--guide-line)}
|
|
444
|
+
.see{color:var(--guide-muted);font-size:12.25px}
|
|
445
|
+
.prose{font-size:15px;line-height:1.9;color:var(--guide-muted)}
|
|
342
446
|
.prose :where(p,ul,ol,pre,blockquote){margin:0}
|
|
343
|
-
.prose>*+*{margin-top:
|
|
344
|
-
.prose ul,.prose ol{padding-left:
|
|
345
|
-
.prose li+li{margin-top:
|
|
346
|
-
.prose strong{color:var(--
|
|
347
|
-
.prose h5,.prose h6{font-family:var(--display);font-weight:700;font-size:
|
|
447
|
+
.prose>*+*{margin-top:16px}
|
|
448
|
+
.prose ul,.prose ol{padding-left:22px}
|
|
449
|
+
.prose li+li{margin-top:8px}
|
|
450
|
+
.prose strong{color:var(--guide-text)}
|
|
451
|
+
.prose h5,.prose h6{font-family:var(--display);font-weight:700;font-size:15px;color:var(--guide-text);margin:18px 0 0}
|
|
348
452
|
.prose code{white-space:normal;overflow-wrap:anywhere}
|
|
349
|
-
.prose pre{margin:0;padding:
|
|
350
|
-
.prose pre code{background:none;border:0;padding:0;font-size:inherit;white-space:pre;overflow-wrap:normal}
|
|
351
|
-
.prose hr{border:0;border-top:1px solid var(--
|
|
352
|
-
.prose blockquote{margin:0;padding-left:
|
|
353
|
-
.tbl{overflow-x:auto;border:1px solid var(--
|
|
354
|
-
.tbl table{border-collapse:
|
|
355
|
-
.tbl th,.tbl td{text-align:left;vertical-align:top;padding:
|
|
356
|
-
.tbl th{background:var(--
|
|
357
|
-
.tbl tr:
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
.
|
|
453
|
+
.prose pre{margin:0;padding:16px 18px;overflow-x:auto;background:linear-gradient(180deg,#152033,#0C1422);color:#F8FBFF;border:1px solid #22314A;border-radius:16px;font-family:var(--codefont);font-size:13px;line-height:1.75;box-shadow:inset 0 1px 0 color-mix(in srgb,#fff 10%,transparent),0 1px 0 rgba(15,23,42,.12);tab-size:2}
|
|
454
|
+
.prose pre code{display:block;background:none;border:0;padding:0;font-size:inherit;white-space:pre;overflow-wrap:normal;color:inherit}
|
|
455
|
+
.prose hr{border:0;border-top:1px solid var(--guide-line)}
|
|
456
|
+
.prose blockquote{margin:0;padding-left:14px;border-left:3px solid var(--guide-accent);color:var(--guide-muted)}
|
|
457
|
+
.tbl{overflow-x:auto;border:1px solid var(--guide-line);border-radius:16px;background:var(--guide-panel);box-shadow:0 10px 28px rgba(15,23,42,.04)}
|
|
458
|
+
.tbl table{border-collapse:separate;border-spacing:0;width:100%;font-size:13px;line-height:1.65}
|
|
459
|
+
.tbl th,.tbl td{text-align:left;vertical-align:top;padding:12px 16px;border-bottom:1px solid var(--guide-line)}
|
|
460
|
+
.tbl th{background:var(--guide-soft);color:var(--guide-muted);font-weight:700;font-size:10px;letter-spacing:.08em;text-transform:uppercase}
|
|
461
|
+
.tbl tbody tr:nth-child(even) td{background:var(--guide-panel-2)}
|
|
462
|
+
.tbl tbody tr:hover td{background:color-mix(in srgb,var(--guide-panel-2) 78%,var(--guide-soft))}
|
|
463
|
+
.tbl td code{font-size:.85em}
|
|
464
|
+
|
|
465
|
+
/* responsive */
|
|
466
|
+
@media (max-width:1180px){
|
|
467
|
+
.shell{grid-template-columns:214px minmax(0,1fr);grid-template-rows:auto minmax(0,1fr)}
|
|
468
|
+
.mast{grid-column:2;grid-row:1}
|
|
469
|
+
.toc{display:none}
|
|
470
|
+
}
|
|
471
|
+
@media (max-width:900px){
|
|
472
|
+
.shell{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);gap:14px;padding:0}
|
|
473
|
+
.rail{grid-column:1;grid-row:1;overflow:visible;border-right:0;border-bottom:1px solid var(--guide-line)}
|
|
474
|
+
.mast{grid-column:1;grid-row:2}
|
|
475
|
+
.rail-inner{padding:12px 14px}
|
|
476
|
+
.rail-group+.rail-group{margin-top:14px}
|
|
364
477
|
.chapters{flex-direction:row;overflow-x:auto;scrollbar-width:none;padding:0}
|
|
365
478
|
.chapters::-webkit-scrollbar{display:none}
|
|
366
479
|
.chapters li{flex:none}
|
|
367
|
-
.chapters a{grid-template-columns:auto auto;gap:6px;
|
|
368
|
-
.chapters
|
|
369
|
-
.chapters
|
|
370
|
-
.chapters a::before{left:0;right:0;top:auto;bottom:0;width:auto;height:3px;transform:scaleX(0);transform-origin:left}
|
|
480
|
+
.chapters a{grid-template-columns:auto auto;gap:6px;padding:9px 12px}
|
|
481
|
+
.chapters .n{padding-top:1px}
|
|
482
|
+
.chapters a::before{left:10px;right:10px;top:auto;bottom:0;width:auto;height:2px;transform:scaleX(0);transform-origin:left}
|
|
371
483
|
.chapters a[aria-current]::before{transform:scaleX(1)}
|
|
372
|
-
.panel{grid-row:3;padding:
|
|
373
|
-
.
|
|
484
|
+
.panel{grid-column:1;grid-row:3;padding:0 14px 32px}
|
|
485
|
+
.page{padding:24px 10px 24vh;border-radius:0}
|
|
486
|
+
.tabs{margin-left:auto}
|
|
374
487
|
.facts{grid-template-columns:minmax(0,1fr)}
|
|
375
488
|
.area{grid-template-columns:minmax(0,1fr)}
|
|
376
489
|
}
|
|
377
490
|
@media (max-width:640px){
|
|
378
|
-
.mast{padding:
|
|
379
|
-
.
|
|
380
|
-
.
|
|
381
|
-
.
|
|
382
|
-
.chead h2{font-size:21px}
|
|
491
|
+
.mast{padding:12px 14px;height:auto;flex-wrap:wrap}
|
|
492
|
+
.tabs{order:3;margin-left:0}
|
|
493
|
+
.page{padding:22px 4px 22vh;border-radius:0}
|
|
494
|
+
.pagehead h1,.chead h2{font-size:24px}
|
|
383
495
|
}
|
|
384
496
|
@media (prefers-reduced-motion:reduce){.panel{scroll-behavior:auto}.chapters a::before{transition:none}}
|
|
385
497
|
|
|
386
|
-
/*
|
|
498
|
+
/* print */
|
|
387
499
|
@media print{
|
|
388
500
|
#app{display:block;height:auto}
|
|
389
|
-
.rail,.theme,.skip{display:none}
|
|
501
|
+
.rail,.toc,.theme,.tabs,.skip{display:none}
|
|
390
502
|
.panel{overflow:visible;padding:0}
|
|
391
|
-
.page{max-width:none;padding-
|
|
392
|
-
.mast{background:none;color:var(--
|
|
393
|
-
.mast .sub{color:var(--muted)}
|
|
503
|
+
.page{max-width:none;padding:0;border:0;box-shadow:none;background:none}
|
|
504
|
+
.mast{padding:0 0 12px;background:none;color:var(--guide-text);border-bottom:1px solid var(--guide-text);backdrop-filter:none}
|
|
394
505
|
.spec,.doc{break-inside:auto}
|
|
395
506
|
.chapter{break-before:page}
|
|
396
507
|
.chapter:first-child{break-before:auto}
|
|
397
508
|
}
|
|
398
509
|
`
|
|
399
510
|
|
|
400
|
-
/**
|
|
511
|
+
/** Theme switching, active left rail, and a docs-style "On this page" outline for the current chapter. */
|
|
401
512
|
const GUIDE_JS = `(function () {
|
|
402
513
|
var root = document.documentElement;
|
|
403
514
|
var dark = function () {
|
|
@@ -417,26 +528,91 @@ const GUIDE_JS = `(function () {
|
|
|
417
528
|
|
|
418
529
|
var panel = document.getElementById("panel");
|
|
419
530
|
var links = Array.prototype.slice.call(document.querySelectorAll(".chapters a"));
|
|
531
|
+
var railSearch = document.getElementById("rail-search");
|
|
532
|
+
var railGroups = Array.prototype.slice.call(document.querySelectorAll(".rail-group"));
|
|
533
|
+
var tocCurrent = document.getElementById("toc-current");
|
|
534
|
+
var tocLinks = document.getElementById("toc-links");
|
|
420
535
|
var byId = {};
|
|
421
536
|
links.forEach(function (a) { byId[a.getAttribute("href").slice(1)] = a; });
|
|
422
|
-
var
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
537
|
+
var filterRail = function (term) {
|
|
538
|
+
railGroups.forEach(function (group) {
|
|
539
|
+
var items = Array.prototype.slice.call(group.querySelectorAll(".chapters li"));
|
|
540
|
+
var shown = 0;
|
|
541
|
+
items.forEach(function (item) {
|
|
542
|
+
var a = item.querySelector("a");
|
|
543
|
+
var label = a ? a.textContent.toLowerCase() : "";
|
|
544
|
+
var on = !term || label.indexOf(term) !== -1;
|
|
545
|
+
item.style.display = on ? "" : "none";
|
|
546
|
+
if (on) shown += 1;
|
|
547
|
+
});
|
|
548
|
+
group.style.display = shown ? "" : "none";
|
|
549
|
+
});
|
|
426
550
|
};
|
|
427
551
|
var chapters = Array.prototype.slice.call(document.querySelectorAll(".chapter"));
|
|
552
|
+
var itemText = function (node) {
|
|
553
|
+
var heading = node.querySelector("h3,h4,h5");
|
|
554
|
+
return heading ? heading.textContent.trim() : "";
|
|
555
|
+
};
|
|
556
|
+
var tocItems = function (chapter) {
|
|
557
|
+
return Array.prototype.slice.call(chapter.querySelectorAll("[id^='cap-'],[id^='doc-']")).filter(function (node) { return !!itemText(node); });
|
|
558
|
+
};
|
|
428
559
|
var current = function () {
|
|
429
|
-
var top = panel.getBoundingClientRect().top +
|
|
560
|
+
var top = panel.getBoundingClientRect().top + 72, id = chapters[0].id;
|
|
430
561
|
chapters.forEach(function (c) { if (c.getBoundingClientRect().top <= top) id = c.id; });
|
|
431
562
|
return id;
|
|
432
563
|
};
|
|
564
|
+
var currentItem = function (nodes) {
|
|
565
|
+
if (!nodes.length) return null;
|
|
566
|
+
var top = panel.getBoundingClientRect().top + 116, id = nodes[0].id;
|
|
567
|
+
nodes.forEach(function (node) { if (node.getBoundingClientRect().top <= top) id = node.id; });
|
|
568
|
+
return id;
|
|
569
|
+
};
|
|
570
|
+
var renderToc = function (chapterId) {
|
|
571
|
+
var chapter = document.getElementById(chapterId);
|
|
572
|
+
if (!chapter || !tocLinks || !tocCurrent) return;
|
|
573
|
+
var title = chapter.querySelector(".chead h2");
|
|
574
|
+
tocCurrent.textContent = title ? title.textContent.trim() : "On this page";
|
|
575
|
+
var nodes = tocItems(chapter);
|
|
576
|
+
tocLinks.innerHTML = "";
|
|
577
|
+
nodes.forEach(function (node) {
|
|
578
|
+
var li = document.createElement("li");
|
|
579
|
+
var a = document.createElement("a");
|
|
580
|
+
a.setAttribute("href", "#" + node.id);
|
|
581
|
+
a.textContent = itemText(node);
|
|
582
|
+
li.appendChild(a);
|
|
583
|
+
tocLinks.appendChild(li);
|
|
584
|
+
});
|
|
585
|
+
var itemId = currentItem(nodes);
|
|
586
|
+
Array.prototype.forEach.call(tocLinks.querySelectorAll("a"), function (a) {
|
|
587
|
+
if (itemId && a.getAttribute("href") === "#" + itemId) a.setAttribute("aria-current", "location");
|
|
588
|
+
else a.removeAttribute("aria-current");
|
|
589
|
+
});
|
|
590
|
+
};
|
|
591
|
+
var mark = function (id) {
|
|
592
|
+
links.forEach(function (a) { if (a === byId[id]) a.setAttribute("aria-current", "location"); else a.removeAttribute("aria-current"); });
|
|
593
|
+
var a = byId[id];
|
|
594
|
+
if (a && a.scrollIntoView && window.matchMedia("(max-width:900px)").matches) a.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
595
|
+
renderToc(id);
|
|
596
|
+
};
|
|
597
|
+
var locateChapter = function (id) {
|
|
598
|
+
for (var i = 0; i < chapters.length; i++) {
|
|
599
|
+
var chapter = chapters[i];
|
|
600
|
+
if (chapter.id === id) return chapter.id;
|
|
601
|
+
var safe = window.CSS && CSS.escape ? CSS.escape(id) : id.replace(/[^a-zA-Z0-9_-]/g, "\\$&");
|
|
602
|
+
if (chapter.querySelector("#" + safe)) return chapter.id;
|
|
603
|
+
}
|
|
604
|
+
return current();
|
|
605
|
+
};
|
|
433
606
|
var ticking = false;
|
|
434
607
|
panel.addEventListener("scroll", function () {
|
|
435
608
|
if (ticking) return;
|
|
436
609
|
ticking = true;
|
|
437
610
|
requestAnimationFrame(function () { ticking = false; mark(current()); });
|
|
438
611
|
}, { passive: true });
|
|
439
|
-
|
|
612
|
+
if (railSearch) railSearch.addEventListener("input", function () { filterRail(railSearch.value.trim().toLowerCase()); });
|
|
613
|
+
filterRail("");
|
|
614
|
+
mark(location.hash && document.getElementById(location.hash.slice(1)) ? locateChapter(location.hash.slice(1)) : current());
|
|
615
|
+
|
|
440
616
|
// The browser jumps to a link's section before the fonts arrive, and the text reflows when they do: jump again
|
|
441
617
|
// after each font loads and once the page has, until the reader scrolls themselves.
|
|
442
618
|
var target = location.hash && document.getElementById(location.hash.slice(1));
|
|
@@ -447,9 +623,15 @@ const GUIDE_JS = `(function () {
|
|
|
447
623
|
var settle = function () {
|
|
448
624
|
if (moved) return;
|
|
449
625
|
target.scrollIntoView({ block: "start", behavior: "instant" });
|
|
450
|
-
mark(
|
|
626
|
+
mark(locateChapter(target.id));
|
|
451
627
|
};
|
|
452
628
|
window.addEventListener("load", settle);
|
|
453
629
|
if (document.fonts) document.fonts.addEventListener("loadingdone", settle);
|
|
454
630
|
}
|
|
631
|
+
window.addEventListener("hashchange", function () {
|
|
632
|
+
var id = location.hash.slice(1);
|
|
633
|
+
if (!id) return mark(current());
|
|
634
|
+
mark(locateChapter(id));
|
|
635
|
+
});
|
|
455
636
|
})();`
|
|
637
|
+
|