Skip to content

Commit 8050fd2

Browse files
authored
Create a public project site that explains rdt outside the README (#6)
The repository had solid CLI docs and maintainer notes, but no public-facing site that framed the project for first-time users. This adds a VitePress-based GitHub Pages surface with a landing page, workflow guide, architecture guide, and a deploy workflow that follows the protected-branch path. Constraint: GitHub Pages should deploy from Actions without changing branch protection Constraint: Public docs should not expose maintainer-only handoff notes as site pages Rejected: Keep everything inside README only | too dense for first-time discovery Rejected: Use Jekyll or a heavier docs framework | worse fit for this Node repo and v1 scope Confidence: high Scope-risk: moderate Reversibility: clean Directive: Keep the public site focused on user-facing explanation and workflows; do not publish internal validation artifacts without a deliberate docs decision Tested: npm run build; npm test; npm run docs:build Not-tested: Live GitHub Pages deployment after merge to main
1 parent 00252ed commit 8050fd2

11 files changed

Lines changed: 2849 additions & 142 deletions

File tree

.github/workflows/pages.yml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Pages
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
push:
8+
branches:
9+
- main
10+
workflow_dispatch:
11+
12+
permissions:
13+
contents: read
14+
pages: write
15+
id-token: write
16+
17+
concurrency:
18+
group: pages
19+
cancel-in-progress: true
20+
21+
jobs:
22+
build:
23+
name: Build VitePress site
24+
runs-on: ubuntu-latest
25+
steps:
26+
- name: Checkout
27+
uses: actions/checkout@v5
28+
29+
- name: Setup Node.js
30+
uses: actions/setup-node@v5
31+
with:
32+
node-version: 22
33+
cache: npm
34+
35+
- name: Setup Pages
36+
uses: actions/configure-pages@v5
37+
38+
- name: Install dependencies
39+
run: npm ci
40+
41+
- name: Build site
42+
run: npm run docs:build
43+
44+
- name: Upload Pages artifact
45+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
46+
uses: actions/upload-pages-artifact@v3
47+
with:
48+
path: docs/.vitepress/dist
49+
50+
deploy:
51+
name: Deploy to GitHub Pages
52+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
53+
needs: build
54+
runs-on: ubuntu-latest
55+
environment:
56+
name: github-pages
57+
url: ${{ steps.deployment.outputs.page_url }}
58+
steps:
59+
- name: Deploy
60+
id: deployment
61+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Thumbs.db
1414

1515
coverage/
1616
dist/
17+
docs/.vitepress/cache/
18+
docs/.vitepress/dist/
1719
*.tgz
1820

1921
*.jsonl

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Agent-first CLI for inspecting React applications through a Playwright-managed b
44

55
It gives agents and engineers a structured command surface for React tree snapshots, node inspection, source reveal, deterministic browser interaction, and commit-oriented profiler analysis without opening the DevTools UI. The public CLI is engine-based: `auto` chooses between the current custom engine and a DevTools-aligned engine when capability checks allow it.
66

7+
Project site: https://ring-wdr.github.io/react-devtool-cli/
8+
79
## Recommended architecture
810

911
- `rdt` talks to Playwright directly through the Node API

docs/.vitepress/config.mts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { defineConfig } from "vitepress";
2+
3+
const repoUrl = "https://github.com/Ring-wdr/react-devtool-cli";
4+
5+
export default defineConfig({
6+
title: "react-devtool-cli",
7+
description: "Playwright-native CLI for inspecting live React apps without opening the DevTools UI.",
8+
base: "/react-devtool-cli/",
9+
cleanUrls: true,
10+
lastUpdated: true,
11+
srcExclude: ["devtools-concept-mapping.md", "public-repo-strategy.md"],
12+
themeConfig: {
13+
nav: [
14+
{ text: "Home", link: "/" },
15+
{ text: "Workflows", link: "/workflows" },
16+
{ text: "Architecture", link: "/architecture" },
17+
{ text: "GitHub", link: repoUrl }
18+
],
19+
sidebar: [
20+
{
21+
text: "Guide",
22+
items: [
23+
{ text: "Why RDT", link: "/" },
24+
{ text: "Workflows", link: "/workflows" },
25+
{ text: "Architecture", link: "/architecture" }
26+
]
27+
}
28+
],
29+
socialLinks: [{ icon: "github", link: repoUrl }],
30+
editLink: {
31+
pattern: `${repoUrl}/edit/main/docs/:path`,
32+
text: "Edit this page on GitHub"
33+
},
34+
search: {
35+
provider: "local"
36+
},
37+
footer: {
38+
message: "Playwright-native React inspection for agents and engineers.",
39+
copyright: "MIT Licensed"
40+
}
41+
}
42+
});

docs/.vitepress/theme/custom.css

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
:root {
2+
--vp-c-brand-1: #0f766e;
3+
--vp-c-brand-2: #0b5f59;
4+
--vp-c-brand-3: #134e4a;
5+
--vp-c-brand-soft: rgba(15, 118, 110, 0.14);
6+
--vp-c-sponsor: #c2410c;
7+
--vp-home-hero-name-color: transparent;
8+
--vp-home-hero-name-background: linear-gradient(120deg, #0f766e 10%, #c2410c 90%);
9+
--vp-home-hero-image-background-image: radial-gradient(circle at top, rgba(15, 118, 110, 0.28), rgba(194, 65, 12, 0.2));
10+
--vp-home-hero-image-filter: blur(64px);
11+
}
12+
13+
.VPFeature {
14+
border: 1px solid rgba(15, 23, 42, 0.08);
15+
box-shadow: 0 18px 40px rgba(15, 23, 42, 0.06);
16+
}
17+
18+
.vp-doc table {
19+
display: table;
20+
width: 100%;
21+
}

docs/.vitepress/theme/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import DefaultTheme from "vitepress/theme";
2+
import "./custom.css";
3+
4+
export default DefaultTheme;

docs/architecture.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Architecture
2+
3+
`react-devtool-cli` is intentionally not a browser extension wrapper. It is a CLI runtime that owns browser automation, React tree capture, and profiler export as one command surface.
4+
5+
## Runtime shape
6+
7+
| Layer | Responsibility |
8+
| --- | --- |
9+
| CLI | Parse commands, format output, and route calls to the session daemon |
10+
| Session daemon | Own browser lifecycle, transport selection, and RPC between commands and the active page |
11+
| Runtime script | Discover roots through the React global hook, collect snapshots, inspect nodes, and capture profiler data |
12+
13+
This split keeps user-facing commands stable while transport and runtime details evolve underneath.
14+
15+
## Session transports
16+
17+
| Transport | Meaning | Recommended use |
18+
| --- | --- | --- |
19+
| `open` | `rdt` launches the browser directly through Playwright | Default for local work |
20+
| `connect` | `rdt` connects to an existing Playwright endpoint | Best remote path |
21+
| `attach` | `rdt` attaches through Chromium CDP | Compatibility fallback when Playwright protocol is unavailable |
22+
23+
## Engine selection
24+
25+
`--engine auto` is the default because it chooses between the current custom engine and a DevTools-aligned path when capability checks allow it.
26+
27+
- `custom` forces the snapshot-diff engine
28+
- `devtools` requests the DevTools-aligned path and falls back when capability checks fail
29+
- `doctor` exposes `selectedEngine`, `recommendedEngine`, and capability hints so callers know what they are actually trusting
30+
31+
## Snapshot semantics
32+
33+
Snapshot-scoped node identity is a deliberate design choice, not a temporary workaround.
34+
35+
- `tree get` creates a snapshot and returns `snapshotId`
36+
- follow-up node ids are only stable inside that snapshot
37+
- commands fail loudly when a requested snapshot has expired from the cache
38+
39+
This makes the CLI more deterministic for agent workflows than a model that pretends node ids stay globally stable across live React updates.
40+
41+
## Inspect payload model
42+
43+
`node inspect` is closest to an inspected-element payload, but the CLI keeps it intentionally simpler than full DevTools frontend data.
44+
45+
- `ownerStack` is a lightweight owner chain
46+
- `hooks` is a simplified serialized view of hook state
47+
- `context` is a serialized view of current context dependencies
48+
- `source` may be `null` when `_debugSource` is not present in the runtime
49+
- `dom` is the first host descendant summary used for highlight and DOM-oriented follow-up
50+
51+
## Profiler model
52+
53+
Profiler support is commit-oriented.
54+
55+
- summaries focus on commit count, timestamps, roots, and live-tree size
56+
- exported profiles use NDJSON or `jsonl.gz`
57+
- ranked and flamegraph views provide CLI-oriented hotspot summaries
58+
- duration support depends on what the current React runtime exposes
59+
60+
Important limitation: current profiler output does not prove exact rerender sets the way a full DevTools frontend with component-duration instrumentation might.
61+
62+
## Trust boundaries
63+
64+
Most structured responses expose the same three guardrails:
65+
66+
- `observationLevel`: what was directly observed
67+
- `limitations`: what the payload does not prove
68+
- `runtimeWarnings`: environmental or runtime conditions that can mislead follow-up analysis
69+
70+
The project is designed so agents can read those fields literally instead of inferring hidden guarantees.
71+
72+
## Documentation boundary
73+
74+
Public docs should explain the product, workflow, and architecture clearly. Maintainer handoff notes, raw validation logs, and internal investigation artifacts still belong in the repository, but they are not the public narrative for the GitHub Pages site.

docs/index.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
layout: home
3+
4+
hero:
5+
name: react-devtool-cli
6+
text: Inspect live React apps without opening DevTools UI
7+
tagline: A Playwright-native CLI for tree snapshots, node inspection, deterministic interaction, and commit-oriented profiler analysis.
8+
actions:
9+
- theme: brand
10+
text: Start with Workflows
11+
link: /workflows
12+
- theme: alt
13+
text: Read the Architecture
14+
link: /architecture
15+
16+
features:
17+
- title: Snapshot-aware tree inspection
18+
details: Collect a tree once, keep the returned snapshot context, and inspect nodes deterministically instead of chasing unstable live ids.
19+
- title: Playwright-managed sessions
20+
details: Open local browser sessions directly, connect to Playwright endpoints remotely, or attach to Chromium over CDP when compatibility matters more than fidelity.
21+
- title: Commit-oriented profiler analysis
22+
details: Move from suspicion to evidence with doctor checks, built-in interaction helpers, profiler capture, and exportable NDJSON traces.
23+
---
24+
25+
## Why this project exists
26+
27+
`react-devtool-cli` gives agents and engineers a structured command surface for investigating React applications from the terminal. It is built for workflows where opening the DevTools UI is either too manual, too hard to automate, or too indirect for repeatable debugging.
28+
29+
Unlike browser extensions or frontend-only DevTools flows, `rdt` owns the browser session through Playwright. That makes it useful for automated investigations, remote environments, and agent-driven debugging loops where commands need deterministic output and explicit trust boundaries.
30+
31+
## What you can do with it
32+
33+
- Open a browser session against a live app with `session open`, `session connect`, or `session attach`
34+
- Capture snapshot-scoped trees with `tree get`
35+
- Search, inspect, highlight, and source-map React nodes with explicit snapshot context
36+
- Run built-in interactions before profiling, instead of stitching together ad hoc browser scripts
37+
- Record and export commit-oriented profiler data for later comparison
38+
39+
## Recommended first run
40+
41+
```bash
42+
npm install -g react-devtool-cli
43+
rdt session open --url http://localhost:3000 --session demo
44+
rdt tree get --session demo
45+
rdt node search App --session demo --snapshot <snapshotId>
46+
```
47+
48+
That sequence captures the core model of the tool:
49+
50+
1. Open a browser session that `rdt` manages.
51+
2. Collect a tree and persist the returned `snapshotId`.
52+
3. Reuse that snapshot for follow-up inspection so node lookups stay deterministic.
53+
54+
## What makes it different
55+
56+
| Area | `react-devtool-cli` bias |
57+
| --- | --- |
58+
| Runtime host | Playwright-managed browser session |
59+
| Primary interface | Structured CLI output for agents and engineers |
60+
| Tree stability model | Snapshot-scoped node ids |
61+
| Profiler output | Commit-oriented summaries and NDJSON export |
62+
| Trust boundary | Explicit `observationLevel`, `limitations`, and `runtimeWarnings` fields |
63+
64+
## Where to go next
65+
66+
- Use [Workflows](/workflows) to get productive quickly.
67+
- Use [Architecture](/architecture) to understand engine choice, snapshot semantics, and profiler interpretation limits.

docs/workflows.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# Workflows
2+
3+
This page is the fastest path from zero context to a useful `rdt` session.
4+
5+
## Install
6+
7+
```bash
8+
npm install -g react-devtool-cli
9+
```
10+
11+
`rdt` resolves Playwright from the local project first, then falls back through `playwright-core`, `RDT_PLAYWRIGHT_PATH`, and global installs.
12+
13+
## Choose the right session mode
14+
15+
| Command | Use when | Notes |
16+
| --- | --- | --- |
17+
| `rdt session open` | You want `rdt` to launch and own the browser locally | Recommended default path |
18+
| `rdt session connect` | You already have a Playwright `wsEndpoint` | Remote-friendly, keeps Playwright fidelity |
19+
| `rdt session attach` | You only have Chromium CDP access | Compatibility path, lower fidelity than Playwright protocol |
20+
21+
## Quick start
22+
23+
```bash
24+
rdt session open --url http://localhost:3000 --browser chromium --engine auto --session demo
25+
rdt tree get --session demo
26+
rdt node search App --session demo --snapshot <snapshotId>
27+
rdt node inspect <nodeId> --session demo --snapshot <snapshotId>
28+
```
29+
30+
If you only remember one rule, remember this one: `tree get` starts the inspection cycle, and the returned `snapshotId` should follow later lookup commands.
31+
32+
## Snapshot-aware inspection
33+
34+
- `tree get` returns a `snapshotId`.
35+
- Node ids are only guaranteed to be meaningful inside that snapshot.
36+
- If you omit `--snapshot`, `rdt` falls back to the latest collected snapshot.
37+
- If a requested snapshot has been evicted from the in-memory cache, the command fails with `snapshot-expired`.
38+
39+
Recommended flow:
40+
41+
```bash
42+
rdt tree get --session demo
43+
rdt node search App --session demo --snapshot <snapshotId>
44+
rdt node highlight <nodeId> --session demo --snapshot <snapshotId>
45+
rdt source reveal <nodeId> --session demo --snapshot <snapshotId>
46+
```
47+
48+
Recovery flow:
49+
50+
```bash
51+
rdt tree get --session demo
52+
# save the new snapshotId
53+
rdt node search App --session demo --snapshot <newSnapshotId>
54+
```
55+
56+
## Run `doctor` before deeper investigation
57+
58+
```bash
59+
rdt session doctor --session demo
60+
```
61+
62+
Use it to confirm:
63+
64+
- React was detected
65+
- which engine was selected
66+
- whether built-in `interact` helpers are supported
67+
- whether profiler and source-reveal capabilities are trustworthy for the current runtime
68+
69+
## Interact before profiling
70+
71+
Built-in interactions keep the investigation inside the same session instead of forcing separate helper scripts.
72+
73+
```bash
74+
rdt interact click --session demo --selector 'button.save'
75+
rdt interact type --session demo --selector 'input[name="query"]' --text hello
76+
rdt interact wait --session demo --ms 500
77+
```
78+
79+
After interaction, verify the app settled by collecting a fresh tree or reading profiler output instead of assuming the UI state changed correctly.
80+
81+
## Profile a real update
82+
83+
```bash
84+
rdt profiler start --session demo
85+
rdt interact type --session demo --selector 'input[name="query"]' --text hello
86+
rdt profiler stop --session demo
87+
rdt profiler summary --session demo
88+
rdt profiler ranked <commitId> --session demo --limit 10
89+
rdt profiler export --session demo --compress
90+
```
91+
92+
Read profiler output literally:
93+
94+
- `commitCount` tells you how many commits were captured
95+
- `nodeCount` fields describe live tree size at commit time, not exact rerender counts
96+
- `primaryUpdateCommitId` and `recommendedCommitIds` are better drill-down targets than blindly reading the first commit
97+
98+
## Close the loop cleanly
99+
100+
```bash
101+
rdt session close --session demo
102+
```
103+
104+
Treat sessions as explicit resources. Close them when the investigation is over so later runs start from a known state.

0 commit comments

Comments
 (0)