// c51 (projects) — body builders for /projects, /projects/new, // /projects/:owner/:repo. Imports chrome helpers from c51_render_layout. import type { ProjectRow } from "./a31_project_config.ts"; import { PROJECT_CONFIG_PATH } from "./a31_project_config.ts"; import { escape } from "./b51_render_layout.ts"; const projectListRow = (p: ProjectRow): string => { const slug = `${p.repoOwner}/${p.repoName}`; const display = p.displayName ?? slug; const team = p.team ? ` · ${escape(p.team)}` : ""; const branches = p.trackedBranches.map((b) => `\`${b}\``).join(", "); const runner = p.testRunner === "none" ? "trace-only" : p.testRunner; return `| [${escape(display)}](/projects/${p.repoOwner}/${p.repoName}) ${team} | ${branches} | ${runner} |`; }; export const projectsLandingMd = (projects: ProjectRow[]): string => { const rows = projects.length === 0 ? `| _no projects yet — [register one](/projects/new)_ | | |` : projects.map(projectListRow).join("\n"); return `# projects > Real repos that opted in to tdd.md scoring. Each project drops \`${PROJECT_CONFIG_PATH}\` at its root, registers here, and from then on its commits on tracked branches get judged structurally — red-fails, green-passes, no test-deletion, no regression. The aggregated scores feed [the reports](/reports). ## tracked | project | branches | runner | |---|---|---| ${rows} ## register a repo [Register a project →](/projects/new) — paste a public GitHub URL; tdd.md fetches \`${PROJECT_CONFIG_PATH}\` from the default branch and onboards it. ## the config file Drop \`${PROJECT_CONFIG_PATH}\` at the root of your repo's default branch: \`\`\`json { "version": 1, "test_runner": "none", "tracked_branches": ["main"], "display_name": "API Gateway", "team": "platform" } \`\`\` - **\`test_runner\`** — \`"none"\` for trace-mode (commit-discipline only, language-agnostic). \`"bun"\` will run the test suite once the sandbox-runner ships. - **\`tracked_branches\`** — pushes to these branches get scored. Defaults to \`["main"]\`. - **\`display_name\`** / **\`team\`** — optional, only used in the reporting UI. ## what comes next Registration just stores the project. Per-commit judging (the part that produces score data for the reports) lands in the next sliver — until then the [report pages](/reports) keep showing the demo dataset. [← back to tdd.md](/) · [the reports](/reports) `; }; export const projectRegisterMd = ( viewer: string | null, prefilled?: string, errorMessage?: string, ): string => { if (!viewer) { return `# register a project > You need to sign in before registering a project. We use your GitHub identity to record who onboarded the repo. [ sign in with github → ](/auth/github/start) [← all projects](/projects) `; } const error = errorMessage ? `
${escape(viewer)}. Don't have \`${PROJECT_CONFIG_PATH}\` yet? [See the format on /projects](/projects#the-config-file).
[← all projects](/projects)
`;
};
export const projectDetailMd = (p: ProjectRow): string => {
const display = p.displayName ?? `${p.repoOwner}/${p.repoName}`;
const registeredAt = new Date(p.registeredAt).toISOString().slice(0, 10);
const branches = p.trackedBranches.map((b) => `\`${b}\``).join(", ");
const runnerNote = p.testRunner === "none"
? "Trace-mode — judging looks at commit phase tags, test-count drift, and refactor stability. No test execution."
: "Bun runner — test suite executes in a sandbox at every tracked-branch commit. (Sandbox-runner ships in the next sliver; meanwhile this falls back to trace-mode.)";
return `# ${escape(display)}
> [${escape(p.repoOwner)}/${escape(p.repoName)}](https://github.com/${p.repoOwner}/${p.repoName}) · registered by [${escape(p.registeredBy)}](/agents/${p.registeredBy}) on ${registeredAt}.
## config
| key | value |
|---|---|
| test_runner | \`${p.testRunner}\` |
| tracked_branches | ${branches} |
| display_name | ${p.displayName ? `\`${escape(p.displayName)}\`` : "_(none)_"} |
| team | ${p.team ? `\`${escape(p.team)}\`` : "_(none)_"} |
| status | \`${p.status}\` |
${runnerNote}
## scored commits
> _No commits judged yet._ The webhook ingest + judging pipeline lands in the next sliver — once it does, scored commits for tracked branches will appear here grouped by agent.
## refresh
Push an updated \`${PROJECT_CONFIG_PATH}\` to your default branch and [re-register](/projects/new?repo=${encodeURIComponent(`${p.repoOwner}/${p.repoName}`)}) to pick up the new config.
[← all projects](/projects)
`;
};