AI Agent Reference
This page is written for both humans and retrieval tools. It summarizes the stable Semitra facts an AI agent should use before generating or editing a Semitra project.
The public docs remain the source to retrieve from. This page is an index of the facts that should be treated as canonical.
Framework identity
Section titled “Framework identity”Semitra is a Rails-inspired application framework for Cloudflare Workers. It is not a Rails clone.
The product shape is:
- Cloudflare-native Worker backend
- JSON-first APIs
- TypeScript schema contracts across layers
- D1 records, R2 storage, KV cache, Queues jobs, Durable Object realtime
- generated React Router 7, Vite, and Tailwind frontend
- typed frontend helpers through
@semitra/cli/frontend
Request flow
Section titled “Request flow”Always preserve this flow:
Request -> Router -> Controller -> Policy -> Model -> Events -> Resource -> ResponseUse each layer for one responsibility:
| Layer | Responsibility |
|---|---|
| Router | Map method and path to controller action. |
| Controller | Coordinate params, authorization, records, side effects, and rendering. |
| Policy | Authorize actions, scope records, and expose field visibility. |
| Model | Persist D1-backed application state through SemitraRecord. |
| Events | Publish domain signals and fan-out reactions. |
| Jobs | Run durable queued work. |
| Resource | Define public JSON response shape. |
| Response | Return a Web Standard Response. |
Canonical app layout
Section titled “Canonical app layout”Backend Semitra apps use this source layout:
app/ controllers/ models/ resources/ policies/ jobs/ mailers/ mailboxes/ channels/config/ application.ts routes.tsdb/ migrate/ schema.tssrc/ index.tsGenerated full-stack workspaces use:
apps/apiapps/webapps/api owns the Worker backend. apps/web owns the React Router frontend.
Base classes
Section titled “Base classes”Use Semitra-prefixed framework base classes through app-level base classes:
| Framework class | App-level class |
|---|---|
SemitraController | ApplicationController |
SemitraRecord | ApplicationRecord |
SemitraResource | ApplicationResource |
SemitraPolicy | ApplicationPolicy |
SemitraJob | ApplicationJob |
SemitraMailer | ApplicationMailer |
SemitraMailbox | ApplicationMailbox |
SemitraChannel | ApplicationChannel |
Cloudflare mapping
Section titled “Cloudflare mapping”| Cloudflare primitive | Semitra subsystem |
|---|---|
| D1 | Records and migrations |
| R2 | Storage and attachments |
| KV | Cache |
| Queues | Jobs and queued events |
| Durable Objects | Realtime coordination |
Application code should use Semitra abstractions before raw Worker bindings.
Common task recipes
Section titled “Common task recipes”Add a JSON resource endpoint
Section titled “Add a JSON resource endpoint”- Add or update a migration under
db/migrate. - Add a
SemitraRecordmodel underapp/models. - Add a
SemitraResourceserializer underapp/resources. - Add a
SemitraPolicyunderapp/policies. - Add a controller action under
app/controllers. - Add a route in
config/routes.ts, usually underapi(() => { ... }). - Run
semitra codegen. - Add or update tests for the request contract and behavior.
Add frontend access to an endpoint
Section titled “Add frontend access to an endpoint”- Add a frontend model under
apps/web/app/models. - Add a
defineSemitraEndpoint(...)entry inapps/web/app/lib/api.ts. - Parse responses with the frontend model schema.
- Keep API calls centralized in
app/lib/api.tsor small hooks that wrap it. - Use
VITE_API_BASE_URLonly when the API runs on a different origin.
Add durable side effects
Section titled “Add durable side effects”- Emit a domain event when the application state changes.
- Use a job when work must be durable, retryable, or delayed.
- Define payload schemas for event or job payloads.
- Preserve trace IDs and tenant context when using envelopes.
Add tenant-aware uploads
Section titled “Add tenant-aware uploads”- Resolve the tenant in
config/application.ts. - Store relational metadata in D1 records.
- Store object bodies in R2 through
SemitraStorageor record attachments. - Use policies to decide who can upload, replace, read, or delete files.
- Use tenant-aware key prefixes instead of manually concatenating tenant keys in controllers.
Do not infer these incorrectly
Section titled “Do not infer these incorrectly”- The example header-based
currentUserpattern is demonstration auth, not a production session system. - The root repo currently has no canonical root lint or typecheck script.
apps/docs/distand.semitra/generatedare generated outputs, not the source docs or source app code.nodejs_compatin a Worker config does not make Node APIs part of the Semitra runtime contract.- Backend response shape belongs in resources, not ad hoc controller objects when returning records.
- Frontend architecture is chosen: React Router 7 framework mode, Vite, and Tailwind CSS.
Retrieval targets
Section titled “Retrieval targets”Use these pages for focused context:
| Question | Page |
|---|---|
| What should I build with Semitra? | Use Cases |
How do apps/api and apps/web fit together? | Full-Stack Apps |
| How does a request move through the framework? | Request Lifecycle |
| Where do files go? | Conventions and Layout |
| How do routes work? | Routing |
| How do controllers validate and render? | Controllers |
| How do records persist data? | Records |
| How do resources define responses? | Resources |
| How should authorization work? | Policies |
| How does runtime binding access work? | Adapters and Runtime |
| What commands are available? | CLI and Generators |
Verification commands
Section titled “Verification commands”For docs-only edits, run:
bun run docs:buildFor framework behavior changes, also run the relevant tests:
bun testbun run smoke