git clone https://github.com/tylerjrbuell/reactive-agents-ts.gitcd reactive-agents-tsbun installbun test # 9,000+ tests — all must passbun run build # ESM + DTS for all 34 packagesDevelopment Cycle
Section titled “Development Cycle”bun test # Run full suitebun test --watch # Watch mode during developmentbun run typecheck # Workspace-wide type checkingbun run build # Build all packages and appsbun run rax -- <args> # Run the local rax CLIbun run docs:dev # Docs site dev serverBefore opening a PR
Section titled “Before opening a PR”-
bun test— 100% green -
bun run build— no errors - Documentation updated (see below)
- Changeset added (see Release Workflow below)
Release Workflow
Section titled “Release Workflow”Releases are tag-driven lockstep: one version number stamps every public package at once. .changeset/*.md files are notes, not the driver — there is no auto-generated “Version Packages” PR. Never manually bump package.json versions or edit CHANGELOG.md.
What a contributor does: add a changeset
Section titled “What a contributor does: add a changeset”Every PR that changes user-facing behaviour needs a changeset:
bun run changesetThe interactive prompt asks:
- Which packages changed? — select the package(s) your change touches
- Bump type? —
patchfor fixes,minorfor new features,majorfor breaking changes (this bump type informs the release note; every package still ships at the same lockstep version regardless) - Summary? — this text becomes the public CHANGELOG entry verbatim, so write it for a reader of the changelog, not as a commit message
This creates .changeset/<random-name>.md. Commit it alongside your code and open the PR as usual.
What a maintainer does: cut the release
Section titled “What a maintainer does: cut the release”At release time, a maintainer aggregates all pending changesets into CHANGELOG.md, picks an explicit version number, and pushes a vX.Y.Z git tag. That tag push is the entire trigger — scripts/release.ts, run by CI, stamps every package to that version, builds, and publishes to npm in dependency order, then consumes (deletes) the changeset files it aggregated. See .claude/skills/prepare-release/SKILL.md for the full maintainer flow.
Bump types
Section titled “Bump types”| Type | When |
|---|---|
patch | Bug fixes, test fixes, internal refactors |
minor | New features, new builder methods, new exports |
major | Breaking API changes, removed exports |
All public packages ship at the same lockstep version — the bump type shapes the changelog note, it does not produce independent per-package versions.
Documentation
Section titled “Documentation”When to update what
Section titled “When to update what”| Change | Update |
|---|---|
| New package | AGENTS.md package map/status, README.md packages table, docs sidebar |
| New builder method | README.md, apps/docs/src/content/docs/reference/builder-api.md, AGENTS.md |
| New CLI command | README.md, apps/docs/src/content/docs/reference/cli.md |
| New feature | apps/docs/src/content/docs/features/<name>.md |
| API signature change | Search docs: grep -r "oldMethod" apps/docs/ |
Docs site
Section titled “Docs site”bun run docs:dev # http://localhost:4321bun run docs:build # Production buildbun run docs:preview # Preview built outputDocs are deployed to docs.reactiveagents.dev on every push to main.
Package Structure
Section titled “Package Structure”New packages follow this layout:
packages/<name>/ src/ types.ts # Schema.Struct types, tagged errors errors.ts # Data.TaggedError definitions services/ # Effect-TS Context.Tag services runtime.ts # Layer factories (createXxxLayer) index.ts # All public exports tests/ package.json # "version" matches workspace, "private": true if internal tsconfig.json # extends ../../tsconfig.jsonInternal packages that should never be published must have "private": true in package.json.
Adding a new package to the publish pipeline
Section titled “Adding a new package to the publish pipeline”- Create the package following the structure above
- Add it to the
fixedgroup in.changeset/config.json - Add its build step to the
build:packagesscript in rootpackage.json - Add it to the workspace in root
package.jsonworkspaces
Code Standards
Section titled “Code Standards”This project uses Effect-TS throughout. Load the effect-ts-patterns skill before writing any service code.
import { Effect } from "effect";// Often also: Layer, Context, Schema, Data, Ref — import only what you use- No
throw— useEffect.failwith tagged errors (orEffect.diefor defects) - No raw
awaitinside Effect programs — useEffect.promise,Effect.tryPromise, oryield*insideEffect.gen - Prefer
Effect.succeed/Effect.syncfor pure or trivial sync work - No
any— use precise types, generics, and tagged unions - All public APIs need JSDoc comments
- New services need tests in
tests/
What’s Next
Section titled “What’s Next”- FAQ — production readiness, honest caveats, what’s not done yet
- Architecture — layer system and package boundaries before you dig into a package
- Troubleshooting — symptom-to-fix reference for common failures