Skip to content

Commit 552f792

Browse files
authored
refactor(web): derive content from repository sources (#142)
1 parent ff62819 commit 552f792

13 files changed

Lines changed: 1089 additions & 227 deletions
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1-
import { pageMarkdown } from "@/components/docs-markdown";
1+
import { loadDocumentationContent } from "@/lib/repository-content.mjs";
22

33
export default function DocsMarkdownPage() {
4-
return <main className="markdown-shell"><div className="markdown-container"><a href="/docs">← Back to docs</a><pre>{pageMarkdown}</pre></div></main>;
4+
const documentation = loadDocumentationContent();
5+
return (
6+
<main className="markdown-shell">
7+
<div className="markdown-container">
8+
<a href="/docs">← Back to docs</a>
9+
<pre>{documentation.markdown}</pre>
10+
</div>
11+
</main>
12+
);
513
}

‎apps/web/app/docs/page.tsx‎

Lines changed: 81 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,79 +2,136 @@ import { CommandBlock, CopyPageButton } from "@/components/docs-copy-controls";
22
import { HeadlessMark } from "@/components/headless-mark";
33
import { LinkGlyph } from "@/components/link-glyph";
44
import { ThemeToggle } from "@/components/theme-toggle";
5+
import { loadDocumentationContent } from "@/lib/repository-content.mjs";
56
import Link from "next/link";
67

7-
const coreCommands = [
8-
["Navigation", "visit, back, reload, wait", "Move through a real browser session and wait for a URL, page text, or settled state."],
9-
["Interaction", "inspect, click, fill, press, scroll", "Use task-ranked controls and accessibility roles instead of mouse coordinates or selectors."],
10-
["Evidence", "screenshot, record, visual compare, report", "Create private PNG/JPG/PDF, MP4/MOV/WebM/GIF, diff, flow, and PR-report artifacts."],
11-
["Diagnostics", "console, network, styles, cookies, storage", "Investigate only when something fails; sensitive values remain redacted by default."],
12-
];
8+
function plainText(markdown: string) {
9+
return markdown
10+
.replace(/\[([^\]]+)]\([^)]+\)/g, "$1")
11+
.replaceAll("`", "")
12+
.replaceAll("**", "");
13+
}
1314

