Initialize repository with harness code and assets

Initial import of all source code, config, and README assets: the
packages workspace (cli, core, server, web, docs, landing, skills),
build scripts, tooling config, and CI workflows.

Includes the data-layout revision made on this branch: the local data
root defaults to ~/.penguin/data (PENGUIN_HOME still overrides; the
installer keeps its binaries in ~/.penguin), and every Agent lives
under <project>/agents/<agent>/ — path helpers, the three
agent-enumeration scans, the system prompt, built-in Skills, tests
and docs all follow the new layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ihk8iQuo3kv2aPjAYEPuR
This commit is contained in:
Yaowei Zheng
2026-07-19 14:06:53 +08:00
committed by GitHub
parent 056bed7aeb
commit 45bfae6e94
543 changed files with 92949 additions and 0 deletions
+60
View File
@@ -0,0 +1,60 @@
/**
* Docs index: local Markdown pages imported at build time via import.meta.glob.
* File naming: content/<slug>.<lang>.md — one file per page per language; a page
* missing the active language falls back to the other one, so navigation is always
* complete in both locales. Same architecture as the landing page blog.
*/
import { parseFrontmatter } from "./frontmatter";
import type { Locale } from "../state/locale";
export interface DocPage {
slug: string;
lang: Locale;
title: string;
/** One-line summary rendered under the title (optional). */
description: string;
body: string;
}
const files = import.meta.glob("../../content/*.md", {
query: "?raw",
import: "default",
eager: true,
}) as Record<string, string>;
function toDoc(path: string, raw: string): DocPage | null {
const file = path.split("/").pop() ?? "";
const match = /^(.+)\.(zh|en)\.md$/.exec(file);
if (!match) return null;
const { meta, body } = parseFrontmatter(raw);
return {
slug: match[1]!,
lang: match[2] as Locale,
title: meta.title ?? match[1]!,
description: meta.description ?? "",
body,
};
}
const ALL: DocPage[] = Object.entries(files)
.map(([path, raw]) => toDoc(path, raw))
.filter((doc): doc is DocPage => doc !== null);
/** The locale's version of a page (fallback to the other language). */
export function getDoc(slug: string, locale: Locale): DocPage | undefined {
const candidates = ALL.filter((doc) => doc.slug === slug);
return candidates.find((doc) => doc.lang === locale) ?? candidates[0];
}
/** Localized page title for sidebar / pagination labels. */
export function docTitle(slug: string, locale: Locale): string {
return getDoc(slug, locale)?.title ?? slug;
}
/**
* The page as plain Markdown (title heading + body) — what the per-page
* "Copy Markdown" button puts on the clipboard.
*/
export function docMarkdown(doc: DocPage): string {
return `# ${doc.title}\n\n${doc.body}\n`;
}
+31
View File
@@ -0,0 +1,31 @@
/**
* Minimal frontmatter parser for doc pages: a leading `---` block of `key: value`
* lines (values may contain colons; quotes optional). Kept dependency-free and pure
* so it is unit-testable without Vite. Same format as the landing page blog.
*/
export interface Frontmatter {
meta: Record<string, string>;
body: string;
}
export function parseFrontmatter(raw: string): Frontmatter {
const normalized = raw.replace(/\r\n/g, "\n");
const match = /^---\n([\s\S]*?)\n---\n?/.exec(normalized);
if (!match) return { meta: {}, body: normalized.trim() };
const meta: Record<string, string> = {};
for (const line of match[1]!.split("\n")) {
const idx = line.indexOf(":");
if (idx === -1) continue;
const key = line.slice(0, idx).trim();
let value = line.slice(idx + 1).trim();
if (
(value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))
) {
value = value.slice(1, -1);
}
if (key) meta[key] = value;
}
return { meta, body: normalized.slice(match[0].length).trim() };
}
+12
View File
@@ -0,0 +1,12 @@
/** External links and language-independent constants used across the docs site. */
export const REPO_URL = "https://github.com/Prism-Shadow/penguin-harness";
export const LICENSE_URL = `${REPO_URL}/blob/main/LICENSE`;
/**
* The main site sits one level above the docs (both ship in one GitHub Pages
* artifact: landing at "/<repo>/", docs at "/<repo>/docs/"). In local dev the docs
* base is "/" so this resolves to the docs root itself — the landing page runs on
* its own dev server there.
*/
export const SITE_URL = import.meta.env.BASE_URL.replace(/docs\/$/, "");
+43
View File
@@ -0,0 +1,43 @@
/**
* Docs navigation: the single source of truth for sidebar sections, page order and
* prev/next pagination. Section labels live in the strings dictionaries (S.sections);
* page titles come from each Markdown file's frontmatter. Kept pure (no import.meta)
* so the content-integrity test can import it under plain node.
*/
export interface DocsSectionDef {
/** Section id — also the key into S.sections for the localized label. */
id: "start" | "design" | "guides" | "reference";
/** Page slugs in display order; content files are content/<slug>.<zh|en>.md. */
slugs: string[];
}
export const DOCS_NAV: DocsSectionDef[] = [
{ id: "start", slugs: ["introduction", "installation", "quickstart"] },
{
id: "design",
slugs: [
"architecture",
"omni-message",
"agent-loop",
"message-flow",
"interfaces",
"tools",
"skills",
"models",
"sessions-and-traces",
],
},
{ id: "guides", slugs: ["web-app", "self-improvement"] },
{ id: "reference", slugs: ["cli", "server-api", "configuration"] },
];
/** All slugs in display order (pagination order). */
export const DOC_SLUGS: string[] = DOCS_NAV.flatMap((section) => section.slugs);
/** The docs landing page ("/" renders this slug). */
export const HOME_SLUG = DOC_SLUGS[0]!;
export function sectionOf(slug: string): DocsSectionDef | undefined {
return DOCS_NAV.find((section) => section.slugs.includes(slug));
}
+52
View File
@@ -0,0 +1,52 @@
/** English dictionary for the docs UI (same shape as `zh` in strings.ts). */
import type { Strings } from "./strings";
export const en: Strings = {
siteName: "PenguinHarness",
docsBadge: "Docs",
nav: {
home: "Website",
github: "GitHub",
openMenu: "Open navigation",
closeMenu: "Close navigation",
},
theme: {
label: "Theme",
light: "Light",
dark: "Dark",
system: "System",
},
lang: {
label: "Language",
zh: "中文",
en: "English",
system: "System",
},
sections: {
start: "Get Started",
design: "Core Design",
guides: "Guides",
reference: "Reference",
} as Record<string, string>,
doc: {
toc: "On this page",
copyMarkdown: "Copy Markdown",
copied: "Copied",
prev: "Previous",
next: "Next",
notFound: "Page not found",
backHome: "Back to docs home",
},
footer: {
repo: "GitHub repository",
license: "Apache-2.0 License",
site: "Website",
copyright: "© 2026 Prism Shadow · Open source under Apache-2.0",
},
};
+70
View File
@@ -0,0 +1,70 @@
/**
* Docs UI copy (bilingual): this file holds the Chinese dictionary `zh` and the runtime
* active dictionary `S`; the English dictionary lives in strings-en.ts (constrained to
* the same shape by the `Strings` type). Locale switching is handled by state/locale.tsx,
* which calls `setActiveStrings` and remounts the tree keyed by locale — keep `S.x`
* reads inside components. Doc page bodies are Markdown files under content/, not here.
*/
export const zh = {
siteName: "PenguinHarness",
docsBadge: "Docs",
nav: {
home: "产品主页",
github: "GitHub",
openMenu: "打开目录",
closeMenu: "关闭目录",
},
theme: {
label: "主题",
light: "浅色",
dark: "深色",
system: "跟随系统",
},
lang: {
label: "语言",
zh: "中文",
en: "English",
system: "跟随系统",
},
sections: {
start: "开始",
design: "核心设计",
guides: "使用指南",
reference: "参考",
} as Record<string, string>,
doc: {
toc: "本页目录",
copyMarkdown: "复制 Markdown",
copied: "已复制",
prev: "上一页",
next: "下一页",
notFound: "页面不存在",
backHome: "返回文档首页",
},
footer: {
repo: "GitHub 仓库",
license: "Apache-2.0 License",
site: "产品主页",
copyright: "© 2026 Prism Shadow · 基于 Apache-2.0 协议开源",
},
};
/** Dictionary shape (constrains the English dictionary so keys line up). */
export type Strings = typeof zh;
/**
* Runtime active dictionary (live binding): the locale Provider calls setActiveStrings
* to switch before render, and remounts the whole tree keyed by locale so every `S.x`
* read reflects the current language.
*/
export let S: Strings = zh;
export function setActiveStrings(next: Strings): void {
S = next;
}
+42
View File
@@ -0,0 +1,42 @@
/**
* Table-of-contents helpers: extract ##/### headings from a Markdown body (skipping
* fenced code blocks) and slugify them the same way the rendered headings do, so TOC
* anchors and heading ids always match. Pure and unit-testable; same behavior as the
* landing page blog.
*/
export interface TocEntry {
id: string;
text: string;
depth: 2 | 3;
}
/** Heading text -> anchor id (keeps CJK, lowercases latin, hyphenates spaces). */
export function slugifyHeading(text: string): string {
return text
.trim()
.toLowerCase()
.replace(/[^\p{L}\p{N}\s-]/gu, "")
.replace(/\s+/g, "-");
}
export function extractToc(body: string): TocEntry[] {
const entries: TocEntry[] = [];
let inFence = false;
for (const line of body.split("\n")) {
if (/^\s*(```|~~~)/.test(line)) {
inFence = !inFence;
continue;
}
if (inFence) continue;
const match = /^(#{2,3})\s+(.+?)\s*$/.exec(line);
if (!match) continue;
const text = match[2]!;
entries.push({
id: slugifyHeading(text),
text,
depth: match[1]!.length === 2 ? 2 : 3,
});
}
return entries;
}