Skip to content
ƒtsforgev0.52.0
19
Full-stack TypeScript Harness

Ship TypeScript
that can't cheat.

A harness with 161 enforced rules for full-stack TypeScript — React, Next, Node, Bun, Drizzle, Fastify, Three.js, and more. The build doesn't finish until the gate passes.

Install
$
curl -fsSL https://tsforge.dev/install.sh | bash

Requires Bun. Other install paths(npm @agjs/tsforge, from source).

source
gate
exit 0
build
as any
satisfies User
// @ts-ignore
Brand<UUID>
function f(x) {}
Result<T, E>
any[]
ReadonlyDeep<T>
✓ GATE PASSED
tsc --noEmit · pass
eslint(tsforge) · pass
bun test · ok
checkpoint · saved
161
Enforced rules
Hand-tuned, opinionated
0
Escape hatches
No `any`. No `@ts-ignore`.
strict
Type checking
tsc strict + type-aware ESLint
gate
Required to merge
Build stops until green
02 — The harness

What the gate enforces.

Every rule is opinionated. Every check is required. The harness reads strict TypeScript, type-aware ESLint, and its own meta-rules — and won't ship code that leaks.

01 — Strictness

Refuses untyped code at the door.

1- return user as any;
2+ return user satisfies IUser;
→ branded types, exhaustive switches, no implicit any, noUncheckedIndexedAccess.
21 rule packs · 31 project checks
02 — LSP-aware

Reads your editor's truth, not heuristics.

const id = users[idx].email
└─ TS2532 · possibly undefined
const id = users[idx]?.email ?? ""
└─ resolved · 0 errors
in-process tsserver
03 — Stacks

Full-stack, one harness.

React
Next
TanStack
Drizzle
Fastify
Elysia
BullMQ
AI SDK
Node
Bun
04 — Gate loop

Builds until the gate passes.

turn 1 · 3 errors
turn 2 · 1 error
turn 3 · 0 errors · gate ✓
checkpoint saved · bounded ctx
Autonomous retry, bounded ctx
05 — Zero escapes

Patterns the harness refuses to ship.

  • as any
  • as unknown as
  • @ts-ignore
  • @ts-nocheck
  • // eslint-disable
  • floating promises
  • non-null !
  • implicit any
06 — CLI + agent

One command. Composable with anything.

$ tsforge "fix the token-refresh type error"
→ edit auth.service.ts
→ gate · tsc, eslint, bun test · pass
checkpoint saved
model-agnostic · any OpenAI-compatible endpoint
07 — Composable

CLI, gate, review, MCP clients.

chattsforge
reviewtsforge review
maptsforge map
gatetsforge gate
Connects to your MCP servers
A sliver of the ruleset
161 enforced · 0 optional
no-floating-promisesno-unchecked-indexed-accessno-explicit-anyno-misused-promisesconsistent-type-importsno-non-null-assertionstrict-boolean-expressionsno-unsafe-argumentno-unsafe-returnrequire-awaitswitch-exhaustiveness-checkprefer-nullish-coalescingban-ts-commentno-unsafe-assignmentno-unsafe-callno-unsafe-member-accessupdate-delete-must-have-wherejwt-must-verify-not-decodeno-user-controlled-fetch-urlno-user-controlled-redirectauth-cookie-must-set-samesiteno-auth-token-in-storagecatch-must-handleno-prototype-polluting-mergewebhook-must-verify-signature-before-parseno-secret-props-to-clientupload-must-set-limitstest-sibling-requiredno-mixed-three-entrypointsrequire-three-dispose-contractno-floating-promisesno-unchecked-indexed-accessno-explicit-anyno-misused-promisesconsistent-type-importsno-non-null-assertionstrict-boolean-expressionsno-unsafe-argumentno-unsafe-returnrequire-awaitswitch-exhaustiveness-checkprefer-nullish-coalescingban-ts-commentno-unsafe-assignmentno-unsafe-callno-unsafe-member-accessupdate-delete-must-have-wherejwt-must-verify-not-decodeno-user-controlled-fetch-urlno-user-controlled-redirectauth-cookie-must-set-samesiteno-auth-token-in-storagecatch-must-handleno-prototype-polluting-mergewebhook-must-verify-signature-before-parseno-secret-props-to-clientupload-must-set-limitstest-sibling-requiredno-mixed-three-entrypointsrequire-three-dispose-contract
03 — The loop

Propose. Build. Gate.
Until it passes.

01

Propose

The model starts primed on the import graph and the rule packs your stack triggers, so the first patch already respects your module boundaries. No blank-prompt guessing.

> tsforge "add refresh-token rotation"
primed · import graph + active packs
02

Build

Patches are type-checked in-process against the language service before they touch disk. One that wouldn't compile never lands; the model gets the diagnostic and revises.

~ edit auth.service.ts
~ edit auth.controller.ts
patch ok · 0 lsp diagnostics
03

Gate

tsc strict, type-aware ESLint, the meta-rules, and your tests run as one exit condition. Red re-plans within a turn budget. Green is the only way out.

→ tsc --noEmit · ok
→ eslint(tsforge) · ok
→ bun test · pass
✓ checkpoint saved
04 — In your terminal

See what changed, and what proved it safe.

Every run prints the edits it made and the gate that signed off: the actual tsc, ESLint, and test output. A failure names the rule that rejected the code. Nothing hides behind a spinner.

deterministic
Same input · same output
sandboxed
No prod-side calls
bounded ctx
Auto-compacts at the cap
audit log
Every edit, every gate
tsforge — auth-servicelive
› fix the token-refresh type error
┌─ edit auth.service.ts
- return user as any;
+ return user satisfies IUser;
┌─ gate (exit 0)
✓ tsc --noEmit
✓ strict ESLint (tsforge)
✓ bun test · 8 passed
✓ no-floating-promises
✓ test-sibling-required
✓ Gate passed. Checkpoint saved.
── model-agnostic · ctx bounded · 2 turns · done
No more vibe code.

Move at model speed. Merge at gate quality.

MIT · made by people who hate as any