// 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 ? `
Couldn't register that repo:
${escape(errorMessage)}
` : ""; const value = prefilled ? ` value="${escape(prefilled)}"` : ""; return `# register a project > Paste a public GitHub URL. tdd.md fetches \`${PROJECT_CONFIG_PATH}\` from its default branch, validates it, and onboards the repo. Re-register the same repo to refresh the config. ${error}
> Signed in as ${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) `; };