Files
zopu-code/AGENTS.md

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, and apps/tui are user interfaces. Shared UI lives in packages/ui; runtime-specific environment validation lives in packages/env.
  • packages/backend/convex owns persistence, Better Auth, daemon registration/presence, the leased command queue, and append-only command events.
  • apps/daemon is 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/primitives provides shared Effect v4 services, currently the AgentOs service and layer over @rivet-dev/agentos.
  • packages/agents contains 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 around apps/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 ./server environment 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.json fields. Formatting/lint configuration is in vite.config.ts, oxfmt.config.ts, and oxlint.config.ts.
  • Use import type for type-only imports. Do not use any; validate or narrow unknown at 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, read packages/backend/AGENTS.md and packages/backend/convex/_generated/ai/guidelines.md; those instructions override remembered Convex APIs.

Effect v4 patterns used by daemon/primitives:

  • Define dependencies with Context.Service and provide them through Layer.
  • Use Schema.TaggedErrorClass for typed failures and Effect.try/Effect.tryPromise at 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 is bun@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: ConvexControlPlane Effect 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-types for TypeScript verification.
  • Effect and @effect/platform-bun are pinned to 4.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.
  • .env and .env*.local may contain deployment values and are generally ignored. Use apps/daemon/.env.example as 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 setupTest helper.
  • 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:

  1. Read repos/effect/LLMS.md before making changes.
  2. Use repos/effect/ as the current source of truth. Its main branch contains Effect v4 beta; Effect v3 is on upstream v3.
  3. Use repos/effect/packages/effect/src/, repos/effect/packages/effect/test/, and repos/effect/ai-docs/ for current APIs and idioms.
  4. Treat repos/effect-smol/ as historical only; read its README.md before consulting it.
  5. Verify API names and signatures against repos/effect/; do not rely on Effect v3 knowledge or prefer older Smol APIs.
  6. Import only from the installed effect package 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