Rename .pi to .feynman, rename citation agent to verifier, add website, skills, and docs

- Rename project config dir from .pi/ to .feynman/ (Pi supports this via piConfig.configDir)
- Rename citation agent to verifier across all prompts, agents, skills, and docs
- Add website with homepage and 24 doc pages (Astro + Tailwind)
- Add skills for all workflows (deep-research, lit, review, audit, replicate, compare, draft, autoresearch, watch, jobs, session-log, agentcomputer)
- Add Pi-native prompt frontmatter (args, section, topLevelCli) and read at runtime
- Remove sync-docs generation layer — docs are standalone
- Remove metadata/prompts.mjs and metadata/packages.mjs — not needed at runtime
- Rewrite README and homepage copy
- Add environment selection to /replicate before executing
- Add prompts/delegate.md and AGENTS.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Advait Paliwal
2026-03-23 17:35:35 -07:00
parent 406d50b3ff
commit f5570b4e5a
98 changed files with 9886 additions and 298 deletions

View File

@@ -8,10 +8,10 @@ import { syncBundledAssets } from "../src/bootstrap/sync.js";
function createAppRoot(): string {
const appRoot = mkdtempSync(join(tmpdir(), "feynman-app-"));
mkdirSync(join(appRoot, ".pi", "themes"), { recursive: true });
mkdirSync(join(appRoot, ".pi", "agents"), { recursive: true });
writeFileSync(join(appRoot, ".pi", "themes", "feynman.json"), '{"theme":"v1"}\n', "utf8");
writeFileSync(join(appRoot, ".pi", "agents", "researcher.md"), "# v1\n", "utf8");
mkdirSync(join(appRoot, ".feynman", "themes"), { recursive: true });
mkdirSync(join(appRoot, ".feynman", "agents"), { recursive: true });
writeFileSync(join(appRoot, ".feynman", "themes", "feynman.json"), '{"theme":"v1"}\n', "utf8");
writeFileSync(join(appRoot, ".feynman", "agents", "researcher.md"), "# v1\n", "utf8");
return appRoot;
}
@@ -38,8 +38,8 @@ test("syncBundledAssets preserves user-modified files and updates managed files"
syncBundledAssets(appRoot, agentDir);
writeFileSync(join(appRoot, ".pi", "themes", "feynman.json"), '{"theme":"v2"}\n', "utf8");
writeFileSync(join(appRoot, ".pi", "agents", "researcher.md"), "# v2\n", "utf8");
writeFileSync(join(appRoot, ".feynman", "themes", "feynman.json"), '{"theme":"v2"}\n', "utf8");
writeFileSync(join(appRoot, ".feynman", "agents", "researcher.md"), "# v2\n", "utf8");
writeFileSync(join(agentDir, "agents", "researcher.md"), "# user-custom\n", "utf8");
const result = syncBundledAssets(appRoot, agentDir);

View File

@@ -58,10 +58,11 @@ test("buildModelStatusSnapshotFromRecords flags an invalid current model and sug
});
test("resolveInitialPrompt maps top-level research commands to Pi slash workflows", () => {
assert.equal(resolveInitialPrompt("lit", ["tool-using", "agents"], undefined), "/lit tool-using agents");
assert.equal(resolveInitialPrompt("watch", ["openai"], undefined), "/watch openai");
assert.equal(resolveInitialPrompt("jobs", [], undefined), "/jobs");
assert.equal(resolveInitialPrompt("chat", ["hello"], undefined), "hello");
assert.equal(resolveInitialPrompt("unknown", ["topic"], undefined), "unknown topic");
const workflows = new Set(["lit", "watch", "jobs", "deepresearch"]);
assert.equal(resolveInitialPrompt("lit", ["tool-using", "agents"], undefined, workflows), "/lit tool-using agents");
assert.equal(resolveInitialPrompt("watch", ["openai"], undefined, workflows), "/watch openai");
assert.equal(resolveInitialPrompt("jobs", [], undefined, workflows), "/jobs");
assert.equal(resolveInitialPrompt("chat", ["hello"], undefined, workflows), "hello");
assert.equal(resolveInitialPrompt("unknown", ["topic"], undefined, workflows), "unknown topic");
});

View File

@@ -21,7 +21,7 @@ test("loadPiWebAccessConfig returns empty config when Pi web config is missing",
test("getPiWebAccessStatus reads Pi web-access config directly", () => {
const root = mkdtempSync(join(tmpdir(), "feynman-pi-web-"));
const configPath = getPiWebSearchConfigPath(root);
mkdirSync(join(root, ".pi"), { recursive: true });
mkdirSync(join(root, ".feynman"), { recursive: true });
writeFileSync(
configPath,
JSON.stringify({