diff --git a/astro/wiki/.gitignore b/astro/wiki/.gitignore new file mode 100644 index 0000000..ddce69b --- /dev/null +++ b/astro/wiki/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +.astro/ diff --git a/astro/wiki/astro.config.mjs b/astro/wiki/astro.config.mjs new file mode 100644 index 0000000..3e3a004 --- /dev/null +++ b/astro/wiki/astro.config.mjs @@ -0,0 +1,12 @@ +import { defineConfig } from "astro/config"; + +const site = process.env.ASTRO_SITE_URL || "https://wiki.clawdie.si"; +const outDir = process.env.ASTRO_OUT_DIR || "./dist"; + +// https://astro.build/config +export default defineConfig({ + site, + outDir, + output: "static", + trailingSlash: "always", +}); diff --git a/astro/wiki/package.json b/astro/wiki/package.json new file mode 100644 index 0000000..8c29066 --- /dev/null +++ b/astro/wiki/package.json @@ -0,0 +1,14 @@ +{ + "name": "clawdie-wiki", + "private": true, + "version": "0.12.0", + "type": "module", + "scripts": { + "dev": "astro dev --host 0.0.0.0", + "build": "astro build", + "preview": "astro preview --host 0.0.0.0" + }, + "dependencies": { + "astro": "^5.16.11" + } +} diff --git a/astro/wiki/src/pages/[...slug].astro b/astro/wiki/src/pages/[...slug].astro new file mode 100644 index 0000000..d27194c --- /dev/null +++ b/astro/wiki/src/pages/[...slug].astro @@ -0,0 +1,131 @@ +--- +import fs from "node:fs"; +import path from "node:path"; + +const WIKI_DIR = path.resolve("../../docs/wiki"); +const EXCLUDE = [".git", "sl", "index.md"]; + +export function getStaticPaths() { + function walk(dir, prefix = "") { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + const slugs = []; + for (const e of entries) { + if (e.name.startsWith(".") || EXCLUDE.includes(e.name)) continue; + const full = path.join(dir, e.name); + if (e.isDirectory()) { + slugs.push(...walk(full, prefix ? `${prefix}/${e.name}` : e.name)); + } else if (e.name.endsWith(".md")) { + const rel = prefix ? `${prefix}/${e.name}` : e.name; + slugs.push({ params: { slug: rel.replace(/\.md$/, "") } }); + } + } + return slugs; + } + return walk(WIKI_DIR); +} + +const { slug } = Astro.params; +const filePath = path.join(WIKI_DIR, `${slug}.md`); + +if (!fs.existsSync(filePath)) { + return new Response("Not found", { status: 404 }); +} + +const raw = fs.readFileSync(filePath, "utf-8"); + +// Parse frontmatter +let content = raw; +let frontmatter = {}; +if (raw.startsWith("---")) { + const end = raw.indexOf("---", 3); + if (end !== -1) { + const fm = raw.slice(3, end); + for (const line of fm.split("\n")) { + const m = line.match(/^(\w+):\s*(.+)$/); + if (m) frontmatter[m[1]] = m[2].replace(/^["']|["']$/g, ""); + } + content = raw.slice(end + 3).trim(); + } +} + +// Resolve relative wiki links [label](./page.md) → [label](/page/) +const resolveLinks = (md) => + md.replace(/\]\(\.\/([^)]+)\.md\)/g, "](/$1/)") + .replace(/\]\(\.\.\/([^)]+)\.md\)/g, "](/$1/)"); + +content = resolveLinks(content); + +// Render fenced code blocks +const renderCode = (md) => + md.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) => { + return `
${code.trim()}
`; + }); + +content = renderCode(content); + +// Render tables +const renderTables = (md) => { + return md.replace(/\|(.+)\|\n\|[-| ]+\|\n((?:\|.+\|\n?)*)/gm, (_, header, rows) => { + const hcells = header.split("|").map(c => c.trim()).filter(Boolean); + const thead = `${hcells.map(c => `${c}`).join("")}`; + const tbody = rows.trim().split("\n").map(row => { + const cells = row.split("|").map(c => c.trim()).filter(Boolean); + return `${cells.map(c => `${c}`).join("")}`; + }).join(""); + return `${thead}${tbody}
`; + }); +}; +content = renderTables(content); + +// Render inline code, bold, italic, links, headings, lists +content = content + .replace(/`([^`]+)`/g, "$1") + .replace(/\*\*([^*]+)\*\*/g, "$1") + .replace(/\*([^*]+)\*/g, "$1") + .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1') + .replace(/^### (.+)$/gm, "

$1

") + .replace(/^## (.+)$/gm, "

$1

") + .replace(/^# (.+)$/gm, "

$1

") + .replace(/^- (.+)$/gm, "
  • $1
  • ") + .replace(/((?:
  • .*<\/li>\n?)+)/g, "") + .replace(/\n\n/g, "

    ") + .replace(/^(.+)$/gm, (line) => { + if (line.startsWith("<")) return line; + return line; + }); + +const title = frontmatter.title || slug; +--- + + + + + + {(title)} — Colibri Wiki + + + +

    +
    +

    {title}

    +

    +

    + + diff --git a/astro/wiki/src/pages/index.astro b/astro/wiki/src/pages/index.astro new file mode 100644 index 0000000..5e628c2 --- /dev/null +++ b/astro/wiki/src/pages/index.astro @@ -0,0 +1,60 @@ +--- +import fs from "node:fs"; +import path from "node:path"; + +const WIKI_DIR = path.resolve("../../docs/wiki"); +const EXCLUDE = [".git", "sl", "index.md"]; + +function walkMarkdown(dir, prefix = "") { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + const files = []; + for (const e of entries) { + if (e.name.startsWith(".") || EXCLUDE.includes(e.name)) continue; + const full = path.join(dir, e.name); + if (e.isDirectory()) { + files.push(...walkMarkdown(full, prefix ? `${prefix}/${e.name}` : e.name)); + } else if (e.name.endsWith(".md")) { + const rel = prefix ? `${prefix}/${e.name}` : e.name; + const slug = rel.replace(/\.md$/, ""); + // Skip frontmatter, grab first H1 as title + const raw = fs.readFileSync(full, "utf-8"); + const title = raw.match(/^#\s+(.+)$/m)?.[1] || slug; + files.push({ slug, title, file: rel }); + } + } + return files.sort((a, b) => a.title.localeCompare(b.title)); +} + +const pages = walkMarkdown(WIKI_DIR); +--- + + + + + + Colibri Wiki + + + +

    Colibri Wiki

    +

    + Decision pages — the why behind the architecture. + LLM Wiki pattern. +

    + + + diff --git a/docs/PLAN-WIKI-CLAWDIE-SI.md b/docs/PLAN-WIKI-CLAWDIE-SI.md new file mode 100644 index 0000000..69561d2 --- /dev/null +++ b/docs/PLAN-WIKI-CLAWDIE-SI.md @@ -0,0 +1,49 @@ +# wiki.clawdie.si — separate domain for decision pages + +**Status:** planned · **Created:** 26.jun.2026 · **Blocks:** nothing in 0.12 + +## Goal + +Split the current docs.clawdie.si (single site) into two domains during the +Astro migration from clawdie-ai → colibri: + +``` +docs.clawdie.si → guide (procedural: install, operate, reference) +wiki.clawdie.si → wiki (decisions: architecture rationale, LLM-wiki) +clawdie.si → landing (unchanged) +``` + +## Why + +- Wiki stays pure Karpathy LLM-wiki pattern — one decision per page, flat list +- Guide stays procedural — structured sidebar with install/operate/architecture +- Different audiences: wiki for agents/architects, guide for operators +- ISO can toggle each surface independently (FEATURE_DOCS, FEATURE_WIKI) + +## What needs building + +| Layer | Task | +|---|---| +| DNS | `wiki.clawdie.si` A/AAAA → same host | +| TLS | New Let's Encrypt cert (acme.sh auto-renew) | +| Nginx | New vhost for wiki.clawdie.si | +| Astro | Two Starlight configs from one colibri source tree | +| Build | `build-docs.sh` → dist-guide/ + dist-wiki/ | +| ISO | `FEATURE_DOCS` / `FEATURE_WIKI` toggle knobs | + +## Two Starlight configs + +``` +colibri/astro/ + guide.config.mjs → full sidebar: Install, Operate, Architecture... + wiki.config.mjs → minimal sidebar: autogenerate flat article list +``` + +Same toolchain, two configs, two output dirs. Wiki uses autogenerate — no +manual sidebar to maintain as pages are added. + +## Prerequisite + +The Astro build pipeline must be migrated from clawdie-ai to colibri first. +The content already lives in colibri (docs/guide/ + docs/wiki/). The build +scripts and Astro config don't yet. diff --git a/scripts/build-wiki.sh b/scripts/build-wiki.sh new file mode 100755 index 0000000..e91d189 --- /dev/null +++ b/scripts/build-wiki.sh @@ -0,0 +1,29 @@ +#!/bin/sh +# Build the Colibri wiki site — plain Astro, no Starlight. +# +# Prerequisites: Node.js + npm (node24 npm-node24 on FreeBSD). +# cd astro/wiki && npm ci +# +# Usage: +# ./scripts/build-wiki.sh # build to astro/wiki/dist/ +# ./scripts/build-wiki.sh --preview # dev server at localhost:4321 +# +# Site URL override: +# ASTRO_SITE_URL=https://wiki.clawdie.si ./scripts/build-wiki.sh + +set -eu + +SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) +REPO_ROOT=$(cd "$SCRIPT_DIR/.." && pwd) +WIKI_DIR="$REPO_ROOT/astro/wiki" + +cd "$WIKI_DIR" + +if [ "${1:-}" = "--preview" ]; then + echo "==> wiki dev server (http://localhost:4321)" + npx astro dev --host 0.0.0.0 +else + echo "==> building wiki ($WIKI_DIR)" + npx astro build + echo "==> wiki built → $WIKI_DIR/dist/" +fi