dd92e070d0
CI / cargo fmt --check (push) Successful in 24s
CI / cargo clippy (push) Successful in 18s
CI / cargo test (push) Successful in 46s
CI / cargo fmt --check (pull_request) Successful in 24s
CI / cargo clippy (pull_request) Successful in 23s
CI / cargo test (pull_request) Successful in 29s
CI / editor keymaps (push) Successful in 1m25s
CI / editor keymaps (pull_request) Successful in 1m23s
Relocate ONBOARDING.md and nuwiki-architecture.html out of the repo root into a dedicated development/ folder. No file references either path, so the move is self-contained. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
324 lines
13 KiB
HTML
324 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>nuwiki Architecture Diagram</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<style>
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
font-family: 'JetBrains Mono', monospace;
|
|
background: #020617;
|
|
min-height: 100vh;
|
|
padding: 2rem;
|
|
color: white;
|
|
}
|
|
|
|
.container {
|
|
max-width: 1200px;
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.header {
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.header-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 1rem;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.pulse-dot {
|
|
width: 12px;
|
|
height: 12px;
|
|
background: #22d3ee;
|
|
border-radius: 50%;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.5; }
|
|
}
|
|
|
|
h1 {
|
|
font-size: 1.5rem;
|
|
font-weight: 700;
|
|
letter-spacing: -0.025em;
|
|
}
|
|
|
|
.subtitle {
|
|
color: #94a3b8;
|
|
font-size: 0.875rem;
|
|
margin-left: 1.75rem;
|
|
}
|
|
|
|
.diagram-container {
|
|
background: rgba(15, 23, 42, 0.5);
|
|
border-radius: 1rem;
|
|
border: 1px solid #1e293b;
|
|
padding: 1.5rem;
|
|
overflow-x: auto;
|
|
}
|
|
|
|
svg {
|
|
width: 100%;
|
|
min-width: 900px;
|
|
display: block;
|
|
}
|
|
|
|
.cards {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
gap: 1rem;
|
|
margin-top: 2rem;
|
|
}
|
|
|
|
.card {
|
|
background: rgba(15, 23, 42, 0.5);
|
|
border-radius: 0.75rem;
|
|
border: 1px solid #1e293b;
|
|
padding: 1.25rem;
|
|
}
|
|
|
|
.card-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 0.5rem;
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
.card-dot {
|
|
width: 8px;
|
|
height: 8px;
|
|
border-radius: 50%;
|
|
}
|
|
|
|
.card-dot.cyan { background: #22d3ee; }
|
|
.card-dot.emerald { background: #34d399; }
|
|
.card-dot.violet { background: #a78bfa; }
|
|
.card-dot.amber { background: #fbbf24; }
|
|
.card-dot.rose { background: #fb7185; }
|
|
|
|
.card h3 {
|
|
font-size: 0.875rem;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.card ul {
|
|
list-style: none;
|
|
color: #94a3b8;
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.card li {
|
|
margin-bottom: 0.375rem;
|
|
}
|
|
|
|
.footer {
|
|
text-align: center;
|
|
margin-top: 1.5rem;
|
|
color: #475569;
|
|
font-size: 0.75rem;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<!-- Header -->
|
|
<div class="header">
|
|
<div class="header-row">
|
|
<div class="pulse-dot"></div>
|
|
<h1>nuwiki Architecture</h1>
|
|
</div>
|
|
<p class="subtitle">Layered architecture showing the Rust LSP backend and editor integration layers</p>
|
|
</div>
|
|
|
|
<!-- Main Diagram -->
|
|
<div class="diagram-container">
|
|
<svg viewBox="0 0 1000 720">
|
|
<!-- Definitions -->
|
|
<defs>
|
|
<marker id="arrowhead" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto">
|
|
<polygon points="0 0, 10 3.5, 0 7" fill="#64748b" />
|
|
</marker>
|
|
<pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse">
|
|
<path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1e293b" stroke-width="0.5"/>
|
|
</pattern>
|
|
</defs>
|
|
|
|
<!-- Background Grid -->
|
|
<rect width="100%" height="100%" fill="url(#grid)" />
|
|
|
|
<!-- Layer Model from SPEC.md -->
|
|
<!-- Consumer Layer -->
|
|
<rect x="50" y="60" width="400" height="80" rx="6" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5"/>
|
|
<text x="250" y="95" fill="white" font-size="12" font-weight="600" text-anchor="middle">Consumer Layer</text>
|
|
<text x="250" y="115" fill="#94a3b8" font-size="9" text-anchor="middle">Editor highlight, HTML export, TOC, etc.</text>
|
|
|
|
<!-- AST Layer -->
|
|
<rect x="50" y="180" width="400" height="80" rx="6" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5"/>
|
|
<text x="250" y="215" fill="white" font-size="12" font-weight="600" text-anchor="middle">AST Layer (nuwiki-core)</text>
|
|
<text x="250" y="235" fill="#94a3b8" font-size="9" text-anchor="middle">Document > Block nodes > Inline nodes</text>
|
|
|
|
<!-- Parser Layer -->
|
|
<rect x="50" y="300" width="400" height="80" rx="6" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5"/>
|
|
<text x="250" y="335" fill="white" font-size="12" font-weight="600" text-anchor="middle">Parser Layer</text>
|
|
<text x="250" y="355" fill="#94a3b8" font-size="9" text-anchor="middle">Syntax-specific (nuwiki-core)</text>
|
|
|
|
<!-- Lexer Layer -->
|
|
<rect x="50" y="420" width="400" height="80" rx="6" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5"/>
|
|
<text x="250" y="455" fill="white" font-size="12" font-weight="600" text-anchor="middle">Lexer Layer</text>
|
|
<text x="250" y="475" fill="#94a3b8" font-size="9" text-anchor="middle">Syntax-specific (nuwiki-core)</text>
|
|
|
|
<!-- Raw Text Input -->
|
|
<rect x="50" y="540" width="400" height="60" rx="6" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1.5"/>
|
|
<text x="250" y="575" fill="white" font-size="12" font-weight="600" text-anchor="middle">Raw Text Input</text>
|
|
|
|
<!-- Arrows showing data flow downward -->
|
|
<line x1="250" y1="140" x2="250" y2="180" stroke="#22d3ee" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="250" y1="260" x2="250" y2="300" stroke="#22d3ee" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="250" y1="380" x2="250" y2="420" stroke="#22d3ee" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="250" y1="500" x2="250" y2="540" stroke="#22d3ee" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
|
|
<!-- Crate Dependency Rules (right side) -->
|
|
<!-- nuwiki-ls -->
|
|
<rect x="550" y="100" width="180" height="60" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5"/>
|
|
<text x="640" y="130" fill="white" font-size="11" font-weight="600" text-anchor="middle">nuwiki-ls</text>
|
|
<text x="640" y="145" fill="#94a3b8" font-size="8" text-anchor="middle">Binary crate — starts stdio LSP server</text>
|
|
|
|
<!-- nuwiki-lsp -->
|
|
<rect x="550" y="200" width="180" height="60" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5"/>
|
|
<text x="640" y="230" fill="white" font-size="11" font-weight="600" text-anchor="middle">nuwiki-lsp</text>
|
|
<text x="640" y="245" fill="#94a3b8" font-size="8" text-anchor="middle">LSP protocol bridge (tower-lsp)</text>
|
|
|
|
<!-- nuwiki-core -->
|
|
<rect x="550" y="300" width="180" height="60" rx="6" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1.5"/>
|
|
<text x="640" y="330" fill="white" font-size="11" font-weight="600" text-anchor="middle">nuwiki-core</text>
|
|
<text x="640" y="345" fill="#94a3b8" font-size="8" text-anchor="middle">Parser, AST, Renderer (editor-agnostic)</text>
|
|
|
|
<!-- Dependencies arrows -->
|
|
<line x1="730" y1="130" x2="730" y2="170" stroke="#34d399" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="730" y1="230" x2="730" y2="270" stroke="#34d399" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
|
|
<!-- Dependency labels -->
|
|
<text x="750" y="150" fill="#94a3b8" font-size="8">depends on</text>
|
|
<text x="750" y="250" fill="#94a3b8" font-size="8">depends on</text>
|
|
|
|
<!-- Editor Integration Layers -->
|
|
<!-- VimL Layer -->
|
|
<rect x="50" y="620" width="250" height="60" rx="6" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5"/>
|
|
<text x="175" y="648" fill="white" font-size="10" font-weight="600" text-anchor="middle">VimL Layer</text>
|
|
<text x="175" y="663" fill="#94a3b8" font-size="8" text-anchor="middle">plugin/nuwiki.vim, autoload/</text>
|
|
|
|
<!-- Lua Layer (Neovim) -->
|
|
<rect x="350" y="620" width="250" height="60" rx="6" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1.5"/>
|
|
<text x="475" y="648" fill="white" font-size="10" font-weight="600" text-anchor="middle">Lua Layer</text>
|
|
<text x="475" y="663" fill="#94a3b8" font-size="8" text-anchor="middle">lua/nuwiki/</text>
|
|
|
|
<!-- Editor arrows from layers to LSP server -->
|
|
<line x1="175" y1="680" x2="250" y2="600" stroke="#a78bfa" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
<line x1="475" y1="680" x2="250" y2="600" stroke="#a78bfa" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
|
|
<!-- Labels for editor connections -->
|
|
<text x="100" y="695" fill="#94a3b8" font-size="8">Vim/Neovim</text>
|
|
<text x="400" y="695" fill="#94a3b8" font-size="8">Neovim only</text>
|
|
|
|
<!-- LSP Features Section -->
|
|
<rect x="750" y="100" width="200" height="200" rx="8" fill="rgba(120, 53, 15, 0.3)" stroke="#fbbf24" stroke-width="1.5"/>
|
|
<text x="850" y="125" fill="white" font-size="11" font-weight="600" text-anchor="middle">LSP Features</text>
|
|
<text x="760" y="145" fill="#94a3b8" font-size="8">• textDocument/semanticTokens</text>
|
|
<text x="760" y="158" fill="#94a3b8" font-size="8">• textDocument/publishDiagnostics</text>
|
|
<text x="760" y="171" fill="#94a3b8" font-size="8">• textDocument/definition</text>
|
|
<text x="760" y="184" fill="#94a3b8" font-size="8">• textDocument/references</text>
|
|
<text x="760" y="197" fill="#94a3b8" font-size="8">• textDocument/documentSymbol</text>
|
|
<text x="760" y="210" fill="#94a3b8" font-size="8">• textDocument/hover</text>
|
|
<text x="760" y="223" fill="#94a3b8" font-size="8">• textDocument/completion</text>
|
|
<text x="760" y="236" fill="#94a3b8" font-size="8">• workspace/rename</text>
|
|
<text x="760" y="249" fill="#94a3b8" font-size="8">• workspace/symbol</text>
|
|
|
|
<!-- Arrow from LSP layer to LSP Features -->
|
|
<line x1="730" y1="260" x2="750" y2="200" stroke="#fbbf24" stroke-width="1.5" marker-end="url(#arrowhead)"/>
|
|
|
|
<!-- Security Boundary/Crate Dependencies -->
|
|
<rect x="540" y="80" width="200" height="300" rx="12" fill="rgba(251, 191, 36, 0.05)" stroke="#fbbf24" stroke-width="1" stroke-dasharray="8,4"/>
|
|
<text x="552" y="98" fill="#fbbf24" font-size="9" font-weight="600">Crate Dependencies</text>
|
|
|
|
<!-- Legend -->
|
|
<text x="750" y="350" fill="white" font-size="10" font-weight="600">Legend</text>
|
|
|
|
<rect x="750" y="362" width="16" height="10" rx="2" fill="rgba(8, 51, 68, 0.4)" stroke="#22d3ee" stroke-width="1"/>
|
|
<text x="772" y="370" fill="#94a3b8" font-size="8">Editor Layers</text>
|
|
|
|
<rect x="750" y="382" width="16" height="10" rx="2" fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" stroke-width="1"/>
|
|
<text x="772" y="390" fill="#94a3b8" font-size="8">Core Crates</text>
|
|
|
|
<rect x="750" y="402" width="16" height="10" rx="2" fill="rgba(76, 29, 149, 0.4)" stroke="#a78bfa" stroke-width="1"/>
|
|
<text x="772" y="410" fill="#94a3b8" font-size="8">Layer Boundaries</text>
|
|
|
|
<line x1="750" y1="425" x2="766" y2="425" stroke="#fbbf24" stroke-width="1" stroke-dasharray="3,3"/>
|
|
<text x="772" y="433" fill="#94a3b8" font-size="8">Data Flow</text>
|
|
</svg>
|
|
</div>
|
|
|
|
<!-- Info Cards -->
|
|
<div class="cards">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot cyan"></div>
|
|
<h3>Editor Integration</h3>
|
|
</div>
|
|
<ul>
|
|
<li>• VimL layer for universal Vim support</li>
|
|
<li>• Lua layer for Neovim integration</li>
|
|
<li>• Zero-logic editor layers (pure wiring only)</li>
|
|
<li>• Supports vim-lsp and coc.nvim for Vim</li>
|
|
<li>• Built-in LSP client for Neovim 0.11+</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot emerald"></div>
|
|
<h3>Core Architecture</h3>
|
|
</div>
|
|
<ul>
|
|
<li>• Strict layer separation (no circular deps)</li>
|
|
<li>• nuwiki-core is editor-agnostic</li>
|
|
<li>• LSP bridge uses tower-lsp</li>
|
|
<li>• Binary crate is intentionally thin</li>
|
|
<li>• Strict dependency rules enforced</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<div class="card-dot violet"></div>
|
|
<h3>LSP Features</h3>
|
|
</div>
|
|
<ul>
|
|
<li>• Syntax highlighting (semantic tokens)</li>
|
|
<li>• Diagnostics (broken links, parse errors)</li>
|
|
<li>• Go-to-definition and references</li>
|
|
<li>• Document symbols (TOC/outline)</li>
|
|
<li>• Hover, completion, workspace symbols</li>
|
|
<li>• Rename and workspace-wide operations</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<p class="footer">
|
|
nuwiki • Rust-based vimwiki replacement with LSP backend
|
|
</p>
|
|
</div>
|
|
</body>
|
|
</html> |