@tsfpp/agents
v1.7.3
Published
Workspace AI tooling for TSF++ projects: scoped instructions, coding agents, and reusable prompts
Maintainers
Readme
@tsfpp/agents
GitHub Copilot agents, scoped instruction files, skills, and Claude Code configuration for TSF++ projects.
Installs a pre-built AI tooling layer into your project's .github/ directory. Once installed, agents are available in VS Code Copilot chat, instruction files are injected automatically whenever a matching file is open, and skills are loaded on demand based on semantic relevance.
Why this works
TSF++ enforces a small, strict set of constraints: sum types with exhaustive dispatch, total functions via Option and Result, immutable records, no hidden effects, pipelines over imperative loops. These constraints exist because algebraic code is easier for a human to reason about locally — you can understand a function from its type alone, without tracing mutations or hidden control flow.
The same properties that help humans happen to help language models significantly more. A codebase that never throws, never mutates, and always makes failure explicit in the type signature gives a model far less surface to hallucinate over. Exhaustive switch with absurd means the model cannot forget a variant. Result<T, E> means error paths are always visible in the return type. pipe makes data flow linear and readable in one pass.
In practice: the agents generate fewer violations, the audit agent catches the ones that slip through, and the refactor agent can fix them mechanically because the fix is always the same shape. The standard makes the code predictable for humans — and predictable code is cheap for a model to generate correctly.
Quickstart — greenfield project
The fastest way to create a fully configured TSF++ project is the bootstrap script. It handles everything in one command:
bash <(curl -fsSL https://raw.githubusercontent.com/tsfpp/agents/main/bootstrap/tsfpp-bootstrap.sh) my-project
cd my-projectOr, if you already have the script locally:
bash tsfpp-bootstrap.sh my-project
cd my-projectOmit the project name to bootstrap in the current directory.
What the bootstrap script does
| Step | What happens |
|------|-------------|
| 1 | git init -b main (skipped if a repo already exists) |
| 2 | pnpm init |
| 3 | Installs the full TSF++ ecosystem: typescript, @tsfpp/standard, @tsfpp/tsconfig, @tsfpp/eslint-config, @tsfpp/prelude, @tsfpp/boundary, @tsfpp/agents |
| 4 | Writes tsconfig.json extending @tsfpp/tsconfig/app |
| 5 | Writes eslint.config.js with the base TSF++ ESLint config |
| 6 | Patches package.json with type: module and typecheck, lint, check scripts |
| 7 | Creates src/index.ts with a getting-started comment |
| 8 | Runs node node_modules/@tsfpp/agents/init.mjs — installs all agents, instructions, skills, and prompts |
| 9 | Writes .gitignore (skipped if one already exists) |
| 10 | Runs pnpm exec husky install to activate pre-commit hooks |
After bootstrapping
The bootstrap script does not install @tsfpp/workflow (commit linting, release automation) or configure a git remote — those steps are intentionally separate and optional.
Add workflow tooling (recommended for real projects):
pnpm add -D @tsfpp/workflow @commitlint/cli @commitlint/config-conventional husky
node node_modules/@tsfpp/workflow/init.mjsThis installs:
commitlintwith the Conventional Commits config- Husky hooks:
commit-msg(lint) andpre-commit(typecheck + lint) - Release Please GitHub Actions workflow for automated semver releases and changelog generation
Push to GitHub — use the /trunk-init-repo prompt in Copilot chat:
/trunk-init-repoThis handles the initial conventional commit, adds the remote, pushes to main, and ensures Husky hooks are active after the git init.
Complete sequence
# 1. Bootstrap
bash tsfpp-bootstrap.sh my-project
cd my-project
# 2. Open in VS Code
code .
# 3. Add workflow tooling (optional but recommended)
pnpm add -D @tsfpp/workflow @commitlint/cli @commitlint/config-conventional husky
node node_modules/@tsfpp/workflow/init.mjs
# 4. Push to GitHub — in Copilot chat:
# /trunk-init-repoFrom there, the full agent workflow is available immediately.
Prerequisites
All @tsfpp/* packages must be installed in the consumer project. The agents reference their documentation from node_modules/@tsfpp/*/ at runtime — this gives them stable, version-locked access to the standard and API surface without bundling duplicate content.
pnpm add -D \
@tsfpp/standard \
@tsfpp/prelude \
@tsfpp/boundary \
@tsfpp/eslint-config \
@tsfpp/tsconfigInstallation
pnpm add -D @tsfpp/agents
node node_modules/@tsfpp/agents/init.mjsThe init script copies all files into your project and prompts before overwriting anything that already exists. Commit the generated files — they are workspace configuration, not build artefacts.
Non-interactive mode
node node_modules/@tsfpp/agents/init.mjs --yesCopies all package-managed files without prompting. Skips eslint.config.js and tsconfig.json — those are workspace-owned and never touched automatically. Use this in postinstall scripts:
{
"scripts": {
"postinstall": "node node_modules/@tsfpp/agents/init.mjs --yes"
}
}This ensures agents and instructions stay up to date with the installed package version on every pnpm install.
Re-run without reinstalling
node node_modules/@tsfpp/agents/init.mjsWhat gets installed
.github/
copilot-instructions.md ← always-on workspace context
instructions/
tsfpp-base.instructions.md ← applyTo: **/*.ts
tsfpp-prelude.instructions.md ← applyTo: **/*.ts
tsfpp-api.instructions.md ← applyTo: routes, handlers, api dirs
tsfpp-react.instructions.md ← applyTo: **/*.tsx
tsfpp-testing.instructions.md ← applyTo: **/*.{test,spec}.{ts,tsx}
trunk.instructions.md ← applyTo: git workflow contexts
agents/
tsfpp-tdd.agent.md
tsfpp-backfill-tests.agent.md
tsfpp-guarded-coding.agent.md
tsfpp-debug.agent.md
tsfpp-audit.agent.md
tsfpp-refactor-engineer.agent.md
tsfpp-annotate.agent.md
trunk-commit.agent.md
trunk-enforcer.agent.md
trunk-release.agent.md
prompts/
trunk-init-repo.prompt.md
tsfpp-new-module.prompt.md
tsfpp-boundary-review.prompt.md
skills/
coding-standard/SKILL.md
prelude-api/SKILL.md
boundary-api/SKILL.md
react-coding-standard/SKILL.md
test-standard/SKILL.md
annotation-standard/SKILL.md
.claude/
CLAUDE.md ← Claude Code project contextAgents
| Agent | Purpose |
|-------|---------|
| tsfpp-tdd | The mandatory first step for new functionality. Writes a failing test suite that specifies the behaviour before any implementation exists. Verifies every test is red for assertion reasons, then hands off to tsfpp-guarded-coding. |
| tsfpp-backfill-tests | Writes tests for existing code that has no coverage. Reads the implementation, derives the implicit contract, writes passing tests, and reports uncovered edge cases and implementation gaps. |
| tsfpp-guarded-coding | Writes TSF++-compliant TypeScript. Infers the active layer from context (core · api · dal · react · cli); applies layer-specific constraints automatically. Refuses to start without failing tests in place. Runs tsc --noEmit after every file edit via a PostToolUse hook. |
| tsfpp-debug | Diagnoses TSF++ bugs before fixing. Reproduces failures, classifies root cause (Result/Option propagation, boundary leak, ADT mismatch, etc.), emits a structured debug report, then applies a minimal fix without type widening. |
| tsfpp-audit | Audits a target path, package, or layer for TSF++ violations. Supports focus areas: types · boundary · complexity · loc · annotations · security · react · data · prelude · test · all. Creates a structured markdown report in docs/audits/ with per-slice checkboxes and a deviation register. |
| tsfpp-refactor-engineer | Reads an audit report and fixes violations slice by slice. Updates the report as it goes. Never resolves a violation by weakening a type. |
| tsfpp-annotate | Adds missing JSDoc blocks, module headers, inline comments (invariants, rejected alternatives, external contracts), DEVIATION(N.M) comments, paired eslint-disable annotations, and structured code markers (TODO, FIXME, HACK, NOTE, OPTIMIZE, BUG, XXX). Never touches runtime code. Uses the /annotation-standard skill. |
| trunk-commit | Analyzes the dirty working tree, groups changes into logical Conventional Commits, executes commits directly, and updates the CHANGELOG.md Unreleased section. |
| trunk-enforcer | Enforces trunk-based workflow conventions: branch hygiene, commit format, and release readiness checks before PR handoff. |
| trunk-release | Release assistant for Conventional Commit analysis, semver bump selection, and release artifact preparation (CHANGELOG.md, package.json, and release-please-manifest.json). |
Workflow
The agents hand off to each other. Each handoff is opt-in — the developer reviews and approves each transition via the handoff buttons in Copilot chat.
New functionality (TDD first)
tsfpp-tdd write failing tests
→ tsfpp-guarded-coding implement against the tests
→ tsfpp-audit verify compliance
→ tsfpp-refactor-engineer fix any violations
→ tsfpp-annotate document the resultExisting code without tests
tsfpp-backfill-tests write passing tests from the existing contract
→ tsfpp-audit verify test compliance + coverage
→ tsfpp-refactor-engineer fix violations in tests or implementationCompliance audit only
tsfpp-audit audit target with chosen focus
→ tsfpp-refactor-engineer fix violations
→ tsfpp-annotate document deviations and markers
→ tsfpp-audit re-audit to verify fixesInstruction files
Instruction files are injected automatically by VS Code Copilot whenever a matching file is open. No explicit invocation required.
| File | Active for | Content |
|------|-----------|---------|
| tsfpp-base | **/*.ts | Forbidden constructs, required patterns, size limits, ADT idioms, marker format |
| tsfpp-prelude | **/*.ts | Full @tsfpp/prelude API: Option, Result, ReadonlyMap, ReadonlySet, List, combinators, record decoding |
| tsfpp-api | Routes, handlers, api dirs | Handler shape, @tsfpp/boundary imports, Zod validation, middleware composition, status codes, security baseline |
| tsfpp-react | **/*.tsx | Component shape, discriminated union state, state elimination ladder, useEffect policy, TanStack Query, RHF+Zod, cva/cn styling |
| tsfpp-testing | **/*.{test,spec}.{ts,tsx} | AAA structure, factory usage, fast-check property tests, MSW, RTL query hierarchy, forbidden patterns |
| trunk | Git workflow contexts | Conventional Commits, branch naming, PR discipline, trunk-based development rules |
The workspace-level copilot-instructions.md is always active regardless of which file is open. It establishes the TSF++ axioms, the prelude-first principle, and the absolute non-negotiables.
Skills
Skills are loaded automatically by Copilot based on semantic match with what is being discussed. Unlike instruction files, skills are not file-scoped — they are injected into the context when the model determines they are relevant.
| Skill | Loaded when |
|-------|------------|
| coding-standard | Writing or reviewing TypeScript; checking rules; auditing compliance |
| prelude-api | Importing from or discussing @tsfpp/prelude; choosing between combinators |
| boundary-api | Writing handlers; discussing HTTP error mapping, pagination, or middleware |
| react-coding-standard | Writing React components, hooks, forms, or stores |
| test-standard | Writing or reviewing test files; discussing coverage or test structure |
| annotation-standard | Writing or reviewing any comment, JSDoc block, module header, code marker, or DEVIATION; discussing what to annotate and why |
| log-standard | Writing or reviewing logging code, Logger port implementations, withRequestLog usage, or tap/tapErr side effects |
| config-standard | Writing or reviewing config loaders, loadConfig usage, Config types, .env.example, or process.env access |
Skills are distilled from the full standard documents — concise enough to fit in the model's context without crowding out code.
Prompts
Reusable slash commands available in Copilot chat.
| Prompt | Purpose |
|--------|---------|
| /trunk-init-repo | Initialises a git repository with main branch, .gitignore, an initial conventional commit, optional remote, and Husky hook activation. Run once after bootstrapping. |
| /trunk-changelog | Inspects the current working tree diff, derives the correct conventional commit message, and appends a matching entry to the ## [Unreleased] section of CHANGELOG.md. |
| /tsfpp-new-module | Scaffolds a new TSF++ module with the correct file structure, barrel export, and JSDoc stubs. |
| /tsfpp-boundary-review | Reviews an HTTP handler against the full @tsfpp/boundary contract. |
How agents reference the standard
Each agent reads TSF++ standards directly from node_modules/@tsfpp/standard/spec/ and the prelude API from node_modules/@tsfpp/prelude/ at runtime. This means:
- The agent always enforces the version of the standard your project has installed.
- Upgrading
@tsfpp/standardautomatically updates what the agents enforce — no changes to agent files required. - The agent files contain workflow logic, checklist structure, and layer-specific patterns — not rule content. Rule content lives in the standard packages.
Further reading
@tsfpp/standard— the normative coding standard@tsfpp/prelude— the functional prelude@tsfpp/boundary— HTTP boundary primitives@tsfpp/eslint-config— ESLint flat config@tsfpp/tsconfig— TypeScript compiler presets
Release process
Releases are automated with Release Please.
- Use Conventional Commits in merged PRs.
- Release Please opens or updates a release PR on each merge to
main. - Merging the release PR publishes to npm, creates a GitHub release, and updates
CHANGELOG.md.
License
MIT
