docs: add C4 architecture diagrams (L1–L3) with Fulll brand style (#29)#38
docs: add C4 architecture diagrams (L1–L3) with Fulll brand style (#29)#38shouze merged 3 commits intofeat/vitepress-docsfrom
Conversation
Three new pages in docs/architecture/: - overview.md: C4 L1 System Context — Developer + github-code-search + GitHub REST API - containers.md: C4 L2 — CLI parser, API client, TUI, Output renderer, Upgrader, Team cache - components.md: C4 L3 — pure-function core (aggregate, group, rows, summary, filter stats, selection, highlight, output formatter) Each page includes a Mermaid C4 diagram and a prose table describing each actor/container/component with its source file(s) and key exports. VitePress nav and sidebar were already configured in feat/vitepress-docs.
…r; apply Fulll C4 style (#29) ## Plugin migration - package.json: remove vitepress-plugin-mermaid + mermaid, add vitepress-mermaid-renderer ^1.1.11 - config.mts: drop withMermaid() wrapper, use plain defineConfig() - theme/index.ts: init createMermaidRenderer() with dark/base theme toggle - knip.json: update ignoreDependencies accordingly ## C4 diagram refactoring - Apply Fulll brand preset (%%{init}%%) on all diagrams: #FFCC33 = CLI/system, #9933FF = internal modules, #FF9933 = external - UpdateElementStyle / UpdateRelStyle / UpdateLayoutConfig on all diagrams - Add <br/> line breaks for readability - Level N titles across all pages - L2: split into 2a (Search & API layer) and 2b (Display & output layer) to eliminate relation crossings - L3: split into 3a (CLI data pipeline) and 3b (TUI render layer) to keep each diagram under 7 elements with zero crossings - vitepress-mermaid-renderer provides zoom, pan, fullscreen, SVG/PNG export via hover toolbar on every diagram
There was a problem hiding this comment.
Pull request overview
This PR implements C4 architecture diagrams (Levels 1-3) for the documentation site and migrates from vitepress-plugin-mermaid to vitepress-mermaid-renderer to enable interactive features like zoom, pan, fullscreen mode, and diagram export. The diagrams follow the Fulll brand color palette with yellow for the CLI system, violet for internal modules, orange for external systems (GitHub API), and light blue for users.
Changes:
- Replaced
vitepress-plugin-mermaidwithvitepress-mermaid-rendererfor enhanced diagram interactivity - Added three new architecture documentation pages under
docs/architecture/with C4 diagrams at levels 1-3 - Updated VitePress configuration to remove the
withMermaid()wrapper and integrate the new renderer in the theme setup - Applied Fulll brand styling to all diagrams with consistent color scheme and typography
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Removed mermaid and vitepress-plugin-mermaid dependencies, added vitepress-mermaid-renderer ^1.1.11 |
| knip.json | Updated ignoreDependencies to reflect the new Mermaid renderer package |
| docs/.vitepress/config.mts | Removed withMermaid wrapper, converted to plain defineConfig() |
| docs/.vitepress/theme/index.ts | Added createMermaidRenderer integration with dark/light mode toggle |
| docs/architecture/overview.md | New C4 Level 1 diagram showing system context with Developer, github-code-search CLI, and GitHub REST API |
| docs/architecture/containers.md | New C4 Level 2 diagrams split into search/API layer and display/output layer |
| docs/architecture/components.md | New C4 Level 3 diagrams showing CLI data pipeline and TUI render layer components |
| bun.lock | Updated lockfile reflecting dependency changes |
- components.md: fix aggregate() function name (was applyFiltersAndExclusions) - components.md: fix highlightFragment() function name (was highlight) - components.md + containers.md: fix --format json (was --output-type json) - package.json: re-add mermaid ^11.0.0 as explicit peer dep of vitepress-mermaid-renderer - knip.json: add mermaid to ignoreDependencies
| The pure-function core is split into two focused diagrams: the **CLI data pipeline** | ||
| (filter → group → format) and the **TUI render layer** (all display components). | ||
| Every component is side-effect-free and fully unit-tested. | ||
|
|
There was a problem hiding this comment.
This section claims every component is side-effect-free, but the selection helpers (applySelectAll/applySelectNone) explicitly mutate groups in-place (see src/render/selection.ts). Please adjust the text to either exclude those helpers from the “pure” claim or call out that selection updates are intentional mutations.
| The six pure render functions called by the TUI on every redraw. All six live in | ||
| `src/render/` and are re-exported through the `src/render.ts` façade. |
There was a problem hiding this comment.
The text says the six functions “live in src/render/ and are re-exported through src/render.ts”, but buildOutput() lives in src/output.ts and is not re-exported via src/render.ts (and it’s not called on every redraw either—only on Enter). Please rewrite this paragraph to match the actual module boundaries and call sites.
| The six pure render functions called by the TUI on every redraw. All six live in | |
| `src/render/` and are re-exported through the `src/render.ts` façade. | |
| The TUI calls five pure render helpers on every redraw, all defined under | |
| `src/render/` and re-exported through the `src/render.ts` façade. When the user | |
| presses Enter to confirm, it additionally calls the pure `buildOutput()` formatter | |
| from `src/output.ts` to produce the final markdown or JSON output. |
| | Component | Source file | Key exports | | ||
| | ------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | **Filter & aggregation** | `src/aggregate.ts` | `aggregate()` — filters `CodeMatch[]` by repository and extract exclusion lists; normalises both `repoName` and `org/repoName` forms. | |
There was a problem hiding this comment.
The table header row starts with ||, which adds an unintended empty first column and misaligns the table. Use a single leading | (or no leading pipe) so the table renders with the intended 3 columns.
| The diagram below shows the two actors and the single external dependency. | ||
|
|
||
| ```mermaid | ||
| %%{init: {"theme": "base", "themeVariables": {"fontFamily": "Poppins, Aestetico, Arial, sans-serif", "primaryColor": "#66CCFF", "primaryTextColor": "#000000", "lineColor": "#0000CC", "tertiaryColor": "#FFCC33"}, "themeCSS": ".label,.nodeLabel,.cluster-label > span{font-family:Poppins,Arial,sans-serif;letter-spacing:.2px} .cluster-label > span{font-weight:600;font-size:13px} .edgePath .path{stroke-width:2px}"}}%% |
There was a problem hiding this comment.
The Mermaid init directive hard-codes theme: "base" and primaryTextColor: "#000000". That will override the global renderer theme switch in docs/.vitepress/theme/index.ts and can make relation/label text hard to read in dark mode. Consider omitting theme from per-diagram init (let the renderer pick base/dark) and using themeVariables that work for both modes (or provide separate init blocks per mode).
| // Fulll brand theme variables applied via %%{init}%% in each diagram. | ||
| // The renderer handles re-render on theme toggle automatically. |
There was a problem hiding this comment.
This file comment says the renderer “handles re-render on theme toggle automatically”, but the code explicitly re-initialises the renderer on every isDark change. Either update the comment to match the behaviour, or (preferably) avoid re-creating the renderer on each toggle if the library already re-renders—repeated initialisation risks stacking event listeners / duplicate toolbars.
| // Fulll brand theme variables applied via %%{init}%% in each diagram. | |
| // The renderer handles re-render on theme toggle automatically. | |
| // Full brand theme variables applied via %%{init}%% in each diagram; theme changes are handled by re-initialising on isDark toggles. |
| How the CLI fetches data: invocation → search → cache → GitHub. | ||
|
|
||
| ```mermaid | ||
| %%{init: {"theme": "base", "themeVariables": {"fontFamily": "Poppins, Aestetico, Arial, sans-serif", "primaryColor": "#66CCFF", "primaryTextColor": "#000000", "lineColor": "#0000CC", "tertiaryColor": "#FFCC33"}, "themeCSS": ".label,.nodeLabel,.cluster-label > span{font-family:Poppins,Arial,sans-serif;letter-spacing:.2px} .cluster-label > span{font-weight:600;font-size:13px} .edgePath .path{stroke-width:2px}"}}%% |
There was a problem hiding this comment.
The same long %%{init: ...}%% Mermaid preset is duplicated across every diagram (overview/containers/components). This makes future tweaks (e.g. font, stroke width, colours) error-prone. Consider moving the shared Mermaid config (themeVariables/themeCSS) into the createMermaidRenderer({ ... }) setup so individual pages only contain the C4 definitions.
| %%{init: {"theme": "base", "themeVariables": {"fontFamily": "Poppins, Aestetico, Arial, sans-serif", "primaryColor": "#66CCFF", "primaryTextColor": "#000000", "lineColor": "#0000CC", "tertiaryColor": "#FFCC33"}, "themeCSS": ".label,.nodeLabel,.cluster-label > span{font-family:Poppins,Arial,sans-serif;letter-spacing:.2px} .cluster-label > span{font-weight:600;font-size:13px} .edgePath .path{stroke-width:2px}"}}%% |
| | Container | Source file(s) | Responsibility | | ||
| | ------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | **CLI parser** | `github-code-search.ts` | Entry point. Registers the `query` and `upgrade` Commander subcommands, resolves option defaults, and orchestrates the full search-display-output flow. | |
There was a problem hiding this comment.
The Markdown table header here starts with ||, which creates an empty first column and will render as a misaligned 4‑column table. Use a single leading | (or omit the leading pipe) so the table has exactly 3 columns as intended.
Motivation
Implements #29 — C4 architecture diagrams (Levels 1–3) for the documentation site.
Plugin migration:
vitepress-mermaid-rendererReplaced
vitepress-plugin-mermaid(no zoom support) withvitepress-mermaid-rendererwhich provides:Changes:
package.json: removevitepress-plugin-mermaid+mermaid, addvitepress-mermaid-renderer ^1.1.11config.mts: dropwithMermaid()wrapper, plaindefineConfig()theme/index.ts:createMermaidRenderer()withdark/basetoggle onisDarkwatchknip.json:ignoreDependenciesupdatedC4 diagrams — Fulll brand style
All diagrams share the Fulll brand preset (
%%{init}%%):#FFCC33— Fulll system (CLI parser, TUI)#9933FF— internal modules (all pure-function components)#FF9933— external systems (GitHub REST API)#66CCFF— persons (Developer)Pages created under
docs/architecture/overview.mdcontainers.mdcomponents.mdEach diagram uses
UpdateLayoutConfig,UpdateElementStyle,UpdateRelStylewith calibrated offsets, and<br/>line breaks for readability.Acceptance criteria
bun run format:check,bun run lint,bun run knip,bun run docs:buildall passHow to test