mirror of
https://github.com/plebbit/seedit.git
synced 2026-06-11 01:25:48 -04:00
docs(agents): add generated LLM context workflow
This commit is contained in:
16
AGENTS.md
16
AGENTS.md
@@ -30,6 +30,21 @@ seedit is a serverless, adminless, decentralized Reddit-style client built on th
|
||||
- Clean up only artifacts created by the current change, such as newly unused imports or dead helper code.
|
||||
- For non-trivial work, define success criteria and verify them with the narrowest reliable checks before marking the task complete.
|
||||
|
||||
## LLM Knowledge Base Policy
|
||||
|
||||
Use compiled context for orientation, not as source of truth.
|
||||
|
||||
Source of truth:
|
||||
|
||||
- Code, tests, package manifests, docs, and runtime/live evidence when relevant.
|
||||
|
||||
Compiled context:
|
||||
|
||||
- `AGENTS.md`, directory-specific `AGENTS.md` files, `CLAUDE.md`, and repo-managed `.codex/`, `.cursor/`, and `.claude/` workflow files.
|
||||
- `docs/agent-playbooks/**`, `docs/agent-runs/**`, `docs/agent-playbooks/known-surprises.md`, and tracked `llms.txt` / `llms-full.txt` files when present.
|
||||
|
||||
Agents may use compiled context to navigate quickly, but must verify against source files before making behavioral claims or edits. External code graph, RAG, MCP, or wiki tools are optional local accelerators unless the developer explicitly asks to make one part of the committed workflow.
|
||||
|
||||
## Task Router (Read First)
|
||||
|
||||
| Situation | Required action |
|
||||
@@ -39,6 +54,7 @@ seedit is a serverless, adminless, decentralized Reddit-style client built on th
|
||||
| `package.json` changed | Run `corepack yarn install` to keep `yarn.lock` in sync |
|
||||
| Dependencies or import graph changed | Run `yarn knip` as an advisory manifest/import audit |
|
||||
| Translation key/value changed | Use `docs/agent-playbooks/translations.md` |
|
||||
| Public-facing English content or AI context changed (`README.md`, `index.html`, `AGENTS.md`, docs pages, or `scripts/generate-llms-files.mjs`) | Run `yarn llms:generate`; inspect and commit any resulting changes to `public/llms*.txt` so LLM indexes stay current |
|
||||
| Bug report in a specific file/line | Start with git history scan from `docs/agent-playbooks/bug-investigation.md` before editing |
|
||||
| `CHANGELOG.md`, `scripts/release-body.js`, or package version changed | Run `yarn changelog` if release notes need regeneration |
|
||||
| Long-running task spans multiple sessions, handoffs, or spawned agents | Use `docs/agent-playbooks/long-running-agent-workflow.md`, keep a machine-readable feature list plus a progress log, and run `./scripts/agent-init.sh` before starting a fresh feature slice |
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "node scripts/start-dev.js",
|
||||
"llms:generate": "node scripts/generate-llms-files.mjs",
|
||||
"build": "cross-env NODE_ENV=production PUBLIC_URL=./ GENERATE_SOURCEMAP=false vite build",
|
||||
"build:preload": "cross-env NODE_ENV=production vite build --config electron/vite.preload.config.js",
|
||||
"build-netlify": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" NODE_ENV=production PUBLIC_URL=./ GENERATE_SOURCEMAP=true VITE_COMMIT_REF=$COMMIT_REF CI='' vite build",
|
||||
|
||||
2075
public/llms-full.txt
Normal file
2075
public/llms-full.txt
Normal file
File diff suppressed because it is too large
Load Diff
42
public/llms.txt
Normal file
42
public/llms.txt
Normal file
@@ -0,0 +1,42 @@
|
||||
# Seedit
|
||||
|
||||
> Seedit is a static, serverless, adminless, decentralized old.reddit-style client built on the Bitsocial protocol.
|
||||
|
||||
This file is generated by `scripts/generate-llms-files.mjs`. Do not hand-edit it; update the source docs or generator config, then run `yarn llms:generate`.
|
||||
|
||||
## Canonical Links
|
||||
|
||||
- [App](https://seedit.app)
|
||||
- [Repository](https://github.com/bitsocialnet/seedit)
|
||||
- [Releases](https://github.com/bitsocialnet/seedit/releases/latest)
|
||||
- [Bitsocial protocol](https://bitsocial.net)
|
||||
- [llms-full.txt](https://seedit.app/llms-full.txt): Expanded inline corpus generated from the curated source docs.
|
||||
|
||||
## Critical Context
|
||||
|
||||
- Seedit is a client for Bitsocial communities, not a centralized forum backend.
|
||||
- Community owners create, host, and moderate their own communities.
|
||||
- The web app uses hash routing and a static app-shell deployment model.
|
||||
- For code contributions, AGENTS.md and directory-specific AGENTS.md files are the source of truth.
|
||||
|
||||
## Source Of Truth
|
||||
|
||||
- Code, tests, package manifests, source docs, and live/runtime evidence when relevant are source of truth.
|
||||
- This generated file is compiled context for orientation. Verify behavioral claims against source files before editing or concluding.
|
||||
- Repo-managed AI instructions live in `AGENTS.md` and any directory-specific `AGENTS.md` files.
|
||||
|
||||
## Core Documents
|
||||
|
||||
- [Seedit](https://github.com/bitsocialnet/seedit/blob/master/README.md): Seedit is a serverless, adminless, decentralized and open-source (old)reddit alternative built on the [Bitsocial protocol](https://bitsocial.net). Like reddit, anyone can create a seedit community, It features a simil...
|
||||
- [AGENTS.md](https://github.com/bitsocialnet/seedit/blob/master/AGENTS.md): This file defines the always-on rules for AI agents working on seedit. Use this as the default policy. Load linked playbooks only when their trigger condition applies.
|
||||
- [src/AGENTS.md](https://github.com/bitsocialnet/seedit/blob/master/src/AGENTS.md): These rules apply to `src/**`. Follow the repo-root `AGENTS.md` first, then use this file for code inside the application source tree.
|
||||
- [scripts/AGENTS.md](https://github.com/bitsocialnet/seedit/blob/master/scripts/AGENTS.md): These rules apply to `scripts/**`. Follow the repo-root `AGENTS.md` first, then use this file for automation and workflow helpers.
|
||||
- [Known Surprises](https://github.com/bitsocialnet/seedit/blob/master/docs/agent-playbooks/known-surprises.md): This file tracks repository-specific confusion points that caused agent mistakes.
|
||||
- [Long-Running Agent Workflow](https://github.com/bitsocialnet/seedit/blob/master/docs/agent-playbooks/long-running-agent-workflow.md): Use this playbook when a task is likely to span multiple sessions, handoffs, or spawned agents.
|
||||
- [Bug Investigation Workflow](https://github.com/bitsocialnet/seedit/blob/master/docs/agent-playbooks/bug-investigation.md): Use this when a bug is reported in a specific file/line/code block.
|
||||
- [Translations Workflow](https://github.com/bitsocialnet/seedit/blob/master/docs/agent-playbooks/translations.md): This project uses i18next translation files in `public/translations/{lang}/default.json`.
|
||||
- [Skills and Tools](https://github.com/bitsocialnet/seedit/blob/master/docs/agent-playbooks/skills-and-tools.md): Use this playbook when setting up/adjusting skills and external tooling.
|
||||
|
||||
## Optional
|
||||
|
||||
- [Changelog](https://github.com/bitsocialnet/seedit/blob/master/CHANGELOG.md): * **electron:** keep module-scoped Tray ref and destroy before reassign ([a33d708](https://github.com/plebbit/seedit/commit/a33d708e069c59bc52f6fc76c2e0291e27280c66))
|
||||
241
scripts/generate-llms-files.mjs
Normal file
241
scripts/generate-llms-files.mjs
Normal file
@@ -0,0 +1,241 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||||
|
||||
const config = JSON.parse(await readText("scripts/llms-config.json"));
|
||||
|
||||
for (const key of ["title", "summary", "repoUrl", "llmsFullUrl"]) {
|
||||
if (!config[key]) throw new Error(`Missing llms config key: ${key}`);
|
||||
}
|
||||
|
||||
const docs = await loadDocs(config.docs);
|
||||
const optionalDocs = await loadDocs(config.optionalDocs || []);
|
||||
|
||||
if (docs.length === 0) {
|
||||
throw new Error("No source docs found for llms generation");
|
||||
}
|
||||
|
||||
await writeOutputs(config.shortOutputs, buildShortFile(config, docs, optionalDocs));
|
||||
await writeOutputs(config.fullOutputs, buildFullFile(config, docs, optionalDocs));
|
||||
|
||||
function buildShortFile(config, docs, optionalDocs) {
|
||||
const lines = [
|
||||
`# ${config.title}`,
|
||||
"",
|
||||
`> ${config.summary}`,
|
||||
"",
|
||||
"This file is generated by `scripts/generate-llms-files.mjs`. Do not hand-edit it; update the source docs or generator config, then run `yarn llms:generate`.",
|
||||
"",
|
||||
"## Canonical Links",
|
||||
"",
|
||||
...config.links.map(([label, url]) => `- [${label}](${url})`),
|
||||
`- [llms-full.txt](${config.llmsFullUrl}): Expanded inline corpus generated from the curated source docs.`,
|
||||
"",
|
||||
"## Critical Context",
|
||||
"",
|
||||
...config.notes.map((note) => `- ${note}`),
|
||||
"",
|
||||
"## Source Of Truth",
|
||||
"",
|
||||
"- Code, tests, package manifests, source docs, and live/runtime evidence when relevant are source of truth.",
|
||||
"- This generated file is compiled context for orientation. Verify behavioral claims against source files before editing or concluding.",
|
||||
"- Repo-managed AI instructions live in `AGENTS.md` and any directory-specific `AGENTS.md` files.",
|
||||
"",
|
||||
"## Core Documents",
|
||||
"",
|
||||
...docs.map(formatDocLink)
|
||||
];
|
||||
|
||||
if (optionalDocs.length > 0) {
|
||||
lines.push("", "## Optional", "", ...optionalDocs.map(formatDocLink));
|
||||
}
|
||||
|
||||
return `${lines.join("\n")}\n`;
|
||||
}
|
||||
|
||||
function buildFullFile(config, docs, optionalDocs) {
|
||||
const allDocs = [...docs, ...optionalDocs];
|
||||
const lines = [
|
||||
`# ${config.title} Full LLM Context`,
|
||||
"",
|
||||
`> ${config.summary}`,
|
||||
"",
|
||||
"This file is generated by `scripts/generate-llms-files.mjs`. Do not hand-edit it; update the source docs or generator config, then run `yarn llms:generate`.",
|
||||
"",
|
||||
"Use this as compiled context only. Source files, tests, manifests, and live/runtime evidence remain authoritative.",
|
||||
"",
|
||||
"## Index",
|
||||
"",
|
||||
...allDocs.map((doc) => `- [${doc.relativePath}](#${anchorFor(doc.relativePath)})`),
|
||||
"",
|
||||
"---"
|
||||
];
|
||||
|
||||
for (const doc of allDocs) {
|
||||
lines.push(
|
||||
"",
|
||||
`## ${doc.relativePath}`,
|
||||
"",
|
||||
`Source: ${doc.url}`,
|
||||
"",
|
||||
"```markdown",
|
||||
doc.content.trim(),
|
||||
"```",
|
||||
"",
|
||||
"---"
|
||||
);
|
||||
}
|
||||
|
||||
return `${lines.join("\n")}\n`;
|
||||
}
|
||||
|
||||
function formatDocLink(doc) {
|
||||
return `- [${doc.title}](${doc.url}): ${doc.summary}`;
|
||||
}
|
||||
|
||||
async function loadDocs(relativePaths) {
|
||||
const docs = [];
|
||||
|
||||
for (const relativePath of relativePaths) {
|
||||
const content = await readOptional(relativePath);
|
||||
if (!content) continue;
|
||||
|
||||
docs.push({
|
||||
relativePath,
|
||||
content,
|
||||
title: titleFromMarkdown(content, relativePath),
|
||||
summary: summaryFromMarkdown(content),
|
||||
url: `${config.repoUrl}/blob/master/${encodeURI(relativePath).replace(/%2F/g, "/")}`
|
||||
});
|
||||
}
|
||||
|
||||
return docs;
|
||||
}
|
||||
|
||||
function titleFromMarkdown(content, fallback) {
|
||||
if (fallback.endsWith("CHANGELOG.md")) return "Changelog";
|
||||
if (fallback.endsWith("TODO.md")) return "TODO";
|
||||
|
||||
let inFence = false;
|
||||
let inFrontmatter = false;
|
||||
let fallbackHeading = "";
|
||||
const lines = content.split(/\r?\n/);
|
||||
|
||||
for (let index = 0; index < lines.length; index += 1) {
|
||||
const trimmed = lines[index].trim();
|
||||
|
||||
if (index === 0 && trimmed === "---") {
|
||||
inFrontmatter = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inFrontmatter) {
|
||||
if (trimmed === "---") inFrontmatter = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (trimmed.startsWith("```")) {
|
||||
inFence = !inFence;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inFence) continue;
|
||||
|
||||
const h1 = trimmed.match(/^#\s+(.+)$/);
|
||||
if (h1) return h1[1].trim();
|
||||
|
||||
const h2 = trimmed.match(/^##\s+(.+)$/);
|
||||
if (h2 && !fallbackHeading) fallbackHeading = h2[1].trim();
|
||||
}
|
||||
|
||||
return fallbackHeading || fallback;
|
||||
}
|
||||
|
||||
function summaryFromMarkdown(content) {
|
||||
const lines = content.split(/\r?\n/);
|
||||
const paragraphs = [];
|
||||
let current = [];
|
||||
let inFence = false;
|
||||
let inFrontmatter = false;
|
||||
|
||||
for (let index = 0; index < lines.length; index += 1) {
|
||||
const line = lines[index];
|
||||
const trimmed = line.trim();
|
||||
|
||||
if (index === 0 && trimmed === "---") {
|
||||
inFrontmatter = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inFrontmatter) {
|
||||
if (trimmed === "---") inFrontmatter = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (trimmed.startsWith("```")) {
|
||||
inFence = !inFence;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inFence || !trimmed || trimmed.startsWith("#") || trimmed.startsWith("|")) {
|
||||
if (current.length > 0) {
|
||||
paragraphs.push(current.join(" "));
|
||||
current = [];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
trimmed.startsWith("[![") ||
|
||||
trimmed.startsWith("_Telegram") ||
|
||||
trimmed.startsWith("<img") ||
|
||||
trimmed.startsWith("<p") ||
|
||||
trimmed.startsWith("<br") ||
|
||||
trimmed.startsWith("</") ||
|
||||
trimmed.startsWith("<!--")
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
current.push(trimmed.replace(/\s+/g, " "));
|
||||
}
|
||||
|
||||
if (current.length > 0) paragraphs.push(current.join(" "));
|
||||
|
||||
const summary = paragraphs.find(Boolean) || "Repository documentation.";
|
||||
return summary.length > 220 ? `${summary.slice(0, 217).trimEnd()}...` : summary;
|
||||
}
|
||||
|
||||
function anchorFor(value) {
|
||||
return value
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9\s-]/g, "")
|
||||
.trim()
|
||||
.replace(/\s+/g, "-");
|
||||
}
|
||||
|
||||
async function writeOutputs(relativePaths, content) {
|
||||
for (const relativePath of relativePaths) {
|
||||
const absolutePath = path.join(rootDir, relativePath);
|
||||
await mkdir(path.dirname(absolutePath), { recursive: true });
|
||||
await writeFile(absolutePath, content);
|
||||
console.log(`[llms] wrote ${relativePath}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function readOptional(relativePath) {
|
||||
try {
|
||||
return await readText(relativePath);
|
||||
} catch (error) {
|
||||
if (error && error.code === "ENOENT") return "";
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function readText(relativePath) {
|
||||
return readFile(path.join(rootDir, relativePath), "utf8");
|
||||
}
|
||||
33
scripts/llms-config.json
Normal file
33
scripts/llms-config.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"title": "Seedit",
|
||||
"summary": "Seedit is a static, serverless, adminless, decentralized old.reddit-style client built on the Bitsocial protocol.",
|
||||
"repoUrl": "https://github.com/bitsocialnet/seedit",
|
||||
"llmsUrl": "https://seedit.app/llms.txt",
|
||||
"llmsFullUrl": "https://seedit.app/llms-full.txt",
|
||||
"shortOutputs": ["public/llms.txt"],
|
||||
"fullOutputs": ["public/llms-full.txt"],
|
||||
"links": [
|
||||
["App", "https://seedit.app"],
|
||||
["Repository", "https://github.com/bitsocialnet/seedit"],
|
||||
["Releases", "https://github.com/bitsocialnet/seedit/releases/latest"],
|
||||
["Bitsocial protocol", "https://bitsocial.net"]
|
||||
],
|
||||
"notes": [
|
||||
"Seedit is a client for Bitsocial communities, not a centralized forum backend.",
|
||||
"Community owners create, host, and moderate their own communities.",
|
||||
"The web app uses hash routing and a static app-shell deployment model.",
|
||||
"For code contributions, AGENTS.md and directory-specific AGENTS.md files are the source of truth."
|
||||
],
|
||||
"docs": [
|
||||
"README.md",
|
||||
"AGENTS.md",
|
||||
"src/AGENTS.md",
|
||||
"scripts/AGENTS.md",
|
||||
"docs/agent-playbooks/known-surprises.md",
|
||||
"docs/agent-playbooks/long-running-agent-workflow.md",
|
||||
"docs/agent-playbooks/bug-investigation.md",
|
||||
"docs/agent-playbooks/translations.md",
|
||||
"docs/agent-playbooks/skills-and-tools.md"
|
||||
],
|
||||
"optionalDocs": ["CHANGELOG.md"]
|
||||
}
|
||||
Reference in New Issue
Block a user