ADR-0007: Tooling
- Status: Accepted. Spike S2 (packaging) was answered by the build itself: 0.1 has no client entries, publint and attw run in
pnpm check, and the tarball check builds a fresh app with Turbopack and webpack before each release candidate. - Date: 2026-10-29
Decision
| Area | Choice | Notes |
|---|---|---|
| Workspace | pnpm 12 workspaces | No Turborepo or Nx: 2–3 workspaces don't need an orchestrator |
| Library build | tsdown | 0.1 has no client entries: the widget is a prebuilt iframe app. The React subpath in 0.2 will start each client entry with 'use client', checked in CI. tsup is unmaintained. |
| iframe app and loader | Vite 8 | Library mode. The output is inlined into the package as string modules. |
| TypeScript | Typecheck with TS 7 (tsgo); isolatedDeclarations | TS 6.0 only where a tool needs the compiler's JavaScript API |
| Lint and format | Biome 2.6 | Import restrictions enforce module boundaries; for example, only src/openai/ may import openai. |
| Unit and integration tests | Vitest 5 + MSW 3 | Recorded Responses API SSE fixtures are replayed with http.post handlers |
| End-to-end tests | Playwright 1.64 | Two origins (app and host page), axe checks, visual regression on the state gallery |
| Package quality | publint, @arethetypeswrong/cli, size budgets in the asset build, .d.ts snapshot, no-leak test | Loader under 5 KB gzipped |
| Release | Changesets 3, npm trusted publishing (OIDC) with provenance | No npm token stored anywhere |
| CI and maintenance | GitHub Actions, Renovate (openai updates batched weekly), CodeQL, TruffleHog | Nightly canary and daily live smoke (ADR-0006) |
AI-assisted development
.mcp.jsonholds read-only servers only:- the OpenAI Docs MCP (
https://developers.openai.com/mcp); next-devtools-mcp, pinned to a version.
- the OpenAI Docs MCP (
- Skills are vetted before use and pinned, kept in
.claude/skills/with their sources, commits and reviews in.claude/skills/sources.json. - Project skills:
typescript-conventions,openai-api,release,adr. CLAUDE.mdat the root.site/CLAUDE.mdandexamples/starter/CLAUDE.mdimport theAGENTS.mdnext to them (generated bynext dev; in the starter, also written byinit).- Servers with account write access (Vercel, Heroku, Upstash) are configured in local or user scope only, never in the repo.
Alternatives considered
- Turborepo or Nx. Overkill at this size.
- ESLint 10 with flat config. Fine, but Biome covers lint and format in one fast tool.
- API Extractor. Deferred; the
.d.tssnapshot plus the no-leak test cover the risk for now.