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 ZhengandClaude Opus 4.8 authored and GitHub committed 2026-07-19 14:06:53 +08:00
1 parent 056bed7aeb
commit 45bfae6e94
543 files changed
+92949

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { assertValidId, isValidId, loadOrInitAgentState } from "../src/state/index.js";
describe("isValidId / assertValidId", () => {
const valid = ["default_project", "default_agent", "my-agent", "agent-1", "ABC_123"];
// Only alphanumerics, `_`, and `-` are allowed; dots, spaces/tabs, path separators, and any
// other character are all rejected.
const invalid = [
"",
" ",
"a b",
"a\tb",
" lead",
"trail ",
"a/b",
"a\\b",
".",
"..",
"...",
"a.b",
"v1.0",
".hidden",
"中文ok",
"emoji😀",
];
it.each(valid)("接受合法单段目录名:%j", (id) => {
expect(isValidId(id)).toBe(true);
expect(() => assertValidId("project_id", id)).not.toThrow();
expect(() => assertValidId("agent_id", id)).not.toThrow();
});
it.each(invalid)("拒绝非法 id:%j", (id) => {
expect(isValidId(id)).toBe(false);
expect(() => assertValidId("agent_id", id)).toThrow();
});
it("错误信息点明 kind 与非法 id", () => {
expect(() => assertValidId("agent_id", "a/b")).toThrow(/agent_id/);
expect(() => assertValidId("agent_id", "a/b")).toThrow(/a\/b/);
expect(() => assertValidId("project_id", "..")).toThrow(/project_id/);
});
});
describe("loadOrInitAgentState id 校验", () => {
let tmpRoot: string;
let prevHome: string | undefined;
beforeEach(async () => {
prevHome = process.env.PENGUIN_HOME;
tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), "penguin-validate-id-"));
process.env.PENGUIN_HOME = tmpRoot;
});
afterEach(async () => {
if (prevHome === undefined) {
delete process.env.PENGUIN_HOME;
} else {
process.env.PENGUIN_HOME = prevHome;
}
await fs.rm(tmpRoot, { recursive: true, force: true });
});
it("agentId 含路径分隔符时抛错", async () => {
await expect(loadOrInitAgentState({ agentId: "a/b" })).rejects.toThrow(/agent_id/);
});
it("projectId 为 .. 时抛错", async () => {
await expect(loadOrInitAgentState({ projectId: ".." })).rejects.toThrow(/project_id/);
});
it("agentId 为 Windows 结尾空格变体 '.. ' 时抛错(防路径穿越绕过)", async () => {
await expect(loadOrInitAgentState({ agentId: ".. " })).rejects.toThrow(/agent_id/);
});
it("默认 id 合法,可正常初始化", async () => {
const state = await loadOrInitAgentState();
expect(state.projectId).toBe("default_project");
expect(state.agentId).toBe("default_agent");
});
});