@agent-scope/site 1.17.1 → 1.17.3

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 (2) hide show
  1. package/README.md +429 -0
  2. package/package.json +3 -2
package/README.md ADDED
@@ -0,0 +1,429 @@
1
+ # @agent-scope/site
2
+
3
+ Static HTML gallery generator for Scope — reads `.reactscope/` output and produces a self-contained component documentation website with a gallery, analytics dashboard, per-component detail pages, and design token compliance visualization.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Usage](#usage)
9
+ - [Output Structure](#output-structure)
10
+ - [Pages](#pages)
11
+ - [Gallery (index.html)](#gallery-indexhtml)
12
+ - [Dashboard (dashboard.html)](#dashboard-dashboardhtml)
13
+ - [Component Detail Pages](#component-detail-pages)
14
+ - [Configuration Options](#configuration-options)
15
+ - [Architecture](#architecture)
16
+ - [Data Formats](#data-formats)
17
+
18
+ ---
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install @agent-scope/site
24
+ ```
25
+
26
+ The package is also bundled with `@agent-scope/cli`. If you have the CLI installed, `scope site build` is the recommended way to invoke it.
27
+
28
+ ---
29
+
30
+ ## Usage
31
+
32
+ ### Via the CLI (recommended)
33
+
34
+ ```bash
35
+ # Build the site from .reactscope/ output
36
+ scope site build
37
+
38
+ # Build with custom options
39
+ scope site build \
40
+ --output ./docs/components \
41
+ --base-path /docs/ \
42
+ --title "Acme Component Library" \
43
+ --compliance .reactscope/compliance.json
44
+
45
+ # Serve locally for preview
46
+ scope site serve
47
+ scope site serve --port 8080
48
+ ```
49
+
50
+ See [`@agent-scope/cli`](../cli/README.md) for the full `scope site` command reference.
51
+
52
+ ### Programmatic API
53
+
54
+ ```typescript
55
+ import { buildSite } from '@agent-scope/site';
56
+
57
+ await buildSite({
58
+ inputDir: '.reactscope',
59
+ outputDir: '.reactscope/site',
60
+ basePath: '/docs/',
61
+ title: 'My Component Library',
62
+ compliancePath: '.reactscope/compliance.json',
63
+ });
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Output Structure
69
+
70
+ `buildSite()` generates a directory of static HTML files with all CSS and JavaScript embedded inline — no web server or build step needed after generation.
71
+
72
+ ```
73
+ outputDir/ # default: .reactscope/site/
74
+ ├── index.html # Gallery homepage — component grid with search
75
+ ├── dashboard.html # Analytics dashboard
76
+ ├── button.html # Detail page for "Button" component
77
+ ├── search-page.html # Detail page for "SearchPage" component
78
+ ├── complex-form.html # Detail page for "ComplexForm" component
79
+ └── ... # One file per component (PascalCase → kebab-case)
80
+ ```
81
+
82
+ **File naming:** Component names are slugified from PascalCase to kebab-case:
83
+ - `Button` → `button.html`
84
+ - `SearchPage` → `search-page.html`
85
+ - `ComplexForm` → `complex-form.html`
86
+
87
+ **Total files generated:** N (components) + 2 (index + dashboard)
88
+
89
+ All HTML files are fully self-contained: CSS variables, layout styles, syntax highlighting, and client-side search JavaScript are all inlined. No external assets or CDN requests are required.
90
+
91
+ ---
92
+
93
+ ## Pages
94
+
95
+ ### Gallery (`index.html`)
96
+
97
+ The gallery homepage provides an overview of all components with real-time search.
98
+
99
+ **Header:**
100
+ - Site title
101
+ - Total component count
102
+ - Search box (filters component cards in real time, client-side)
103
+
104
+ **Statistics grid:**
105
+
106
+ | Stat | Description |
107
+ |------|-------------|
108
+ | Total Components | Count of all components in the manifest |
109
+ | Simple | Components classified as simple complexity |
110
+ | Complex | Components classified as complex complexity |
111
+ | Memoized | Components wrapped in `React.memo` |
112
+
113
+ **Component card grid:**
114
+
115
+ Each card shows:
116
+ - Rendered screenshot (base64 PNG from `.reactscope/renders/`) if available
117
+ - Component name
118
+ - Prop count
119
+ - Complexity badge (`simple` / `complex`)
120
+ - Hook count
121
+
122
+ Cards link to the corresponding detail page. The grid uses CSS `auto-fill / minmax(280px)` for responsive layout.
123
+
124
+ ---
125
+
126
+ ### Dashboard (`dashboard.html`)
127
+
128
+ The analytics dashboard provides a library-wide view of component health and design token compliance.
129
+
130
+ **Key metrics grid:**
131
+ - Total components
132
+ - Average props per component
133
+ - Components with screenshots
134
+ - Overall design token compliance percentage
135
+
136
+ **Complexity breakdown:**
137
+ - Simple / complex counts and percentage
138
+
139
+ **Top components by prop count:**
140
+ A ranked table (top 10) with: component name (linked to detail page), prop count, complexity badge.
141
+
142
+ **Design token compliance section** (requires `--compliance` / `compliancePath`):
143
+ - Overall compliance percentage with visual progress bar
144
+ - Per-component compliance scores
145
+ - On-system and off-system property counts per component
146
+
147
+ ---
148
+
149
+ ### Component Detail Pages
150
+
151
+ Each component gets its own page (`<slug>.html`) with ten expandable sections.
152
+
153
+ #### Playground
154
+
155
+ - **Props reference table:** prop name, type (syntax-highlighted), required/optional, default value, possible enum values
156
+ - **Rendered preview:** embedded base64 PNG screenshot, or "not generated" if no render exists
157
+
158
+ #### Matrix
159
+
160
+ Grid of renders across prop axis combinations (from `scope render matrix`):
161
+ - Each cell shows the rendered output or an error message
162
+ - Cell labels show the axis values for that combination
163
+ - Grid column count adapts to the number of cells
164
+
165
+ #### Docs
166
+
167
+ Placeholder for component documentation. Currently displays "No documentation file found."
168
+
169
+ #### Analysis
170
+
171
+ **Statistics grid:**
172
+ - Complexity class badge
173
+ - Prop count
174
+ - Hook count
175
+ - Side effect count
176
+ - Export type (named / default)
177
+ - Memoized (Yes / No)
178
+ - Forwarded ref (Yes / No)
179
+
180
+ **Analysis grid (2 columns):**
181
+ - Detected hooks (tagged list: `useState`, `useEffect`, etc.)
182
+ - Required contexts (tagged list)
183
+ - HOC wrappers (tagged list)
184
+ - Side effects (tagged list: fetch URLs, timers, subscriptions, global listeners)
185
+
186
+ #### X-Ray
187
+
188
+ Collapsible DOM tree from the rendered component:
189
+ - First 2 levels open by default, deeper levels collapsed
190
+ - Syntax-highlighted element attributes and values
191
+ - Total element count shown in header
192
+
193
+ Optional computed styles table:
194
+ - CSS selector (element path)
195
+ - CSS property name
196
+ - Computed value
197
+
198
+ #### Tokens
199
+
200
+ Design token compliance audit (requires `--compliance` / `compliancePath`):
201
+ - Compliance percentage with visual bar
202
+ - Per-property audit table:
203
+
204
+ | Column | Description |
205
+ |--------|-------------|
206
+ | Property | CSS property name (monospace) |
207
+ | Value | Computed value (with color swatch for hex values) |
208
+ | Status | `✓ on-system (token.path)` or `✗ off-system` |
209
+ | Nearest | Closest on-system token (when off-system) |
210
+
211
+ #### Accessibility
212
+
213
+ WCAG accessibility audit (from `scope render` data):
214
+ - Component ARIA role badge
215
+ - Accessible name
216
+ - Violation list (red-highlighted) or success confirmation
217
+
218
+ #### Composition
219
+
220
+ Component dependency graph:
221
+ - Left column: components this component composes (children)
222
+ - Right column: components that compose this component (parents)
223
+ - All entries link to their respective detail pages
224
+
225
+ #### Responsive
226
+
227
+ Multi-viewport renders. Placeholder: "Not generated."
228
+
229
+ #### Stress Tests
230
+
231
+ Edge case and stress test renders. Placeholder: "Not generated."
232
+
233
+ ---
234
+
235
+ ## Configuration Options
236
+
237
+ ### `SiteOptions`
238
+
239
+ | Option | Type | Default | Description |
240
+ |--------|------|---------|-------------|
241
+ | `inputDir` | `string` | `".reactscope"` | Directory containing manifest and renders |
242
+ | `outputDir` | `string` | `".reactscope/site"` | Output directory for generated HTML files |
243
+ | `basePath` | `string` | `"/"` | Base URL path prefix for subdirectory deployment |
244
+ | `compliancePath` | `string` | — | Path to compliance batch report JSON (optional) |
245
+ | `title` | `string` | `"Scope — Component Gallery"` | Site title shown in header and `<title>` |
246
+
247
+ ### `basePath` for subdirectory deployment
248
+
249
+ When deploying to a path other than the domain root, set `basePath` so that inter-page links resolve correctly:
250
+
251
+ ```typescript
252
+ await buildSite({
253
+ basePath: '/docs/components/',
254
+ // ...
255
+ });
256
+ ```
257
+
258
+ This prefixes all `href` attributes in the generated HTML with the given path.
259
+
260
+ ---
261
+
262
+ ## Architecture
263
+
264
+ The package is a zero-dependency static site generator organized into focused modules:
265
+
266
+ ```
267
+ src/
268
+ ├── index.ts # Public API: exports buildSite()
269
+ ├── builder.ts # Main orchestrator: read → render → write
270
+ ├── reader.ts # Input reading: manifest.json, renders/, compliance
271
+ ├── types.ts # TypeScript interfaces (ManifestData, RenderFileData, etc.)
272
+ ├── css.ts # Inline CSS string (design tokens, layout, components)
273
+ ├── utils.ts # escapeHtml(), slugify(), syntaxHighlightJSX(), renderDOMTree()
274
+ └── templates/
275
+ ├── layout.ts # HTML shell, top nav, sidebar, "On This Page" nav
276
+ ├── component-index.ts # Gallery homepage template
277
+ ├── component-detail.ts # Per-component detail page template
278
+ └── dashboard.ts # Analytics dashboard template
279
+ ```
280
+
281
+ ### Data flow
282
+
283
+ ```
284
+ .reactscope/manifest.json ─┐
285
+ .reactscope/renders/*.json ├─→ reader.ts → builder.ts → templates/ → *.html
286
+ .reactscope/compliance.json (opt.) ─┘
287
+ ```
288
+
289
+ 1. **`reader.ts`** reads the manifest JSON, optionally scans the `renders/` directory for per-component JSON files, and optionally reads the compliance report.
290
+ 2. **`builder.ts`** iterates over all components, calls templates for each page, and writes HTML files to `outputDir`.
291
+ 3. **`templates/`** functions receive typed data objects and return HTML strings. All templates call `layout.ts` to wrap content in the shared shell (nav, sidebar, "On This Page").
292
+ 4. **`css.ts`** exports a single inline CSS string embedded in every page's `<style>` tag.
293
+ 5. **`utils.ts`** provides XSS-safe HTML escaping, PascalCase-to-kebab-case slugification, JSX syntax highlighting, and recursive DOM tree rendering.
294
+
295
+ ### Design principles
296
+
297
+ - **Zero dependencies** — the package has no runtime NPM dependencies. All output is pure HTML/CSS/JS.
298
+ - **Embedded assets** — CSS and JavaScript are inlined into every HTML file. No separate asset directory.
299
+ - **XSS safety** — all user-controlled strings (component names, prop values, file paths) pass through `escapeHtml()` before insertion into HTML.
300
+ - **Idempotent builds** — running `buildSite()` multiple times on the same input produces identical output.
301
+ - **Progressive enhancement** — pages are readable without JavaScript; search filtering and collapsible sections are added via inline `<script>` tags.
302
+
303
+ ### CSS design system
304
+
305
+ The generated HTML uses CSS custom properties for consistent styling:
306
+
307
+ ```css
308
+ --color-text: #0f0f0f;
309
+ --color-muted: #6b7280;
310
+ --color-border: #e5e7eb;
311
+ --color-bg: #ffffff;
312
+ --color-bg-subtle: #f9fafb;
313
+ --color-bg-code: #1a1a2e;
314
+ --color-accent: #2563eb;
315
+ --color-success: #16a34a;
316
+ --color-warn: #d97706;
317
+ --color-error: #dc2626;
318
+
319
+ --font-body: 'Inter', system-ui, -apple-system, sans-serif;
320
+ --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
321
+ ```
322
+
323
+ **Layout:** Three-column design — left sidebar (220px, component list with search), main content (flex, max 900px), right sidebar (200px, "On This Page" nav). The left sidebar collapses at 768px, the right sidebar at 1024px.
324
+
325
+ ---
326
+
327
+ ## Data Formats
328
+
329
+ ### Input: `manifest.json`
330
+
331
+ ```typescript
332
+ interface ManifestData {
333
+ version: string;
334
+ generatedAt: string;
335
+ components: Record<string, ComponentData>;
336
+ tree: Record<string, { children: string[]; parents: string[] }>;
337
+ }
338
+
339
+ interface ComponentData {
340
+ filePath: string;
341
+ exportType: "named" | "default" | "none";
342
+ displayName: string;
343
+ props: Record<string, PropData>;
344
+ composes: string[];
345
+ composedBy: string[];
346
+ forwardedRef: boolean;
347
+ hocWrappers: string[];
348
+ memoized: boolean;
349
+ loc: { start: number; end: number };
350
+ complexityClass: "simple" | "complex";
351
+ requiredContexts: string[];
352
+ detectedHooks: string[];
353
+ sideEffects: {
354
+ fetches: string[];
355
+ timers: boolean;
356
+ subscriptions: string[];
357
+ globalListeners: boolean;
358
+ };
359
+ }
360
+
361
+ interface PropData {
362
+ type: string;
363
+ values?: string[]; // enum values
364
+ default?: string;
365
+ required: boolean;
366
+ rawType: string;
367
+ }
368
+ ```
369
+
370
+ ### Input: `renders/<Component>.json`
371
+
372
+ ```typescript
373
+ interface RenderFileData {
374
+ screenshot?: string; // Base64-encoded PNG
375
+ width?: number;
376
+ height?: number;
377
+ renderTimeMs?: number;
378
+ computedStyles?: Record<string, Record<string, string>>;
379
+ dom?: {
380
+ tree: DOMNodeData;
381
+ elementCount: number;
382
+ boundingBox: { x: number; y: number; width: number; height: number };
383
+ };
384
+ console?: {
385
+ errors: string[];
386
+ warnings: string[];
387
+ logs: string[];
388
+ };
389
+ accessibility?: {
390
+ role: string;
391
+ name: string;
392
+ violations: string[];
393
+ };
394
+ // Matrix render fields
395
+ cells?: MatrixCellData[];
396
+ axisLabels?: string[][];
397
+ stats?: {
398
+ total: number;
399
+ success: number;
400
+ failed: number;
401
+ avgRenderTimeMs: number;
402
+ };
403
+ }
404
+ ```
405
+
406
+ ### Input: `compliance.json`
407
+
408
+ ```typescript
409
+ interface ComplianceBatchData {
410
+ components: Record<string, ComplianceReportData>;
411
+ }
412
+
413
+ interface ComplianceReportData {
414
+ properties: Record<string, PropertyResultData>;
415
+ total: number;
416
+ onSystem: number;
417
+ offSystem: number;
418
+ compliance: number; // 0–1
419
+ auditedAt: string;
420
+ }
421
+
422
+ interface PropertyResultData {
423
+ property: string;
424
+ value: string;
425
+ status: "on_system" | "OFF_SYSTEM";
426
+ token?: string;
427
+ nearest?: { token: string; value: string; distance: number };
428
+ }
429
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-scope/site",
3
- "version": "1.17.1",
3
+ "version": "1.17.3",
4
4
  "description": "Static HTML gallery generator for Scope — reads .reactscope/ output and produces a component gallery website",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -20,7 +20,8 @@
20
20
  "module": "./dist/index.js",
21
21
  "types": "./dist/index.d.ts",
22
22
  "files": [
23
- "dist"
23
+ "dist",
24
+ "README.md"
24
25
  ],
25
26
  "scripts": {
26
27
  "build": "tsup",