fix(wiki): agent harness title — pi, zot & Colibri (not just zot + Colibri)
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 <title> tag instead of the slug.
This commit is contained in:
parent
29796ab102
commit
834197e2ae
4 changed files with 41 additions and 64 deletions
|
|
@ -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>
|
||||
<title>{title} — Colibri Wiki</title>
|
||||
<style>
|
||||
:root { --bg: #fff; --fg: #1a1a1a; --link: #0366d6; --muted: #666; --border: #e0e0e0; }
|
||||
@media (prefers-color-scheme: dark) { :root { --bg: #1a1a1a; --fg: #e6e6e6; --link: #58a6ff; --muted: #999; --border: #333; } }
|
||||
body { max-width: 720px; margin: 2rem auto; padding: 0 1rem; font: 16px/1.6 system-ui; background: var(--bg); color: var(--fg); }
|
||||
nav { margin-bottom: 1.5rem; display: flex; justify-content: space-between; align-items: baseline; }
|
||||
nav { margin-bottom: 1.5rem; }
|
||||
nav a { color: var(--muted); font-size: .9rem; }
|
||||
nav .lang a { font-weight: 600; color: var(--link); }
|
||||
h1 { font-size: 1.8rem; }
|
||||
h2 { font-size: 1.4rem; margin-top: 2rem; border-bottom: 1px solid var(--border); padding-bottom: .3rem; }
|
||||
h3 { font-size: 1.1rem; margin-top: 1.5rem; }
|
||||
|
|
@ -138,13 +118,10 @@ const otherLabel = isSl ? "English" : "Slovenščina";
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<nav>
|
||||
<a href={isSl ? "/sl/" : "/"}>{isSl ? "← kazalo" : "← wiki index"}</a>
|
||||
<span class="lang"><a href={`/${otherSlug}/`}>{otherLabel}</a></span>
|
||||
</nav>
|
||||
<nav><a href="/">← wiki index</a></nav>
|
||||
<article>
|
||||
<h1>{title}</h1>
|
||||
<p set:html={content} />
|
||||
<Fragment set:html={content} />
|
||||
</article>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -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) =>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Agent harness: zot + Colibri
|
||||
# Agent harness: pi, zot & Colibri
|
||||
|
||||
← [index](./index.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)."
|
||||
---
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue