Commands
| Command | Purpose |
|---|---|
typewire init | Read the project, ask what it needs, wire it up |
typewire test | Run the contract tests declared on your endpoints (default) |
typewire list | Print every route in the contract, with its transport |
typewire release-doc <version> | Scaffold a release note in docs/releases |
init
npx typewire initIt reads the project first — framework, TypeScript, package manager, src/,
monorepo, and which @tahanabavi/* packages are already installed — then asks
one question: what does this project need?
project acme-shop
framework Next.js
language TypeScript
installer pnpm
source src/
What does this project need?
• [•] typefetch — typed HTTP client
1 [✓] Query layer — caching, dedup, declared invalidation
2 [ ] typesocket — typed WebSocket contracts
3 [✓] Devtools panel — request timeline and cache inspector
4 [ ] GraphQL transport
5 [ ] gRPC transport
...Everything detected is a default, shown and overridable — never a silent decision. Options that cannot apply are not offered: the devtools panel does not appear in an Express project, and the NestJS adapter appears only in a NestJS one.
It then writes a typewire/ folder wired for what you picked — client,
contracts, query cache, provider, devtools bridge, permissions — prints the
install command for your package manager, and lists what to do next. Files
that already exist are skipped unless --force.
| Flag | Meaning |
|---|---|
--yes | Take every detected default, ask nothing |
--features <a,b> | Skip the question — reproducible in CI |
--contracts-path <path> | Use contracts you already have |
--output <dir> | Scaffold somewhere other than the project root |
--dry-run | Print the plan, write nothing |
--force | Replace existing files instead of skipping them |
The framework changes what is generated, not just where: a Next.js scaffold
marks the provider and devtools "use client", and reads
process.env.NEXT_PUBLIC_API_URL where a Vite project reads
import.meta.env.VITE_API_URL.
Without a TTY — a CI shell, a piped run — it takes the defaults and prints what it chose rather than blocking on a prompt nobody can answer.
test
npx typewire test --base-url https://staging.example.com --mode smoke| Flag | Meaning |
|---|---|
-c, --config <path> | Config file (default: discovered in cwd) |
-m, --mode <mode> | Test mode |
--base-url <url> | Override the client's base URL |
--token <token> | Auth token |
--timeout <ms> | Per-case timeout |
--include-tags / --exclude-tags | Filter by tag |
--include-destructive | Include cases marked destructive |
--stop-on-fail | Halt at the first failure |
-o, --output <path> | Report output path |
-f, --format <fmt> | md, html, or json |
list prints every route through the transport's own describe(), so a gRPC
route shows gRPC unary user.v1.UserService/GetUser rather than an empty
method/path — the CLI never reads transport-specific fields directly.