CodeVetter · Repo Unpack · Contributor handoff
earendil-works/pi
AGENTS.md is unusually prescriptive and must be read first: erasable-TypeScript-only syntax (no enums/namespaces/parameter properties — Node strip-only mode), no inline imports, top-level imports only, no `any` unless necessary, no hardcoded key checks (use DEFAULT_*_KEYBINDINGS). After code changes run `npm run check` fully; never run npm run build or npm test unless asked; use ./test.sh or targeted vitest/node --test. Never edit generated files (models.generated.ts); regenerate via scripts. Stage explicit paths only — concurrent pi sessions share the worktree.
- Read first: AGENTS.md (all rules), then packages/coding-agent/src/main.ts (dispatch), src/core/agent-session.ts (session core), src/core/extensions/types.ts (ExtensionAPI), src/core/session-manager.ts (persistence), and packages/agent/src/agent-loop.ts (the loop).
- Code style: tabs with indentWidth 3, lineWidth 120, biome recommended rules; only erasable TypeScript in packages/*/src and test dirs (no enum, namespace, parameter properties, import=) because Node runs sources in strip-only mode during development.
- After code changes run `npm run check` with full output (no tail) and fix all errors/warnings/infos; it runs biome, pinned-dep checks, tsgo --noEmit, entry-graph, shrinkwrap and browser-smoke checks — it does NOT run tests.
- Test commands: ./test.sh for the suite (scrubs env/API keys); single vitest file via node node_modules/vitest/dist/cli.js --run test/x.test.ts from the package root; node --test for packages/tui; harness/suite tests must use test/suite/harness.ts + faux provider — never real provider APIs or paid tokens.
- Changelog convention: per-package packages/*/CHANGELOG.md with fixed [Unreleased] subsections (Breaking Changes/Added/Changed/Fixed/Removed); released sections are immutable; attribution format links to issues/PRs.
- Dependency changes are treated as reviewed code: direct deps pinned exactly (save-exact=true, min-release-age=2), installs use --ignore-scripts, lockfile commits require PI_ALLOW_LOCKFILE_CHANGE=1, and coding-agent shrinkwrap regeneration goes through scripts/generate-coding-agent-shrinkwrap.mjs with an explicit lifecycle-script allowlist.
- Git safety: stage only files you changed (git add <paths>, never -A), check git status first, commit format {feat,fix,docs}[(ai,tui,agent,coding-agent)]: msg, never run reset --hard/checkout ./clean -fd/stash/--no-verify — other pi sessions may share the worktree.
- When fixing a GitHub issue, add a regression test with a comment containing the issue number; when a fix needs a test file, run it and iterate until it passes.
- Trap: models.generated.ts and image-models.generated.ts are generated — edit packages/ai/scripts/generate-models.ts (or generate-image-models.ts) and regenerate instead; the generated diff may include unrelated upstream model metadata and that's acceptable.
- Trap: project trust affects behavior — project-local .pi resources (settings, extensions, skills) silently don't load when untrusted, so tests/manual runs may differ from what a repo's .pi directory suggests; use --approve/-a or --no-approve/-na to control it.
- Trap: session state leaks between runs under ~/.pi/agent (sessions, auth.json, settings.json, models.json); tests must isolate HOME (as test.sh does) or AgentSession will pick up real credentials and sessions.
- The build order matters — root `build` script chains packages explicitly; coding-agent's build also runs scripts/build-coding-agent-bundle.mjs and copy-assets (themes, export-html template, vendor JS) so asset changes need the copy step, not just tsgo.
- Safe edit boundaries: prefer adding extensions/examples over core changes (CONTRIBUTING.md: 'pi's core is minimal; PRs that bloat the core will likely be rejected'); new slash commands go through registerCommand, new tools through createXTool + the index.ts factory switch.