From 834197e2ae1e05be288ba6e7f2555ca3fe043b83 Mon Sep 17 00:00:00 2001 From: Sam & Claude Date: Fri, 26 Jun 2026 12:34:15 +0200 Subject: [PATCH] =?UTF-8?q?fix(wiki):=20agent=20harness=20title=20?= =?UTF-8?q?=E2=80=94=20pi,=20zot=20&=20Colibri=20(not=20just=20zot=20+=20C?= =?UTF-8?q?olibri)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The agent harness page describes THREE agents: pi (fallback), zot (default), and Colibri (supervisor). Title updated in both EN and SL. Also: H1 extraction fallback for pages without YAML frontmatter — content.match(/^#\s+(.+)$/m)?.[1] so pages with only markdown H1 still get a proper tag instead of the slug. --- astro/wiki/src/pages/[...slug].astro | 99 ++++++++++--------------- astro/wiki/src/pages/sl/[...slug].astro | 2 +- docs/wiki/agent-harness.md | 2 +- docs/wiki/sl/agent-harness.md | 2 +- 4 files changed, 41 insertions(+), 64 deletions(-) diff --git a/astro/wiki/src/pages/[...slug].astro b/astro/wiki/src/pages/[...slug].astro index 23bc196..bf16331 100644 --- a/astro/wiki/src/pages/[...slug].astro +++ b/astro/wiki/src/pages/[...slug].astro @@ -2,10 +2,9 @@ import fs from "node:fs"; import path from "node:path"; -const WIKI_DIR = path.resolve("../../docs/wiki"); -const EXCLUDE = [".git", "index.md"]; - export function getStaticPaths() { + const WIKI_DIR = path.resolve("src/content"); + const EXCLUDE = [".git", "index.md"]; function walk(dir, prefix = "") { const entries = fs.readdirSync(dir, { withFileTypes: true }); const slugs = []; @@ -25,6 +24,7 @@ export function getStaticPaths() { } const { slug } = Astro.params; +const WIKI_DIR = path.resolve("src/content"); const filePath = path.join(WIKI_DIR, `${slug}.md`); if (!fs.existsSync(filePath)) { @@ -33,7 +33,6 @@ if (!fs.existsSync(filePath)) { const raw = fs.readFileSync(filePath, "utf-8"); -// Parse frontmatter let content = raw; let frontmatter = {}; if (raw.startsWith("---")) { @@ -48,46 +47,28 @@ if (raw.startsWith("---")) { } } -// Detect locale from slug prefix -const isSl = slug.startsWith("sl/"); -const locale = isSl ? "sl" : "en"; -const base = isSl ? "/sl/" : "/"; +const title = (frontmatter.title || content.match(/^#\s+(.+)$/m)?.[1] || slug).replace(/^["']|["']$/g, ""); -// Resolve relative wiki links with locale prefix -// ./page.md → /page/ or /sl/page/ -// ../packaging/x → /../packaging/x (pass through absolute-ish paths) -const resolveLinks = (md) => - md.replace(/\]\(\.\/([^)]+)\.md\)/g, `](${base}$1/)`) - .replace(/\]\(\.\.\/([^)]+)\)/g, "](/$1)"); +// Resolve wiki links [label](./page.md) → [/page/] +content = content.replace(/\]\(\.\/([^)]+)\.md\)/g, "](/$1/)") + .replace(/\]\(\.\.\/([^)]+)\.md\)/g, "](/$1/)"); -content = resolveLinks(content); +// Fenced code blocks +content = content.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) => + `<pre><code${lang ? ` class="language-${lang}"` : ""}>${code.trim()}</code></pre>`); -// Resolve cross-wiki locale links: [label](./sl/page.md) → [/sl/page/] -content = content.replace(/\]\(\.\/sl\/([^)]+)\.md\)/g, "](/sl/$1/)"); +// Tables +content = content.replace(/\|(.+)\|\n\|[-| ]+\|\n((?:\|.+\|\n?)*)/gm, (_, header, rows) => { + const hcells = header.split("|").map(c => c.trim()).filter(Boolean); + const thead = `<tr>${hcells.map(c => `<th>${c}</th>`).join("")}</tr>`; + const tbody = rows.trim().split("\n").map(row => { + const cells = row.split("|").map(c => c.trim()).filter(Boolean); + return `<tr>${cells.map(c => `<td>${c}</td>`).join("")}</tr>`; + }).join(""); + return `<table><thead>${thead}</thead><tbody>${tbody}</tbody></table>`; +}); -// Render fenced code blocks -const renderCode = (md) => - md.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) => { - return `<pre><code${lang ? ` class="language-${lang}"` : ""}>${code.trim()}</code></pre>`; - }); - -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 = `<tr>${hcells.map(c => `<th>${c}</th>`).join("")}</tr>`; - const tbody = rows.trim().split("\n").map(row => { - const cells = row.split("|").map(c => c.trim()).filter(Boolean); - return `<tr>${cells.map(c => `<td>${c}</td>`).join("")}</tr>`; - }).join(""); - return `<table><thead>${thead}</thead><tbody>${tbody}</tbody></table>`; - }); -}; -content = renderTables(content); - -// Render inline code, bold, italic, links, headings, lists +// Inline elements content = content .replace(/`([^`]+)`/g, "<code>$1</code>") .replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>") @@ -97,33 +78,32 @@ content = content .replace(/^## (.+)$/gm, "<h2>$1</h2>") .replace(/^# (.+)$/gm, "<h1>$1</h1>") .replace(/^- (.+)$/gm, "<li>$1</li>") - .replace(/((?:<li>.*<\/li>\n?)+)/g, "<ul>$1</ul>") - .replace(/\n\n/g, "</p><p>") - .replace(/^(.+)$/gm, (line) => { - if (line.startsWith("<")) return line; - return line; - }); + .replace(/((?:<li>.*<\/li>\n?)+)/g, "<ul>$1</ul>"); -const title = frontmatter.title || slug; - -// Other locale link for language switcher -const otherLocale = isSl ? "en" : "sl"; -const otherSlug = isSl ? slug.replace(/^sl\//, "") : `sl/${slug}`; -const otherLabel = isSl ? "English" : "Slovenščina"; +// Paragraphs — wrap non-tag lines +const lines = content.split("\n"); +const wrapped = []; +for (const line of lines) { + if (line.startsWith("<") || line === "") { + wrapped.push(line); + } else { + wrapped.push(`<p>${line}</p>`); + } +} +content = wrapped.join("\n"); --- <!DOCTYPE html> -<html lang={locale}> +<html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <title>{(title)} — Colibri Wiki + {title} — Colibri Wiki - +

{title}

-

+

diff --git a/astro/wiki/src/pages/sl/[...slug].astro b/astro/wiki/src/pages/sl/[...slug].astro index 4a59e6b..2823789 100644 --- a/astro/wiki/src/pages/sl/[...slug].astro +++ b/astro/wiki/src/pages/sl/[...slug].astro @@ -46,7 +46,7 @@ if (raw.startsWith("---")) { } } -const title = (frontmatter.title || slug).replace(/^["']|["']$/g, ""); +const title = (frontmatter.title || content.match(/^#\s+(.+)$/m)?.[1] || slug).replace(/^["']|["']$/g, ""); content = content.replace(/\]\(\.\/([^)]+)\.md\)/g, "](/sl/$1/)") .replace(/\]\(\.\.\/([^)]+)\.md\)/g, "](/sl/$1/)") .replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) => diff --git a/docs/wiki/agent-harness.md b/docs/wiki/agent-harness.md index 14ff614..6aade18 100644 --- a/docs/wiki/agent-harness.md +++ b/docs/wiki/agent-harness.md @@ -1,4 +1,4 @@ -# Agent harness: zot + Colibri +# Agent harness: pi, zot & Colibri ← [index](./index.md) diff --git a/docs/wiki/sl/agent-harness.md b/docs/wiki/sl/agent-harness.md index 0aa24e5..ef66eb2 100644 --- a/docs/wiki/sl/agent-harness.md +++ b/docs/wiki/sl/agent-harness.md @@ -1,5 +1,5 @@ --- -title: "Agentska vprega: zot + Colibri" +title: "Agentska vprega: pi, zot & Colibri" description: "Dve binarni datoteki, ne ena — zot (agent, Go) in Colibri (krmilna ravnina, Rust)." ---