10 KiB
Repository Guidelines
Project Overview
This is a Bun/TypeScript monorepo for operating coding agents across web, native, desktop, terminal, and remote daemon surfaces. Convex is the backend control plane; the compiled Bun daemon subscribes to Convex commands and dispatches them to AgentOS/RivetKit actors that manage isolated agent VMs.
Architecture & Data Flow
apps/web,apps/native,apps/desktop, andapps/tuiare user interfaces. Shared UI lives inpackages/ui; runtime-specific environment validation lives inpackages/env.packages/backend/convexowns persistence, Better Auth, daemon registration/presence, the leased command queue, and append-only command events.apps/daemonis an Effect v4 application. It connects to Convex, subscribes to available commands, atomically claims a lease, invokes an AgentOS actor action, then reports success or failure.packages/primitivesprovides shared Effect v4 services, currently theAgentOsservice and layer over@rivet-dev/agentos.packages/agentscontains separate Flue agent definitions; do not conflate these with the AgentOS daemon runtime.
Primary daemon flow:
UI mutation -> Convex daemonCommands.enqueue
-> daemon onUpdate subscription
-> claim -> start -> AgentOS action
-> succeed/fail + daemonCommandEvents
The command queue is lease-based. Preserve ownership checks through claimedBySessionId, expiry through leaseExpiresAt, terminal statuses, and bounded query results. Keep stable daemon configuration separate from high-churn presence/heartbeat state.
Key Directories
apps/web/: React Router 8 web client; desktop consumes its static build.apps/native/: Expo/React Native client.apps/desktop/: Electrobun shell aroundapps/web/build/client.apps/tui/: OpenTUI/React terminal client.apps/daemon/: compiled Bun daemon; Effect runtime, Convex adapter, AgentOS adapter.packages/backend/convex/: schema, queries, mutations, HTTP/auth integration, generated Convex bindings.packages/primitives/: reusable Effect v4 primitives.packages/ui/: shared shadcn/Tailwind UI package.packages/env/:./web,./native, and./serverenvironment schemas.packages/config/: shared strict TypeScript configuration.repos/: committed, read-only upstream references; exclude from normal project tooling.
Development Commands
Run commands from the repository root unless noted.
bun install # install workspace dependencies
bun run dev:setup # configure/start the Convex development deployment
bun run dev # run workspace dev scripts
bun run build # build all targets; desktop is built separately last
bun run check-types # recursive workspace type checks
bun run check # Ultracite checks
bun run lint # Oxlint through Vite+
bun run format # Oxfmt through Vite+
bun run fix # apply Ultracite fixes
Targeted commands:
bun run dev:web
bun run dev:native
bun run dev:desktop
bun run dev:tui
bun run dev:server # Convex dev server
bun run dev:daemon
bun run build:daemon # apps/daemon/dist/code-daemon
bun run build:desktop
Repository maintenance:
bun run docs:update [commit-or-range] --dry-run # preview a documentation-agent prompt
bun run docs:update [commit-or-range] # update first-party docs with codex/opencode/claude
bun run subtree list # list configured vendored subtrees
bun run subtree status [name] # inspect local subtree metadata
bun run subtree preview <name> # show incoming upstream commits
bun run subtree update <name> --yes # pull a configured subtree using --squash
docs:update defaults to HEAD, accepts Git ranges such as main..HEAD, excludes vendored/generated content, and detects the agent in codex, opencode, claude order. Override it with --agent or DOCS_AGENT. Subtree configuration is stored in scripts/subtrees.json; pinned historical entries require --force-pinned --yes.
Add shared shadcn components with npx shadcn@latest add <name> -c packages/ui and import them from @code/ui/components/<name>.
Code Conventions & Common Patterns
- Use ESM, TypeScript 6, double quotes, semicolons, and sorted
package.jsonfields. Formatting/lint configuration is invite.config.ts,oxfmt.config.ts, andoxlint.config.ts. - Use
import typefor type-only imports. Do not useany; validate or narrowunknownat trust boundaries. - Reuse workspace packages through
@code/<package>and their declared subpath exports instead of reaching into unrelated package internals. - Environment access belongs in
packages/env; validate new variables with Zod and expose them through the correct runtime entry point. - Generated files are not hand-edited: notably
packages/backend/convex/_generated/**,apps/web/src/routeTree.gen.ts, and framework build/type directories. - Convex modules map directly to
api.<file>.<function>. Every function requires argument validators. Prefer indexed, bounded reads and preserve mutation atomicity for claims/state transitions. - Before changing
packages/backend/convex, readpackages/backend/AGENTS.mdandpackages/backend/convex/_generated/ai/guidelines.md; those instructions override remembered Convex APIs.
Effect v4 patterns used by daemon/primitives:
- Define dependencies with
Context.Serviceand provide them throughLayer. - Use
Schema.TaggedErrorClassfor typed failures andEffect.try/Effect.tryPromiseat external boundaries. - Name effectful functions with
Effect.fn("Module.operation"). - Manage resources with scopes,
Effect.acquireRelease, and finalizers; use structured concurrency (FiberSet, scoped fibers) rather than detached promises. - Bridge callback APIs through Effect streams/queues. Keep promise and callback errors in the typed error channel.
- Run Bun applications through
BunRuntime.runMain.
Important Files
package.json: workspace catalog and authoritative scripts; package manager isbun@1.3.14.vite.config.ts: Vite+ task, lint, format, staged-file, and generated-file exclusions.packages/config/tsconfig.base.json: shared strict compiler settings.packages/backend/convex/schema.ts: daemon and command data model.packages/backend/convex/daemonCommands.ts: lease-based command state machine.packages/backend/convex/daemonRuntime.ts: connection, heartbeat, disconnect, and event reporting.apps/daemon/src/index.ts: Bun/Effect entry point.apps/daemon/src/runtime.ts: command subscription and execution loop.apps/daemon/src/convex.ts:ConvexControlPlaneEffect service.apps/daemon/src/agent-os.ts: RivetKit registry and AgentOS action dispatch.packages/primitives/src/agent-os.ts: reusable AgentOS Effect service/layer.packages/env/src/{web,native,server}.ts: runtime environment contracts.
Runtime/Tooling Preferences
- Use Bun, not npm/pnpm/yarn, for root installation and scripts. The daemon intentionally compiles with
bun build --compile. - Vite+ (
vp) is the workspace task runner; there is no Turbo or Nx workflow. - Linting is not type-aware. Always run
bun run check-typesfor TypeScript verification. - Effect and
@effect/platform-bunare pinned to4.0.0-beta.99. AgentOS uses@rivet-dev/agentos; RivetKit is currently pinned to a feature build. Verify APIs against installed declarations/source before upgrading or generalizing. .envand.env*.localmay contain deployment values and are generally ignored. Useapps/daemon/.env.exampleas the daemon template. Placeholder Convex hosts are deliberately rejected by the environment schemas.
Testing & QA
There are currently no first-party automated tests, test scripts, coverage thresholds, or CI workflows. Do not claim a test suite passed. The current baseline verification is:
bun run check-types
bun run check
Also run the changed application path: compile and start the daemon for daemon work, exercise the affected page for UI work, and use a development Convex deployment for backend state transitions.
When adding tests:
- Use the Vite+ test configuration rather than adding a standalone Vitest config.
- Convex tests belong under
packages/backend/convex/and should follow the generated guidance (convex-test, Vitest, edge runtime). - RivetKit actor tests should use its
setupTesthelper. - Tests must defend observable behavior such as lease ownership, state transitions, cleanup, retries, authentication, or rendered interactions.
Vendored Repositories
External repositories under repos/ are read-only reference material.
- Prefer their patterns, examples, tests, and API usage over guesses or web snippets.
- Do not edit files under
repos/unless explicitly asked. - Do not import application code from
repos/; use normal package dependencies. - Exclude
repos/from project-wide formatting, linting, typechecking, and tests unless explicitly validating a vendored repository.
Effect v4 and Effect Smol
Effect v4 moved from the archived effect-smol repository into canonical Effect-TS/effect in July 2026. When writing or reviewing Effect v4 code:
- Read
repos/effect/LLMS.mdbefore making changes. - Use
repos/effect/as the current source of truth. Itsmainbranch contains Effect v4 beta; Effect v3 is on upstreamv3. - Use
repos/effect/packages/effect/src/,repos/effect/packages/effect/test/, andrepos/effect/ai-docs/for current APIs and idioms. - Treat
repos/effect-smol/as historical only; read itsREADME.mdbefore consulting it. - Verify API names and signatures against
repos/effect/; do not rely on Effect v3 knowledge or prefer older Smol APIs. - Import only from the installed
effectpackage in application code.
Refresh the current reference only from a clean worktree:
git subtree pull --prefix=repos/effect https://github.com/Effect-TS/effect.git main --squash
The archived Smol subtree should normally stay pinned. If historical synchronization is explicitly required:
git subtree pull --prefix=repos/effect-smol https://github.com/Effect-TS/effect-smol.git main --squash