diff --git a/astro.config.mjs b/astro.config.mjs index 0108d08..0ad6deb 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,5 +1,6 @@ // @ts-check +import mdx from "@astrojs/mdx"; import starlight from "@astrojs/starlight"; import { defineConfig } from "astro/config"; @@ -44,7 +45,7 @@ export default defineConfig({ tag: "link", attrs: { rel: "stylesheet", - href: "https://fonts.googleapis.com/css2?family=Spectral:ital,wght@0,400;0,500;0,600;1,400;1,500&family=IBM+Plex+Mono:wght@400;500&display=swap", + href: "https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,300;0,400;0,500;0,600;1,400;1,500&family=JetBrains+Mono:wght@400;500&display=swap", }, }, ], @@ -81,11 +82,24 @@ export default defineConfig({ label: "Examples", autogenerate: { directory: "examples" }, }, + { + label: "Tools", + badge: { text: "new", variant: "tip" }, + items: [ + { + label: "Sketch", + slug: "tools/sketch", + badge: { text: "live", variant: "success" }, + }, + { label: "All tools", slug: "tools" }, + ], + }, { label: "Decisions (ADRs)", autogenerate: { directory: "adr" }, }, ], }), + mdx(), ], }); diff --git a/package.json b/package.json index d104cdd..9d9047c 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@astrojs/check": "^0.9.9", + "@astrojs/mdx": "^5.0.4", "@astrojs/starlight": "^0.38.4", "astro": "^6.2.1", "sharp": "^0.33.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 80f35a0..61a2dff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,9 @@ importers: '@astrojs/check': specifier: ^0.9.9 version: 0.9.9(prettier@3.8.3)(typescript@5.9.3) + '@astrojs/mdx': + specifier: ^5.0.4 + version: 5.0.4(astro@6.2.1(@types/node@24.12.2)(rollup@4.60.2)(typescript@5.9.3)(yaml@2.8.3)) '@astrojs/starlight': specifier: ^0.38.4 version: 0.38.4(astro@6.2.1(@types/node@24.12.2)(rollup@4.60.2)(typescript@5.9.3)(yaml@2.8.3)) diff --git a/public/tools/sketch-app.html b/public/tools/sketch-app.html new file mode 100644 index 0000000..48470b5 --- /dev/null +++ b/public/tools/sketch-app.html @@ -0,0 +1,345 @@ + + + + + + Plinth Sketch + + + + + + + +
+
+ Example + +
+
+ + + +
+ ready +
+ +
+
+
+ Diagram source 0 lines +
+ +
+
+
+ Preview 0 nodes · 0 edges +
+
+ Type something on the left to see a diagram. +
+
+
+ + + + + diff --git a/src/assets/theme.css b/src/assets/theme.css index f994c84..5dcf959 100644 --- a/src/assets/theme.css +++ b/src/assets/theme.css @@ -1,71 +1,64 @@ -/* Plinth — Manuscript theme for Starlight. - Warm aged-paper light mode (default), warm-leather dark mode (alternate). - Palette: cream paper / dark warm charcoal / single ochre accent. - Type: Spectral throughout (display + body), IBM Plex Mono for code. - Vibe: reads like a thoughtful book about computing, not a product page. */ +/* Plinth — Wide Platform v2 theme for Starlight. + Off-white (#FBFBF9) light + warm-charcoal dark. + Sober navy single accent (#1B3A5C). Italic em → navy. + IBM Plex Sans body + JetBrains Mono code. No serifs anywhere. + Reads as a serious technical platform — not a thesis. */ -/* ── Shared tokens (both themes) ─────────────────────────────────── */ +/* ── Shared tokens ───────────────────────────────────────────────── */ :root { - --sl-font: "Spectral", "Iowan Old Style", Garamond, Georgia, serif; + --sl-font: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, sans-serif; --sl-font-system: var(--sl-font); - --sl-font-system-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace; + --sl-font-system-mono: "JetBrains Mono", "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace; - --sl-content-width: 50rem; - --sl-line-height: 1.65; + --sl-content-width: 60rem; + --sl-line-height: 1.55; --sl-line-height-headings: 1.1; - --sl-text-base: 1.0625rem; /* 17px */ + --sl-text-base: 1rem; - /* Manuscript ornamentation we'll reuse */ --plinth-rule: 1px solid var(--sl-color-hairline); } -/* Note: we don't override Starlight's `--sl-color-white|black|gray-*` ramp. - Starlight uses those semantically (gray-1 = highest-contrast text, gray-7 = - near-bg) and swaps them between light/dark. Overriding broke H1/H2 visibility - in light mode. We override only the warm palette tokens; Starlight handles - the contrast ladder. */ - -/* ── Light theme — the manuscript ────────────────────────────────── */ +/* ── Light theme — Wide Platform v2 ──────────────────────────────── */ :root, :root[data-theme="light"] { - --sl-color-bg: oklch(0.965 0.018 78); - --sl-color-bg-nav: oklch(0.95 0.02 78); - --sl-color-bg-sidebar: oklch(0.945 0.02 78); - --sl-color-bg-inline-code: oklch(0.92 0.04 75); + --sl-color-bg: #FBFBF9; + --sl-color-bg-nav: #FBFBF9; + --sl-color-bg-sidebar: #FBFBF9; + --sl-color-bg-inline-code: #F4F1EA; - --sl-color-text: oklch(0.24 0.025 50); - --sl-color-text-invert: oklch(0.965 0.018 78); - --sl-color-text-accent: oklch(0.5 0.15 55); + --sl-color-text: #0F1012; + --sl-color-text-invert: #FBFBF9; + --sl-color-text-accent: #1B3A5C; - --sl-color-accent: oklch(0.55 0.14 60); - --sl-color-accent-low: oklch(0.93 0.05 70); - --sl-color-accent-high: oklch(0.42 0.16 50); + --sl-color-accent: #1B3A5C; + --sl-color-accent-low: #DCE3EC; + --sl-color-accent-high: #3F6390; - --sl-color-border: oklch(0.85 0.03 78); - --sl-color-hairline: oklch(0.88 0.025 78); - --sl-color-hairline-light: oklch(0.92 0.02 78); - --sl-color-hairline-shade: oklch(0.82 0.03 78); + --sl-color-border: #E5E3DD; + --sl-color-hairline: #E5E3DD; + --sl-color-hairline-light: #F4F3EE; + --sl-color-hairline-shade: #C8C4BB; } -/* ── Dark theme — warm leather, never blue-black ──────────────────── */ +/* ── Dark theme — warm charcoal ──────────────────────────────────── */ :root[data-theme="dark"] { - --sl-color-bg: oklch(0.19 0.014 50); - --sl-color-bg-nav: oklch(0.22 0.014 50); - --sl-color-bg-sidebar: oklch(0.21 0.014 50); - --sl-color-bg-inline-code: oklch(0.27 0.015 50); + --sl-color-bg: #0F1012; + --sl-color-bg-nav: #14151A; + --sl-color-bg-sidebar: #14151A; + --sl-color-bg-inline-code: #1A1B20; - --sl-color-text: oklch(0.92 0.02 78); - --sl-color-text-invert: oklch(0.19 0.014 50); - --sl-color-text-accent: oklch(0.78 0.155 65); + --sl-color-text: #E8E6E1; + --sl-color-text-invert: #0F1012; + --sl-color-text-accent: #7BA3D6; - --sl-color-accent: oklch(0.72 0.155 60); - --sl-color-accent-low: oklch(0.32 0.05 60); - --sl-color-accent-high: oklch(0.88 0.13 70); + --sl-color-accent: #7BA3D6; + --sl-color-accent-low: #1F2A3A; + --sl-color-accent-high: #9BBADD; - --sl-color-border: oklch(0.32 0.014 50); - --sl-color-hairline: oklch(0.28 0.014 50); - --sl-color-hairline-light: oklch(0.25 0.014 50); - --sl-color-hairline-shade: oklch(0.36 0.014 50); + --sl-color-border: #22242A; + --sl-color-hairline: #22242A; + --sl-color-hairline-light: #1A1B20; + --sl-color-hairline-shade: #3A3D45; } /* ── Base ─────────────────────────────────────────────────────────── */ @@ -75,21 +68,7 @@ body { -webkit-font-smoothing: antialiased; text-wrap: pretty; font-feature-settings: "kern", "liga"; -} - -/* Subtle paper grain on light mode only — almost invisible, adds warmth. */ -:root[data-theme="light"] body::before { - content: ""; - position: fixed; - inset: 0; - background-image: - radial-gradient(oklch(0 0 0 / 0.012) 1px, transparent 1px), - radial-gradient(oklch(0 0 0 / 0.008) 1px, transparent 1px); - background-size: 4px 4px, 7px 7px; - background-position: 0 0, 2px 2px; - pointer-events: none; - z-index: 100; - mix-blend-mode: multiply; + font-variant-numeric: tabular-nums; } ::selection { @@ -97,100 +76,108 @@ body { color: var(--sl-color-text-invert); } -/* ── Site title (when no logo is set) ─────────────────────────────── */ +/* ── Site title (wordmark) ────────────────────────────────────────── */ .site-title { font-family: var(--sl-font); - font-weight: 500; - font-size: 1.4rem; + font-weight: 600; + font-size: 1.05rem; letter-spacing: -0.01em; } +.site-title::after { + content: "."; + color: var(--sl-color-text-accent); +} /* ── Markdown content ─────────────────────────────────────────────── */ .sl-markdown-content { - max-width: 65ch; + max-width: 64ch; } .sl-markdown-content :is(h1, h2, h3, h4, h5, h6) { font-family: var(--sl-font); - font-weight: 500; + font-weight: 600; letter-spacing: -0.018em; line-height: var(--sl-line-height-headings); text-wrap: balance; } -.sl-markdown-content h1 { font-size: 2.6rem; margin-bottom: 0.5rem; } -.sl-markdown-content h2 { font-size: 1.8rem; margin-top: 3rem; } -.sl-markdown-content h3 { font-size: 1.35rem; margin-top: 2rem; } -.sl-markdown-content h4 { font-size: 1.1rem; margin-top: 1.5rem; } +.sl-markdown-content h1 { font-size: 2.4rem; margin-bottom: 0.5rem; letter-spacing: -0.024em; } +.sl-markdown-content h2 { font-size: 1.6rem; margin-top: 2.8rem; } +.sl-markdown-content h3 { font-size: 1.2rem; margin-top: 1.8rem; } +.sl-markdown-content h4 { font-size: 1.05rem; margin-top: 1.4rem; } -/* Italic em — the manuscript's signature: ochre on italic */ +/* Italic em — the v2 signature: navy on italic */ .sl-markdown-content em, .sl-markdown-content i { font-style: italic; color: var(--sl-color-text-accent); + font-weight: 500; } -/* Strong — slightly heavier without colour shift */ .sl-markdown-content strong { font-weight: 600; color: var(--sl-color-text); } -/* Links — ochre, restrained underline */ +/* Links */ .sl-markdown-content a { color: var(--sl-color-text-accent); text-decoration: underline; - text-decoration-color: var(--sl-color-accent-low); + text-decoration-color: var(--sl-color-hairline-shade); text-underline-offset: 3px; text-decoration-thickness: 1px; - transition: text-decoration-color 0.15s; + transition: text-decoration-color 0.15s, color 0.15s; } .sl-markdown-content a:hover { + color: var(--sl-color-accent-high); text-decoration-color: var(--sl-color-accent); } /* Inline code */ .sl-markdown-content code:not(pre code) { background: var(--sl-color-bg-inline-code); - padding: 0.5px 5px; + padding: 1px 5px; border-radius: 0; - font-size: 0.92em; + font-size: 0.86em; color: var(--sl-color-text); } -/* Code blocks — accent rule on the left, like a margin annotation */ +/* Code blocks — top + bottom hairline rules, no left-border-accent */ .sl-markdown-content pre, .sl-markdown-content .expressive-code { - border-left: 2px solid var(--sl-color-accent); + border-top: 1px solid var(--sl-color-hairline-shade); + border-bottom: 1px solid var(--sl-color-hairline-shade); } .sl-markdown-content pre { padding: 1rem 1.25rem; } -/* Blockquotes — manuscript style, italic with accent rule */ +/* Blockquotes — minimalist, navy left rule */ .sl-markdown-content blockquote { border-left: 2px solid var(--sl-color-accent); padding-left: 1.5rem; margin: 1.5rem 0; font-style: italic; color: var(--sl-color-text); - font-size: 1.08em; + font-size: 1rem; line-height: 1.55; } -/* Tables */ +/* Tables — clean, two-rule (top header underline + final row) */ .sl-markdown-content table { border-collapse: collapse; - font-size: 0.95em; + font-size: 0.94em; margin: 1.5rem 0; width: 100%; } .sl-markdown-content th { - font-weight: 500; + font-weight: 600; text-align: left; - border-bottom: 2px solid var(--sl-color-hairline-shade); + border-bottom: 2px solid var(--sl-color-text); padding: 10px 14px 10px 0; color: var(--sl-color-text); - font-style: italic; + font-size: 0.86em; + letter-spacing: 0.04em; + text-transform: uppercase; } .sl-markdown-content td { border-bottom: 1px solid var(--sl-color-hairline); @@ -201,7 +188,6 @@ body { border-bottom: 1px solid var(--sl-color-hairline-shade); } -/* Horizontal rule — minimal, like the page break in a book */ .sl-markdown-content hr { border: none; border-top: 1px solid var(--sl-color-hairline-shade); @@ -209,16 +195,12 @@ body { width: 100%; } -/* Lists */ .sl-markdown-content ul li, .sl-markdown-content ol li { margin: 0.4rem 0; } -.sl-markdown-content ol { - font-variant-numeric: oldstyle-nums; -} -/* ── Sidebar (left nav) ──────────────────────────────────────────── */ +/* ── Sidebar ─────────────────────────────────────────────────────── */ .sl-sidebar-state-persist nav, nav[aria-label="Main"] { font-family: var(--sl-font); @@ -228,87 +210,79 @@ nav[aria-label="Main"] { background: var(--sl-color-bg-sidebar); } -/* Group labels — italic, like a book's section heading */ .sidebar-content details > summary, .sidebar-content .group-label, .sidebar-content .large { - font-style: italic; - font-weight: 500; + font-weight: 600; color: var(--sl-color-text); - letter-spacing: 0.01em; + letter-spacing: 0.04em; + text-transform: uppercase; + font-size: 0.78rem; + font-family: var(--sl-font); } -/* Sidebar links */ .sidebar-content a { font-family: var(--sl-font); - font-size: 0.96rem; + font-size: 0.92rem; line-height: 1.4; } .sidebar-content a[aria-current="page"] { color: var(--sl-color-text-accent); - font-style: italic; font-weight: 500; - background: transparent; + background: var(--sl-color-accent-low); + border-left: 2px solid var(--sl-color-accent); } /* ── Right rail TOC ──────────────────────────────────────────────── */ .right-sidebar h2 { - font-style: italic; - font-weight: 500; - font-size: 0.8rem; - letter-spacing: 0.06em; + font-weight: 600; + font-size: 0.78rem; + letter-spacing: 0.04em; text-transform: uppercase; - color: var(--sl-color-text-accent); + color: var(--sl-color-text); + font-family: var(--sl-font); } .right-sidebar a { font-family: var(--sl-font); - font-size: 0.92rem; + font-size: 0.86rem; } .right-sidebar a[aria-current="true"] { color: var(--sl-color-text-accent); - font-style: italic; + font-weight: 500; } -/* ── Page meta (last updated, edit link) ─────────────────────────── */ footer.sl-flex { - font-style: italic; - font-size: 0.92rem; + font-size: 0.86rem; color: var(--sl-color-gray-4); } footer.sl-flex a { color: var(--sl-color-text-accent); } -/* ── Top header rail ─────────────────────────────────────────────── */ .header { background: var(--sl-color-bg-nav); border-bottom: var(--plinth-rule); } -/* ── Search box ──────────────────────────────────────────────────── */ [data-open-modal]:hover { border-color: var(--sl-color-accent); } -/* ── Splash hero scaffolding (Hero override picks up the rest) ────── */ .hero { - padding: 5rem 0 3rem; + padding: 3rem 0 2rem; } -/* ── Page title block (non-splash pages) ─────────────────────────── */ .content-panel h1#_top { font-family: var(--sl-font); - font-weight: 500; - font-size: 2.6rem; - letter-spacing: -0.022em; + font-weight: 600; + font-size: 2.4rem; + letter-spacing: -0.024em; line-height: 1.05; text-wrap: balance; } -/* ── Pagination links ────────────────────────────────────────────── */ .pagination-links a { font-family: var(--sl-font); - font-style: italic; border: 1px solid var(--sl-color-hairline); background: var(--sl-color-bg); } @@ -316,22 +290,19 @@ footer.sl-flex a { border-color: var(--sl-color-accent); } -/* ── Asides / callouts ───────────────────────────────────────────── */ .starlight-aside { border-left: 2px solid var(--sl-color-accent); background: transparent; padding-left: 1.25rem; - font-style: italic; } .starlight-aside--note { border-left-color: var(--sl-color-accent); } -.starlight-aside--caution { border-left-color: oklch(0.65 0.18 30); } -.starlight-aside--danger { border-left-color: oklch(0.55 0.22 25); } -.starlight-aside--tip { border-left-color: oklch(0.6 0.14 145); } +.starlight-aside--caution { border-left-color: #B43A3A; } +.starlight-aside--danger { border-left-color: #8B1A1A; } +.starlight-aside--tip { border-left-color: #2D6E4E; } .starlight-aside__title { - font-style: normal; - font-weight: 500; + font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; - font-size: 0.78rem; + font-size: 0.74rem; color: var(--sl-color-text-accent); } diff --git a/src/components/Hero.astro b/src/components/Hero.astro index 299de39..093b6fa 100644 --- a/src/components/Hero.astro +++ b/src/components/Hero.astro @@ -1,9 +1,7 @@ --- -// Manuscript-direction Hero override for Starlight's splash template. -// Drops Starlight's default hero markup; renders a tighter, asymmetric block -// with a serif display title (em → ochre italic), an italic deck, and primary -// + minimal CTA links. Frontmatter shape is unchanged from Starlight's stock -// hero schema, so existing index.md keeps working. +// Wide Platform v2 hero override for Starlight's splash template. +// IBM Plex Sans 600, navy period flourish, status pill below subtitle, +// filled-navy primary CTA + underlined aux links. const data = Astro.locals.starlightRoute.entry.data; const hero = data.hero; @@ -11,21 +9,23 @@ const hero = data.hero; const titleHtml = hero?.title ?? data.title ?? ""; const tagline = hero?.tagline ?? ""; const actions = hero?.actions ?? []; - -// `image` block left intentionally unused — this hero is type-first. --- -
-

- {tagline &&

{tagline}

} +
+

+ {tagline &&

{tagline}

} + + + v0.1.0 · open source · MIT + {actions.length > 0 && ( -
+ diff --git a/src/components/IFrameTool.astro b/src/components/IFrameTool.astro new file mode 100644 index 0000000..9b39c39 --- /dev/null +++ b/src/components/IFrameTool.astro @@ -0,0 +1,43 @@ +--- +// Embeds an interactive tool (an HTML file in /public/) inside a Starlight page. +// The iframe takes the full content width and a tall fixed height; on small +// viewports we collapse the height so it remains usable. +interface Props { + src: string; + title: string; + height?: string; +} +const { src, title, height = "min(78vh, 760px)" } = Astro.props as Props; +--- + +
+ +
+ + diff --git a/src/content/docs/index.md b/src/content/docs/index.md index 4e28639..9b01900 100644 --- a/src/content/docs/index.md +++ b/src/content/docs/index.md @@ -1,35 +1,26 @@ --- title: Plinth -description: An open-source platform foundation for enterprise teams running fleets of internal-tooling modules. +description: An open-source platform foundation for organisations running fleets of internal-tooling modules at regulated companies. template: splash hero: title: | - The load-bearing base for enterprise internal tooling. - tagline: A substrate, an SDK, a scaffolder. Six commitments. One Helm install. Modules grow on top — so each one isn't the platform's weakest link. + A platform foundation for internal‑tooling fleets. + tagline: Plinth is an open-source platform for organisations that operate fleets of internal-tooling modules at regulated companies — banks, insurers, healthcare, government. A substrate, an SDK, a scaffolder. One Helm install. Modules grow on top. actions: + - text: Open Plinth Sketch + link: /tools/sketch/ + variant: primary - text: Read the manifesto link: /manifesto/ - variant: primary - - text: Try it in 60 minutes - link: /start/try-it/ variant: minimal - - text: Architecture - link: /architecture/ + - text: View on GitHub + link: https://github.com/plinth-dev variant: minimal --- -:::tip[v0.1.0 just shipped] -A working SDK across Go and TypeScript, two starters, a CLI, a Backstage scaffolder, a Helm chart, and a worked example — all stable, all open. Read the [launch announcement](/launch/v0-1-0/). -::: - -## What Plinth gives a team - -A fleet of internal applications — project management, change requests, audit dashboards, HR tooling, internal admin — sharing one substrate, one SDK, one scaffolder. Modules import the platform; they don't re-implement it. +You run a fleet of internal applications — project management, change requests, audit dashboards, HR tooling, internal admin. Modules that began as starters and grew. Every one re-implements the same plumbing: identity, authorisation, audit, observability, deployment. Every one inherits the same gaps: a session secret committed in `.env.example`, an authorisation layer that fails open in dev mode, no real healthcheck, no centralised logs. -- **Substrate.** A Helm umbrella chart that brings up the entire reference architecture on a fresh Kubernetes cluster. Identity, authorization, secrets, data, observability, security, GitOps, dev portal — one `helm install`. -- **SDK.** Versioned Go and TypeScript packages encoding the platform contracts: fail-closed Cerbos client, audit publisher, OTel wiring, typed errors, healthcheck, server-action forms. Imported, not copy-pasted. -- **Scaffolder.** A CLI (`plinth new `) and a Backstage software template. Five minutes from idea to deployed-in-dev. -- **Manifesto.** Six commitments — zero standing trust, GitOps everything, immutable infrastructure, durable workflows, evidence by default, open source first. The opinions that shape every default. +Plinth is the foundation those modules should have stood on from day one. *A substrate, an SDK, a scaffolder* — assembled into something a small platform team can deploy, and let dozens of modules grow on top of without each one becoming the platform's weakest link. ## Who it's for @@ -37,9 +28,26 @@ Organisations that run **multiple internal-facing modules**, operate in a **regu Not for single-product startups, cloud-native teams already happy with managed services, or teams uncomfortable operating Kubernetes. +## What's shipped + +| Repository | What it is | Install | +|---|---|---| +| `platform` | Helm umbrella chart. CloudNativePG, Cerbos, OpenTelemetry Collector. Walking-skeleton dev profile. | `git clone && helm install` | +| `sdk-go` (×7) | Fail-closed authz, non-blocking audit, OTel init, RFC 7807 errors, paginate, vault, health. | `go get …/sdk-go/@v0.1.0` | +| `sdk-ts` (×7) | env, api-client, authz, authz-react, forms, otel-web, tables. | `pnpm add @plinth-dev/` | +| `starter-api` | chi + pgx, every Go SDK pre-wired into one running service. | `git clone` | +| `starter-web` | Next.js 16 + React 19, every TypeScript SDK pre-wired into one app. | `git clone` | +| `cli` | `plinth new` — scaffold both starters with identifiers rewritten. | `go install …/cli/cmd/plinth@v0.1.1` | +| `scaffolder` | Backstage software template emitting the same output as the CLI. | `pnpm add @plinth-dev/scaffolder-actions` | +| `example-access-requests` | Worked internal-tool: temp-prod-access requests with approver workflow. | `git clone` | +| `sketch` | DSL → typeset SVG architecture diagrams. CLI + GitHub Action. | `npm i @plinth-dev/sketch` | + +Eight repositories, all v0.1.0, all MIT. + ## Where to go next -- **New here?** Read the [manifesto](/manifesto/) and the [architecture overview](/architecture/). -- **Curious how the substrate fits together?** Open the [interactive explorer](/explorer.html). -- **Building modules on Plinth?** Start with the [SDK design docs](/sdk/). -- **Standing it up?** Follow the [60-minute tutorial](/start/try-it/). +- **Curious about the opinions?** [Read the manifesto](/manifesto/) — six commitments that shape every default. +- **Want to see the architecture?** [Architecture overview](/architecture/) and the [interactive explorer](/explorer.html). +- **Building on Plinth?** Start with the [SDK design docs](/sdk/). +- **Try the tools** — [Plinth Sketch](/tools/sketch/) is live in your browser, no signup. +- **Standing the platform up?** Follow the [tutorial](/start/try-it/). diff --git a/src/content/docs/tools/index.md b/src/content/docs/tools/index.md new file mode 100644 index 0000000..483fb6b --- /dev/null +++ b/src/content/docs/tools/index.md @@ -0,0 +1,54 @@ +--- +title: Tools +description: Free utilities for working with Plinth and the adjacent stacks Plinth integrates — Cerbos, OpenTelemetry, CloudEvents, Helm, RFC 7807. No signup, no tracking. Each tool's source is on GitHub. +sidebar: + label: All tools + order: 100 +--- + +Free utilities for working with Plinth and the adjacent stacks Plinth integrates — Cerbos, OpenTelemetry, CloudEvents, Helm, RFC 7807. No signup. No tracking. Each tool's source is on GitHub. Each tool's URL is bookmarkable and shareable. + +## Diagrams & visualisation + +### [Sketch](/tools/sketch/) — *live* + +A visual + DSL editor for system architecture diagrams. Type a few lines of plain text — components, edges, layers — get a typeset SVG matching this site's design language. Share via URL. Export PNG / SVG / embed iframe. Available as a [CLI + GitHub Action](https://github.com/plinth-dev/sketch) so you can render diagrams at build time and embed them in any README. + +> **Use instead of** Mermaid (default chrome reads as utility), draw.io (overkill), Excalidraw (looks amateur), screenshotting Whimsical. + +```bash +npm install -g @plinth-dev/sketch +plinth-sketch architecture.sketch -o architecture.svg +``` + +### Module Preview — *coming soon* + +Type a `plinth new` command and see the resulting file tree, dependency graph, and SDK surface area in the browser before installing. + +## Configuration builders + +### OTel Config — *coming soon* + +Drag-and-drop builder for OpenTelemetry Collector configurations. Pick receivers, processors, exporters from a catalog; outputs full YAML. Imports existing configs to validate. Targets: Tempo, Jaeger, SigNoz, Honeycomb, Datadog, vendor-neutral OTLP. + +### Values Diff — *coming soon* + +Paste two Helm `values.yaml` files; see a semantic diff with schema validation against the Plinth platform chart. + +## Validators & explorers + +### Audit Explorer — *coming soon* + +Paste CloudEvents JSON-lines; validate against the 1.0 spec; render as a queryable timeline. See what Plinth's audit module emits before adopting it. + +### Problem Builder — *coming soon* + +Visual builder for RFC 7807 Problem Details JSON. Validates trace + extension fields. Generates copy-paste code for `sdk-go/errors` and `@plinth-dev/api-client`. + +### Cerbos Lint — *coming soon* + +Paste a Cerbos policy; check syntax against the v1 schema; simulate decisions against principals you define inline. + +--- + +**Want a tool that isn't here?** [File an issue](https://github.com/plinth-dev/.github/issues) describing what you'd build for an internal-tooling fleet. Tools with use cases beyond just Plinth get prioritised. diff --git a/src/content/docs/tools/sketch.mdx b/src/content/docs/tools/sketch.mdx new file mode 100644 index 0000000..07b8114 --- /dev/null +++ b/src/content/docs/tools/sketch.mdx @@ -0,0 +1,51 @@ +--- +title: Plinth Sketch +description: Type a few lines of DSL — get a typeset architecture diagram in the Plinth design language. Share via URL. Export PNG / SVG. Live in your browser. +template: splash +sidebar: + label: Sketch + badge: + text: live + variant: success + order: 1 +hero: + title: | + Plinth Sketch. + tagline: A DSL for system architecture diagrams. Output is typeset SVG in this site's design language. The diagram on the home page was made with this tool. +--- + +import IFrameTool from "../../../components/IFrameTool.astro"; + + + +## DSL syntax + +```sketch +# Comments start with #. +@layer Layer name # set the current layer + +id : Label / sublabel # define a node (sublabel optional) +a -> b : edge label # directed edge (label optional) + +@cite Custom bottom-right text # optional cite line +``` + +That's the whole language. Layers stack vertically, nodes flow horizontally inside each layer, edges are auto-routed. + +## Use it at build time + +The same DSL that powers this in-browser editor ships as `@plinth-dev/sketch` on npm. Install once, render diagrams at build time, embed the SVG in your README: + +```bash +npm install -g @plinth-dev/sketch +plinth-sketch architecture.sketch -o architecture.svg +``` + +Or wire up the [GitHub Action](https://github.com/plinth-dev/sketch) to re-render on every commit: + +```yaml +- uses: plinth-dev/sketch@v0 + with: { pattern: 'docs/**/*.sketch', commit: 'true' } +``` + +[**View source on GitHub →**](https://github.com/plinth-dev/sketch)