1415
export default function DocsPage() {
16+
const documentation = loadDocumentationContent();
17+
1518
return (
1619
<main className="docs-shell">
17-
<nav className="docs-nav docs-container" aria-label="Documentation navigation">
18-
<Link className="brand" href="/" aria-label="Headless home"><HeadlessMark className="brand-mark" /><span>headless</span></Link>
19-
<div><Link href="/">Overview</Link><Link className="active" href="/docs">Docs</Link><a className="nav-external" href="https://github.com/LockInTime/headless">GitHub <LinkGlyph kind="external" /></a><ThemeToggle /></div>
20+
<nav
21+
className="docs-nav docs-container"
22+
aria-label="Documentation navigation"
23+
>
24+
<Link className="brand" href="/" aria-label="Headless home">
25+
<HeadlessMark className="brand-mark" />
26+
<span>headless</span>
27+
</Link>
28+
<div>
29+
<Link href="/">Overview</Link>
30+
<Link className="active" href="/docs">
31+
Docs
32+
</Link>
33+
<a
34+
className="nav-external"
35+
href="https://github.com/LockInTime/headless"
36+
>
37+
GitHub <LinkGlyph kind="external" />
38+
</a>
39+
<ThemeToggle />
40+
</div>
2041
</nav>
2142

2243
<div className="docs-container docs-layout">
2344
<aside className="docs-sidebar">
2445
<p>GET STARTED</p>
25-
<a href="#first-run">First run</a><a href="#workflow">QA workflow</a><a href="#commands">Core commands</a><a href="#context">Context pruning</a><a href="#scrollable">Scrollable evidence</a><a href="#safety">Safety</a>
46+
<a href="#first-run">First run</a>
47+
<a href="#workflow">QA workflow</a>
48+
<a href="#commands">Core commands</a>
49+
<a href="#context">Context pruning</a>
50+
<a href="#scrollable">Scrollable evidence</a>
51+
<a href="#safety">Safety</a>
2652
<p>PLATFORMS</p>
27-
<a href="#linux">Linux + Docker</a><a href="#macos">macOS</a>
53+
<a href="#linux">Linux + Docker</a>
54+
<a href="#macos">macOS</a>
2855
</aside>
2956

3057
<article className="docs-content">
31-
<div className="docs-heading-row"><div className="docs-kicker"><span className="status-dot" /> Headless documentation</div><CopyPageButton /></div>
32-
<h1>Browser control,<br /><em>made useful.</em></h1>
33-
<p className="docs-lede">Headless gives an agent a persistent browser through a small, safe CLI. Test a page, capture evidence, and inspect a failure.</p>
58+
<div className="docs-heading-row">
59+
<div className="docs-kicker">
60+
<span className="status-dot" /> Headless documentation
61+
</div>
62+
<CopyPageButton pageMarkdown={documentation.markdown} />
63+
</div>
64+
<h1>
65+
Browser control,
66+
<br />
67+
<em>made useful.</em>
68+
</h1>
69+
<p className="docs-lede">{plainText(documentation.introduction)}</p>
3470

3571
<section id="first-run">
3672
<p className="docs-label">01 / First run</p>
3773
<h2>Start a session.</h2>
38-
<p>Start the host, create a session, then visit the app. The session stays isolated until you close it.</p>
39-
<CommandBlock>{`headless start\nheadless session create qa\nheadless --session qa visit localhost:3000/designers/dashboard\nheadless --session qa inspect --context summary --task "click Continue"`}</CommandBlock>
40-
<p>On macOS, agent startup leaves your current app in front. Use <code>headless config set startup-presentation foreground</code> to make the old foreground behavior persistent, or set it to <code>background</code> to restore the built-in default. Inspect it with <code>headless config get startup-presentation</code>. The <code>headless start --foreground</code> and <code>--background</code> flags override the setting for one new host; they do not reorder a running host.</p>
74+
<p>
75+
Start the host, create a session, then visit the app. The session
76+
stays isolated until you close it.
77+
</p>
78+
<CommandBlock>{documentation.firstRunCommands}</CommandBlock>
79+
<p>{plainText(documentation.startupPresentation)}</p>
4180
</section>
4281

4382
<section id="workflow">
4483
<p className="docs-label">02 / A QA workflow</p>
4584
<h2>Capture the proof.</h2>
4685
<p>Record the path you need, then stop and create a report.</p>
47-
<CommandBlock>{`headless --session qa record start --fps 10 --format mp4\nheadless --session qa click --role button --name Continue\nheadless --session qa wait --url /next --settled\nheadless --session qa record stop --output dashboard-flow.mp4\nheadless --session qa report create --output pr-report.json`}</CommandBlock>
86+
<CommandBlock>{documentation.qaWorkflowCommands}</CommandBlock>
4887
</section>
4988

5089
<section id="commands">
5190
<p className="docs-label">03 / Command groups</p>
5291
<h2>Use intent, not pixels.</h2>
5392
<div className="docs-command-grid">
54-
{coreCommands.map(([title, commands, description]) => <div className="docs-command" key={title}><h3>{title}</h3><code>{commands}</code><p>{description}</p></div>)}
93+
{documentation.commandGroups.map((group) => (
94+
<div className="docs-command" key={group.title}>
95+
<h3>{group.title}</h3>
96+
<code>{group.commands}</code>
97+
<p>{plainText(group.description)}</p>
98+
</div>
99+
))}
55100
</div>
56101
</section>
57102

58103
<section id="context">
59104
<p className="docs-label">04 / Context pruning</p>
60105
<h2>Reveal only what matters.</h2>
61-
<p>Start with <code>{'inspect --context summary --task "..."'}</code>. For large pages, request an <code>outline</code>, choose a structural <code>@rN</code> reference, and inspect only its <code>text</code> or <code>actions</code> with <code>--within</code>. Bound results with <code>--limit</code>, <code>--budget</code>, and <code>--depth</code>; use <code>full --text</code> only as an explicit broad-page escape hatch.</p>
106+
<p>{plainText(documentation.contextPruning)}</p>
62107
</section>
63108

64109
<section id="scrollable">
65110
<p className="docs-label">05 / Scrollable evidence</p>
66111
<h2>Capture the whole scroll.</h2>
67-
<p>Use <code>screenshot --every-viewport --output dashboard-scroll</code> for up to 80 viewport-height stops, always including the bottom; bounded results report <code>truncated</code> and <code>totalPoints</code>. Section series capture headings and regions, and both modes restore the original scroll position. Add <code>--format jpg</code> for JPEG series; PDF requires <code>--full-page</code>.</p>
112+
<p>{plainText(documentation.scrollableEvidence)}</p>
68113
</section>
69114

70115
<section id="safety">
71116
<p className="docs-label">06 / Safety by default</p>
72117
<h2>Keep the browser local.</h2>
73-
<p>Headless uses a private Unix socket, not a public DevTools port. Only HTTP(S) navigation is allowed. Diagnostic secrets are redacted.</p>
118+
<p>{plainText(documentation.security.slice(0, 3).join(" "))}</p>
74119
</section>
75120

76-
<section id="linux" className="docs-note"><p><b>Linux:</b> use the supplied Docker runtime or native Chromium. Ubuntu Snap Chromium is not supported for repeated navigation.</p></section>
77-
<section id="macos" className="docs-note"><p><b>macOS:</b> build with Xcode Command Line Tools, then use the visible WKWebView host through the same CLI.</p></section>
121+
{documentation.platforms.map((platform) => {
122+
const name = platform.startsWith("macOS") ? "macOS" : "Linux";
123+
return (
124+
<section id={name.toLowerCase()} className="docs-note" key={name}>
125+
<p>
126+
<b>{name}:</b>{" "}
127+
{plainText(platform).replace(
128+
new RegExp(`^${name}[^:]*:\\s*`),
129+
"",
130+
)}
131+
</p>
132+
</section>
133+
);
134+
})}
78135
</article>
79136
</div>
80137
</main>

0 commit comments

Comments
 (0)