Thanks for contributing to fro-bot/agent. This document covers the contributor workflow — setup, the command surface, testing, and commit conventions. For how the system is built and where code lives, read these first:
- ARCHITECTURE.md — system design, invariants, the three data flows, cross-cutting concerns.
- STRUCTURE.md — directory layout, key file locations, where to add new code.
- AGENTS.md — conventions, anti-patterns, and the command reference in one operational page.
- Bun — the package manager and test runner for this monorepo.
- Node 24 — matches the
action.yamlruntime; the bundled Action anddeploy/scripts/both target it.
bun installThis installs workspace dependencies and registers the git hooks (via simple-git-hooks).
bun run test # Run the workspace package test suites plus evals/ (Vitest)
bun run test:scripts # Run the repo-root scripts/ test suite (Vitest)
bun run test:evals # Run only the evals/ suite (Vitest)
bun run lint # ESLint check (also scans committed dist/ for hidden Unicode)
bun run fix # ESLint auto-fix
bun run check-types # TypeScript type check (tsc --noEmit)
bun run build # Type-check + bundle to dist/ (dist/ is committed and must stay in sync)bun run build regenerates the committed dist/. Never edit dist/ by hand — CI fails if a fresh build produces a diff. See ARCHITECTURE.md for why dist/ is committed.
- Vitest for the workspace; test files are colocated as
<name>.test.tsnext to the code they cover. - BDD comments mark the phases of each test:
// #given,// #when,// #then. deploy/scripts/is a carve-out: plain Node ESM (.mjs) run with the built-innode --testrunner, not Vitest. It is exercised in CI by theworkspace-smokejob.evals/holds a gated agent-outcome corpus. Its pure gate, scenario, and baseline-integrity tests run as part ofbun run test; the live scenarios execute a real model and only run whenFRO_BOT_EVAL=1is set explicitly, so ordinary contributions never trigger them. Changing the agent prompt invalidates the recorded baseline — seeevals/README.mdfor the re-recording procedure.- Write the test alongside the change in the same PR; behavior changes need a test that pins the new behavior.
Type suppression is forbidden project-wide — no as any, @ts-ignore, or @ts-expect-error. See AGENTS.md for the full convention and anti-pattern list.
Follow Conventional Commits: type(scope): description.
- Types:
feat,fix,docs,refactor,test,build,ci,style,perf,revert,chore. - Releases are automated from commit history via semantic-release, so an accurate
typematters —featandfixdrive version bumps.
Example: feat(setup): add --skip-auth flag.
Hooks are installed automatically on bun install:
- pre-commit — runs
lint-staged(ESLint--fixon staged files). - pre-push — syncs
node_modulesto the lockfile (bun install --frozen-lockfile --ignore-scripts), runsbun run lint && bun run build, then fails the push if the rebuiltdist/differs fromHEAD(git diff --ignore-space-at-eol --stat --exit-code HEAD -- dist/).
Run that same chain yourself before pushing to catch failures early — a build against stale node_modules reproduces its own drift and looks clean locally.
- Keep changes minimal and reversible; minimize blast radius.
- Update tests and
README.mdwhen inputs or public behavior change. - Ensure
bun run lintandbun run buildare clean anddist/is in sync before opening the PR.