Files
suaveplan/CLAUDE.md
2026-05-27 23:29:53 +01:00

27 KiB

Suaveplan Monorepo — Genesis

Bottom-up rebuild at enterprise quality. Branch genesis starts empty; packages land in dependency-order waves at 0.1.0 until graduation to 1.0.0.

Main branch (/mnt/s/web/suaveplan) is reference-only for design intent (enterprise/*.md) and historical audit data. Do not pull code from main into genesis — every package is rewritten fresh.

Change workflow

All non-trivial changes go through OpenSpec. Before coding:

  1. Read openspec/project.md and openspec/AGENTS.md.
  2. Create openspec/changes/<change-id>/ with proposal.md, tasks.md, and spec deltas under specs/<capability>/spec.md (## ADDED / ## MODIFIED / ## REMOVED Requirements).
  3. On ship: fold the delta into openspec/specs/<capability>/spec.md and move the folder to openspec/archive/<yyyy-mm-dd>-<change-id>/.

Stack

  • Turborepo + Bun monorepo at /mnt/s/web/genesis
  • Biome (lint/format), Vitest (tests), Playwright (E2E), TypeScript
  • Use bunx turbo for turbo commands
  • Private registry: Verdaccio at https://npmjs.fq.io/ (auth via NPM_TOKEN)

Packages

Layout (packages/<category>/<plugin>/<pkg>/)

Domain-first 3-level layout: every package lives at packages/<category>/<plugin>/<pkg>/ where <category> is one of the 18 canonical super-categories — foundation, persistence, networking, communication, api-stack, identity, security-stack, observability, media, ui, threejs, localization, geospatial, money, commerce, testkit, devtools, gaming — and <plugin> matches a plugin in suaveplan-skills. Tier (universal / browser / react / r3f / server / python) is per-package via package.json ("browser" field, peer deps, engines), not encoded in the path. Full category → plugin → package map in scripts/folder-reorg/assignment.yml; summarised in MANIFEST.md at repo root. The super-category vocabulary is closed — adding/removing a category requires an OpenSpec change.

Add new packages, then run bun scripts/folder-reorg/generate-manifest.ts to refresh MANIFEST.md (dep graph auto-derived from workspace: ranges).

Note: Detailed package descriptions live in each package's README.md and co-located .md files. This file describes foundational packages widely depended on; everything else is listed by name only — see MANIFEST.md and the package sources for details.

Foundation (zero or near-zero deps, widely consumed)

  • types — types-only foundation: Clock, IdGenerator, Rng, MessageResolver, EventBusLike, LoggerLike, StorageLike, DatabaseLike, HashLike, TimersLike, shared option bundles + cross-package crypto contract (Authority, KeySlotPublic/Private, SlotId, DomainTag, AuthorityVerifier, AeadOps, AeadAlgorithm). Zero runtime, zero deps. Permitted as testing-infra dev dep (rule 8 exception).
  • error — SuaveplanError base, stable code registry via defineCodes, cause-chain traversal, Zod-validated wire format, redaction, OTel span-event adapter, i18n resolver hook. Deps: tslib, zod.
  • events — typed event bus: pub/sub FIFO, interceptors, bounded-queue backpressure, idempotent listeners. Deps: error, types.
  • env — type-safe env loading with schema validation, dotenv + object loaders, maskSensitive, createEnv. Deps: error, types, zod.
  • config — layered config (5 layers: defaults/file/object/env/CLI), Zod validation, dot-path get/has, hot reload, EventBus watch. Deps: error, types, events, env, zod.
  • logger — structured logger: level filtering, OTel trace enrichment, sampling, redaction, pluggable sinks. Deps: error, types.
  • opentelemetry — OTel SDK utilities: NoopSdk, SdkFactory, W3C propagation, span/metrics utilities, resource builder.
  • typescript-config — shared TSConfig presets. No runtime.
  • overview — machine-readable monorepo manifest with Zod schemas + graph utilities. Leaf.
  • api-schemas — shared Zod request/response schemas. Leaf.

Testing infrastructure (no @suaveplan/* runtime deps; rule 8)

  • testing — runner-agnostic utilities (FakeClock, Factory, FixtureManager, MemoryStore, builders). Owns the ./runner conditional-export wrapper resolving to vitest (default) or bun:test (under bun condition) — see rule 11.
  • testing-dom, testing-e2e, testing-integration — DOM helpers + dual-runner adapters; Playwright config factory; ServiceFixture/TestEnvironment/HealthPoller.
  • testing-integration-{surrealdb, redis, postgres, mailpit, typesense, garage-s3, step-ca} — real-service fixtures via testcontainers; each provides env-bridge + health probe + injectable container/exec/fetch factories.

Crypto family

Foundation (widely consumed):

  • crypto-utils — hex/base64/base58, byte helpers, constant-time equality, random bytes, zeroize, Merkle, KAT/fuzz harnesses, PrimitiveId registry.
  • crypto-hash — sha256/384/512, hmac, hkdf, pbkdf2, argon2id. Noble + native, build-time selection.
  • crypto-curve — secp256k1, ed25519, x25519, p256, p384, p521. Noble + native.
  • crypto-cipher — aes-256-gcm, chacha20-poly1305, xchacha20-poly1305. Nonce caller-supplied.
  • crypto — multi-algorithm façade over the four primitive packages. Engine-pluggable.
  • crypto-rsa — RFC 8017 PKCS#1 v2.2: PKCS1v15+PSS sign/verify, OAEP, all 8 key formats, FIPS 186-5 keygen, RFC 7638 thumbprints, blinding-by-default, pluggable engine, HSM bridge. Gates x509/jws/webauthn.

Specialty: crypto-core, crypto-sodium, crypto-browser, crypto-cli (keychain binary), crypto-bin (suaveplan-hash-password), crypto-vault (BIP39 + Argon2id + 2SKD + HKDF + SRP-6a + SecureBuffer; gates vault).

Drive (file VFS)

  • drive — modular file-VFS core. Consumes AbstractStorage directly via structural DriveStorage view. Plugin slot + middleware chain. Template hydration (hydrateFrom/getKeyStatus/presence). 11 DRIVE_* codes.
  • drive-template — server-signed dehydrated descriptor for lazy hydration. 8-step validation pipeline, Ed25519 over canonical bytes, TemplateNonceLru, CDN URL builder, upload-token signing, retroactive key-grant validation. 10 DTP_* codes.
  • drive-mesh-protocol — wire protocol for chunk discovery/request/delivery. ChunkRequest union (whole/specific/bitset), GenerationTracker, AdvertiseThrottle, TrustMap with sample-verify. 10 DMP_* codes.
  • drive-plugin-chunks — chunk addressing: 164-byte fixed-width header, XChaCha20-Poly1305 streaming AEAD, Ed25519 inline-hint signing, sparse-file + chunk-keys layouts, server-signed manifest. 12 CHUNKS_* codes.

Consumers: drive-sharing, drive-transport-https, drive-transport-webrtc, drive-webrtc (browser-tier P2P mesh plugin), drive-mesh (P2P orchestrator: PeerRegistry, GossipEngine, ParallelPuller, ServerFallback), drive-react-sharing (React 19 hooks + accessible components).

Vault

  • vault — orchestration: open/unlock/lock FSM, encrypted single-blob container via DriveLike, items/attachments/shares/sync, OpaqueKeyHandle, forward-only migrations, bitpacked manifest, 25+ error codes.
  • vault-sync — sync + conflict resolution: 3 merge strategies (lww/append/atomic) with vector clocks, RFC 6902 diff/patch, SyncEngine/SyncQueue, payload encryption with AAD + 10 MiB cap. 10 error codes.

Network

  • network — plugin-based core. NetworkPlugin lifecycle, NetworkNode, MessageEnvelope Zod schema, MessageRouter (unicast/broadcast/fan-out), PluginManager, NetworkBus, VersionInfo/VersionManager/VersionNegotiator, NetworkTimestamp, NetworkEvents registry, 5 NET_* codes. Concrete transports/governance/registry/failover/topology all live in sibling network-plugin-* packages.

i18n family

  • i18n — slim integration core (post-Wave-6 split). Owns MessageCatalog, createI18n/I18nInstance, locale negotiation, server middleware, defaultFormatBridge. Re-exports siblings for back-compat.
  • i18n-shared — universal-tier shared atoms: locale constants, LOCALE_BCP47_MAP, RTL_LOCALES, I18N_CODES (18), I18nError, ./testing runBackendConformance harness.
  • i18n-icu-parser — ICU MessageFormat parser (tokenizer + AST + CLDR plurals).
  • i18n-detector — 9-detector chain (querystring, userPreference, cookie, localStorage, htmlLang, acceptLanguage, navigator, cloudflareIpGeo, fallback) + bcp47Negotiate + RTL helpers.
  • i18n-backend-{memory, http, storage, chained, fs-multifile} — translation backends; all conform to runBackendConformance harness. fs-multifile is server-tier.
  • i18n-formatter-{number, currency, date, relative-time, list, display-name, collator, segmenter} — Intl.* adapters plugged into defaultFormatBridge.

Time, sequencing, validation, control flow

  • datetime, timing, cron (gates job-scheduler), job-scheduler (consumes cron + retry), validation, retry, idempotency, fsm, schema-registry, feature-flags, workflow (universal-tier pipeline orchestration: fluent builder, sequential / parallel / conditional steps, saga compensation, retry middleware, hook registry, transition-data pipeline, Zod-validated WorkflowConfig, injectable Clock, six WORKFLOW.* codes, OTel counters + histogram). See per-package READMEs.

Rules

  • rules — universal-tier rule engine + validators + actions + hooks + serializer + optimizer. 24 codes. Discriminated Rule union, RuleBuilder, 33 built-in operators.
  • rules-hono — Hono middleware suite (6 factories: rule, validation, accessControl, responseValidation, rateLimit, combine). Hono peer dep.

Security / vault leaves

  • slsa, security-codes, data-masking, suppression, macos-keychain, hibp, password-generator, password-strength, x509, jws, tpm-struct, cbor, otp, srp, webauthn — see per-package READMEs. webauthn consumes cbor/x509/jws/tpm-struct/crypto-{rsa,curve}; covers all 7 attestation formats.

Serialization / data shape

  • serialize, diff, pagination, mime, templates, bitpacker, bitpacker-compressed, packer, packer-browser (browser-tier runtime for packer archives: SW interceptor + PackedResourceManager + Ed25519 signature verification; no React dep), react-packer (React 19 companion: usePackedResource / usePackedImage / usePackedAudio / usePackedVideo / usePackedFont hooks + PackedResourceProvider context; consumes @suaveplan/packer-browser; React peer-dep only).

File / media / domain utilities (mostly leaves)

  • metadata, exif, dmarc, sitemap, domain-normalizer, dedup, password-formats, barcode, qrcode, compress-image, font-subset, font-convert, font-compress (bin: suaveplan-font-compress — TTF/OTF/WOFF/WOFF2 → BTF pipeline).

Geo / astronomy / tides

  • geo, geo-planet, geo-earth, solar-system, stars, tides, universe — abstract spherical geometry → planet config → Earth specifics → injectable astronomy/star/tidal providers aggregated through universe.

Network clients / IO / DB / installer

  • oauth-client, webhook-client, readline, cli.
  • db (adapter foundation), db-sqlite (universal: bun:sqlite on Bun, @sqlite.org/sqlite-wasm in browser).
  • installer (plugin host, bin suaveplan-install), install-agent-skills (skill bundle installer).

Games (universal-tier)

  • ecs — archetype-based Entity Component System: Uint32Array BitSet, column-oriented archetype storage with O(1) swap-remove, phase+priority SystemScheduler (preUpdate→update→postUpdate→render), entity-ID recycling with generation counters, Zod-validated component schemas, EventBus<WorldEventMap> entity lifecycle events, OTel counter (ecs.entity.lifecycle_total) + histogram (ecs.world.execute_duration_ms), WorldSnapshot round-trip. 7 ECS.* codes. Deps: @suaveplan/error, @suaveplan/types, @suaveplan/events, @suaveplan/opentelemetry, tslib, zod.

Contacts

  • contacts — universal-tier contact and group management: hierarchical n-level groups (adjacency + materialised path), channel-agnostic contacts with dedup, many-to-many memberships with ancestor count propagation, audience resolution with descendant walk + dedup + filters, contact merger, CSV/JSON import-export, injectable Clock + IdGenerator, Zod input boundaries, six OTel counters + three histograms, typed ContactsError hierarchy with stable CONTACTS.* code registry.
  • macos-contacts — macOS Contacts.app bridge: AppleScript reader, Contact ↔ macOS Person mapping, deduplication via @suaveplan/contacts/dedup, push/pull/sync, vCard import-export.
  • api-sandbox-vm — vm.Context-based sandbox host (Stage 8.2). Builds a Proxy-guarded vm.Context with frozen-globals allowlist (URL/URLSearchParams/TextEncoder/TextDecoder/structuredClone + logger-routed console + trimmed crypto), vm.SourceTextModule plugin loader with refuse-everything linker (rejects node:*, bare specifiers, parent traversal), eval/Function traps, host-proxied fs/fetch with permission gating, consolidated __suaveplan capability receiver, in-package PermissionChecker default from PermissionsManifest, idempotent dispose(), OTel sandbox_vm.{boot_duration_ms,eval_rejected_total,module_import_rejected_total} + shared plugin.permission_denied_total, 5-code SAND_VM.* registry, ./testing/runVmSandboxConformance harness. Requires Node ≥ 20 with --experimental-vm-modules.
  • api-plugin-contacts — Contacts + groups HTTP plugin for @suaveplan/api. Mounts /contacts and /groups (with /groups/:id/members, /groups/:id/tree, /groups/:id/move, /groups/:id/resolve) on a Hono OpenAPIHono backed by SurrealDB implementations of the @suaveplan/contacts ContactStore / GroupStore / MembershipStore interfaces. Bulk-import with per-row error reporting, repository-level maxGroupDepth enforcement, six OTel instruments (4 counters + 2 histograms), typed Hono ContextVariableMap + ServiceRegistry augmentations, and the 12-code CONTACTS_API.* error namespace.

API sandboxing

  • api-sandbox-wasm — Stage-8 WebAssembly sandbox host for sandboxed-tier plugins. Instantiates a guest WASM module against a wasi_snapshot_preview1 snapshot built from the plugin's PermissionPolicy: read-only WASI preopens from permissions.fs[] (with rw: opt-in), outbound socket allowlist from permissions.fetch[] (sock_connect gate raises SAND_WASM.OUTBOUND_DENIED BEFORE any OS socket), and capability host imports under suaveplan_caps permission-gated per call (denied → WASI_ERRNO.ACCES + plugin.permission_denied_total{plugin,capability,reason}). Owns a 4-code SAND_WASM.* registry, a runWasmSandboxConformance harness on ./testing, and a hand-encoded fixture WASM builder so the test suite needs no wabt build step. WasmSandboxHandle.dispose() idempotent.

Rules

Critical (never compromise)

  1. NEVER run tsc directly — use Vite/tsup via bunx turbo build. Bun runs .ts natively.
  2. NEVER use mocks — real services only (no vi.mock/jest.mock unless absolutely necessary).
  3. Bun overrides with exact versions.
  4. NEVER re-export external deps for convenience — import directly from source.
  5. NEVER auto-commit/push without user approval — never use --no-verify.
  6. Always use absolute paths in tool calls.
  7. Read files before editing — understand context first.
  8. Testing-infrastructure packages (testing, testing-dom, testing-e2e) must not depend on any @suaveplan/* runtime package — external catalog deps only. Sole exception: @suaveplan/types (types-only, byte-size-test guarded).
  9. NEVER write // biome-ignore (or any static-analysis suppression comment) in migrated/new code. Stale rule names → hard parse-error fails; right names that no longer match → Suppression comment has no effect warnings. Both block CI. To exercise a deliberate violation, use a coding pattern biome cannot statically reject. Full rule: openspec/AGENTS.md §2a.
  10. NEVER write export * in any non-root barrel. Feature-module barrels MUST use explicit named re-exports. Exempt: generated *.select/index.ts forwarders, single-line *.native//*.noble/ impl-variant forwarders, namespace re-exports. Package roots MAY currently use export * but new ones SHOULD prefer namespace exports. Migrate export * → named exports as part of the migration commit, not a follow-up. Full rule: openspec/AGENTS.md §6a.
  11. NEVER import test-runner primitives directly from vitest or bun:test in non-exempt packages. Test files MUST import from @suaveplan/testing/runner. Exempt allowlist (5): testing, testing-dom, testing-e2e, testing-integration, testing-integration-step-ca. CI gate: bun scripts/lint/check-test-runner-imports.ts. Verification: grep -rnE "from ['\"](vitest|bun:test)['\"]" packages/<category>/<plugin>/<pkg>/src/ → zero output. Full rule: openspec/AGENTS.md §7.

Git safety (non-negotiable — code has been lost twice on main)

Before ANY git operation: run git status in every worktree (git worktree list) and confirm each is clean or its state is understood.

NEVER run these without explicit per-use user approval:

  • git filter-repo / git filter-branch — rewrites history, destroys staged + working tree.
  • git push --force / --force-with-lease — only after user explicitly says "force push".
  • git reset --hard, git clean -f[d], git rebase, git stash drop/clear, git gc/prune, git checkout -- <file>.

Large-file push errors: stop, do NOT rewrite history. Run git status/git stash list in all worktrees first, then ask the user (.gitignore + new commit, Git LFS, or manual removal).

Staged changes are irreplaceable — treat them as more precious than committed history.

Worktree discipline — long-lived worktrees are never the answer.

  • Before opening a worktree or dispatching a parallel agent: git worktree list and git status in each existing one. Account for every entry: active agent, work-pending-merge, or stale-and-prune.
  • After a worktree-based agent ships (commit on a feat/* branch), remove the worktree (git worktree remove) so the count returns to baseline. The branch + commit survive; the directory does not need to.
  • The baseline is one worktree (the main checkout). Anything beyond that is an open ticket waiting to be closed.
  • Run bun scripts/worktree-prune.ts to audit + prune in one command. It's idempotent and refuses to remove worktrees whose HEAD commit isn't reachable from any branch ref (so it never loses work).

Worktree-isolated agents: never edit the main checkout. When dispatched into an isolated worktree at .claude/worktrees/agent-<id>/, every file operation MUST target that worktree path, never /home/paul/web/genesis/. The hazards are real and observed:

  1. First action in every agent session: pwd && git worktree list to confirm you're in the right tree. If pwd shows /home/paul/web/genesis instead of a .claude/worktrees/agent-* path, STOP and report — you are not in an isolated worktree.
  2. Use relative paths (packages/..., openspec/...) for every read/edit/write. Avoid absolute paths in tool calls unless reading reference material from outside the worktree (e.g. main-branch source at /mnt/s/web/suaveplan/...).
  3. Never cd to /home/paul/web/genesis/ from a worktree. The Read/Edit/Write tools resolve relative paths against the working directory of the bash session, which starts in the worktree.
  4. Before committing: git rev-parse HEAD and git rev-parse --show-toplevel must show your worktree's branch + path, not main's. If either is wrong, your work landed in the wrong place — recover with git status in BOTH locations, then move the changes back via patch (git diff > /tmp/work.patch, cd $WORKTREE, git apply /tmp/work.patch).

Cross-worktree leakage has been the failure mode in three recent agent sessions — wasted ~1 hour each time. This rule is the prevention.

§0a Sync — worktrees fork from a stale base. Empirically the harness's isolation: "worktree" may fork from an earlier session-stable ref rather than current genesis HEAD. This bit Wave B (5 agents all forked from a pre-Wave-A commit). Prevention: every parallel-dispatch prompt MUST include a §0a Sync block that fast-forwards the worktree to a known base SHA before any work begins:

EXPECTED_BASE=<orchestrator-supplied-sha>
if ! git merge-base --is-ancestor "$EXPECTED_BASE" HEAD; then
    git fetch /home/paul/web/genesis genesis
    git merge FETCH_HEAD --no-edit
fi
git merge-base --is-ancestor "$EXPECTED_BASE" HEAD || { echo "STILL OUT OF DATE"; exit 1; }

The orchestrator passes the expected SHA at dispatch time. Agents that can't reach it STOP and report rather than proceeding Wave-N-blind. Without this gate, agents re-invent interfaces from earlier merges and produce work that doesn't integrate.

Workflow

  1. TaskCreate for multi-step tasks (>3 steps).
  2. Complete all implementations — no stubs, no placeholders, no TODOs, no mocks in production. Missing dep? Add it and wire the real implementation.
  3. Build feature-rich, production-grade packages — comprehensive enterprise-level over minimal MVP.
  4. Professional honesty — no marketing language or fake metrics.
  5. Preserve full public surface during rewrites. Trim ONLY when duplicated in-repo or replaceable by an existing @suaveplan/* library.

Web App & Page Verification

When generating client-side pages/web apps, verification is NOT optional and a 200 response is NOT proof of correctness:

  1. Docker staging environment — mirror production before declaring done.
  2. Full Playwright E2E sweep — every page, every component, every navigation.
  3. Never trust HTTP 200 alone — verify rendered DOM contains expected content.
  4. Inspect browser console — any unexpected error or warning fails the check.
  5. Inspect network activity — failed requests, missing assets, CORS, mixed content.
  6. Zero-defect push to live — fix root cause first.

Package Lifecycle

  • New packages: add to listing, then bun scripts/folder-reorg/generate-manifest.ts.
  • Editing: every package starts at 0.1.0; bump only at 1.0.0 graduation.
  • Pre-publish gate (non-negotiable): bunx turbo lint typecheck test --filter=@suaveplan/<pkg> MUST be green AND bunx turbo test:coverage --filter=@suaveplan/<pkg> must meet 100% on touched modules. Full-package turbo test required — single-file vitest run is not a substitute.
  • After verification passes: bun scripts/publish.ts --package @suaveplan/<pkg>.

Package Structure (library packages)

Five files per feature module, co-located:

src/category/
  feature-name/
    index.ts                   # Barrel — explicit named re-exports (rule 10)
    feature-name.ts            # Implementation
    feature-name.test.ts       # Vitest tests
    feature-name.types.ts      # Type definitions (no .md required)
    feature-name.md            # Co-located docs (required)

Special: types/ (shared types, flat), utils/ (utilities, flat with tests + .md), constants/index.ts (simple exports, no tests/docs).

No flat modules at src/ root. Every implementation file paired with a .test.ts MUST live in a src/<feature>/ folder, not flat at src/ root. The only flat entries permitted at src/ root are index.ts (package barrel) and the three exempt directories above. This includes error-codes, telemetry, schemas, and similar "single-concept" modules — they get their own folder + index.ts barrel just like any other feature. Empirically this gets cut by agents shortcutting "atomic" modules to flat siblings of index.ts; lint+typecheck+coverage all accept it. CI gate: bun scripts/lint/check-feature-layout.ts (wired into bunx turbo lint).

Subpath exports in package.json for tree-shaking: ./category/feature/feature.

README layout: one README.md at package root only. No category-level READMEs inside src/<category>/.

Quality

  • 100% test coverage — bun run test:coverage --filter=@suaveplan/<pkg> (provider: 'istanbul').
  • 100% docs coverage — bun run docs:check --filter=@suaveplan/<pkg>.
  • ~250 lines soft / 300 lines hard limit per code file, 500 lines max per test file.
  • .test.ts for Vitest, .spec.ts for Playwright E2E.
  • Always add { timeout: 5000 } (30000 for async) to it()/test().
  • Root cause analysis — never skip/disable tests.
  • Every React component needs .stories.tsx (default + playground + variants).

Documentation (co-authored .md per implementation file)

Every .ts/.tsx MUST have a sibling .md. Exclusions: .test.ts, .test.tsx, .spec.ts, .types.ts (inside a feature dir), .stories.tsx, barrel index.ts, constants/index.ts.

Required sections: Purpose (≥2 sentences), Features, Usage: Basic, Usage: Advanced, API Reference, Implementation Notes.

Hard constraints: ≥200 words excl. code; both simple AND advanced examples mandatory; code must compile with real imports; no marketing/placeholder text; update docs when code changes.

Vitest / WSL2

  • Use createTestConfig() from @suaveplan/testing/config for vitest configs. For configs needing aliases/plugins, write standalone with pool: 'forks' + setupFiles: ['@suaveplan/testing/polyfills'].
  • NEVER mergeConfig with baseVitestConfig — missing polyfills cause crypto is not defined.
  • vmThreads and threads pools both fail in Bun on WSL2 — use default forks.
  • fileParallelism: false required for browser tests.
  • SurrealDB: check error?.code === 'ConnectionRefused' || error?.message?.includes('Unable to connect').

Code Organization

  • Universal: ZERO browser/React deps | Browser: React/DOM ok | Server: Node.js ok.
  • Co-locate tests with source, .md docs per implementation file.

Dependencies

  • workspace:^ for internal deps, Bun catalogs for external.
  • "sideEffects": false on all pure library packages.

Quick Commands

bunx turbo test --filter=@suaveplan/<pkg>          # Test one package
bunx turbo test:coverage --filter=@suaveplan/<pkg> # Coverage for one package
bunx turbo lint --filter=@suaveplan/<pkg>          # Lint one package
bunx turbo typecheck --filter=@suaveplan/<pkg>     # Type check one package
bunx turbo lint typecheck test --filter=@suaveplan/<pkg>  # Pre-publish gate
bunx turbo test                                    # All tests (no DB)
bunx turbo lint typecheck                          # All lint+types