You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Prefer the Tokio-shaped APIs from `antiox` for concurrency needs. For example, use `antiox/sync/mpsc` for `tx` and `rx` channels, `antiox/task` for spawning tasks, and the matching sync and time modules as needed.
105
105
- Treat `antiox` as the default choice for any TypeScript concurrency work because it mirrors Rust and Tokio APIs used elsewhere in the codebase.
106
106
107
+
### RivetKit Type Build Troubleshooting
108
+
- If `rivetkit` type or DTS builds fail with missing `@rivetkit/*` declarations, run `pnpm build -F rivetkit` from repo root (Turbo build path) before changing TypeScript `paths`.
109
+
- Do not add temporary `@rivetkit/*` path aliases in `rivetkit-typescript/packages/rivetkit/tsconfig.json` to work around stale or missing built declarations.
110
+
111
+
### RivetKit Driver Registry Variants
112
+
- Keep `rivetkit-typescript/packages/rivetkit/fixtures/driver-test-suite/registry.ts` as the canonical type anchor for fixtures and test typing.
113
+
- Run driver runtime suites through `registry-static.ts` and `registry-dynamic.ts` instead of executing `registry.ts` directly.
114
+
- Load static fixture actors with dynamic ESM `import()` from the `fixtures/driver-test-suite/actors/` directory.
115
+
- Skip dynamic registry parity only for the explicit nested dynamic harness gate or missing secure-exec dist, and still treat full static and dynamic compatibility as the target for all normal driver suites.
116
+
107
117
### SQLite Package
108
118
- Use `@rivetkit/sqlite` for SQLite WebAssembly support.
109
119
- Do not use the legacy upstream package directly. `@rivetkit/sqlite` is the maintained fork used in this repository and is sourced from `rivet-dev/wa-sqlite`.
110
120
- The native SQLite addon (`@rivetkit/sqlite-native`) statically links SQLite via `libsqlite3-sys` with the `bundled` feature. The bundled SQLite version must match the version used by `@rivetkit/sqlite` (WASM). When upgrading either, upgrade both.
111
121
112
122
### RivetKit Package Resolutions
113
-
The root `/package.json` contains `resolutions` that map RivetKit packages to their local workspace versions:
123
+
-The root `/package.json` contains `resolutions` that map RivetKit packages to local workspace versions:
114
124
115
125
```json
116
126
{
@@ -123,7 +133,7 @@ The root `/package.json` contains `resolutions` that map RivetKit packages to th
123
133
}
124
134
```
125
135
126
-
When adding RivetKit dependencies to examples in `/examples/`, use `*` as the version. The root resolutions will automatically resolve these to the local workspace packages:
136
+
- Use `*` as the dependency version when adding RivetKit packages to `/examples/`, because root resolutions map them to local workspace packages:
127
137
128
138
```json
129
139
{
@@ -134,7 +144,19 @@ When adding RivetKit dependencies to examples in `/examples/`, use `*` as the ve
134
144
}
135
145
```
136
146
137
-
If you need to add a new `@rivetkit/*` package that isn't already in the root resolutions, add it to the `resolutions` object in `/package.json` with `"workspace:*"` as the value. Internal packages like `@rivetkit/workflow-engine` should be re-exported from `rivetkit` subpaths (e.g., `rivetkit/workflow`) rather than added as direct dependencies.
147
+
- Add new internal `@rivetkit/*` packages to root `resolutions` with `"workspace:*"` if missing, and prefer re-exporting internal packages (for example `@rivetkit/workflow-engine`) from `rivetkit` subpaths like `rivetkit/workflow` instead of direct dependencies.
148
+
149
+
### Dynamic Import Pattern
150
+
- For runtime-only dependencies, use dynamic loading so bundlers do not eagerly include them.
151
+
- Build the module specifier from string parts (for example with `["pkg", "name"].join("-")` or `["@scope", "pkg"].join("/")`) instead of a single string literal.
152
+
- Prefer this pattern for modules like `@rivetkit/sqlite-vfs`, `sandboxed-node`, and `isolated-vm`.
153
+
- If loading by resolved file path, resolve first and then import via `pathToFileURL(...).href`.
154
+
155
+
### Fail-By-Default Runtime Behavior
156
+
- Avoid silent no-ops for required runtime behavior.
157
+
- Do not use optional chaining for required lifecycle and bridge operations (for example sleep, destroy, alarm dispatch, ack, and websocket dispatch paths).
158
+
- If a capability is required, validate it and throw an explicit error with actionable context instead of returning early.
159
+
- Optional chaining is acceptable only for best-effort diagnostics and cleanup paths (for example logging hooks and dispose/release cleanup).
138
160
139
161
### Rust Dependencies
140
162
@@ -154,29 +176,29 @@ If you need to add a new `@rivetkit/*` package that isn't already in the root re
154
176
155
177
### Docs (`website/src/content/docs/**/*.mdx`)
156
178
157
-
Required frontmatter fields:
179
+
-Required frontmatter fields:
158
180
159
181
-`title` (string)
160
182
-`description` (string)
161
183
-`skill` (boolean)
162
184
163
185
### Blog + Changelog (`website/src/content/posts/**/page.mdx`)
All example READMEs in `/examples/` should follow the format defined in `.claude/resources/EXAMPLE_TEMPLATE.md`.
201
+
-All example READMEs in `/examples/` should follow the format defined in `.claude/resources/EXAMPLE_TEMPLATE.md`.
180
202
181
203
## Agent Working Directory
182
204
@@ -188,11 +210,12 @@ All agent working files live in `.agent/` at the repo root.
188
210
-**Notes**: `.agent/notes/` -- general notes and tracking.
189
211
190
212
When the user asks to track something in a note, store it in `.agent/notes/` by default. When something is identified as "do later", add it to `.agent/todo/`. Design documents and interface specs go in `.agent/specs/`.
213
+
- When the user asks to update any `CLAUDE.md`, add one-line bullet points only, or add a new section containing one-line bullet points.
191
214
192
215
## Architecture
193
216
194
217
### Monorepo Structure
195
-
This is a Rust workspace-based monorepo for Rivet. Key packages and components:
218
+
-This is a Rust workspace-based monorepo for Rivet with the following key packages and components:
196
219
197
220
-**Core Engine** (`packages/core/engine/`) - Main orchestration service that coordinates all operations
198
221
-**Workflow Engine** (`packages/common/gasoline/`) - Handles complex multi-step operations with reliability and observability
@@ -208,7 +231,7 @@ This is a Rust workspace-based monorepo for Rivet. Key packages and components:
208
231
- Custom error system at `packages/common/error/`
209
232
- Uses derive macros with struct-based error definitions
210
233
211
-
To use custom errors:
234
+
- Use this pattern for custom errors:
212
235
213
236
```rust
214
237
userivet_error::*;
@@ -237,13 +260,13 @@ let error = AuthInvalidToken.build();
- Do not glob import (`::*`) from anyhow. Instead, import individual types and traits
248
271
- Prefer anyhow's `.context()` over `anyhow!` macro
249
272
@@ -283,7 +306,7 @@ Key points:
283
306
284
307
## Naming Conventions
285
308
286
-
Data structures often include:
309
+
-Data structures often include:
287
310
288
311
-`id` (uuid)
289
312
-`name` (machine-readable name, must be valid DNS subdomain, convention is using kebab case)
@@ -320,6 +343,7 @@ Data structures often include:
320
343
-**Never use `vi.mock`, `jest.mock`, or module-level mocking.** Write tests against real infrastructure (Docker containers, real databases, real filesystems). For LLM calls, use `@copilotkit/llmock` to run a mock LLM server. For protocol-level test doubles (e.g., ACP adapters), write hand-written scripts that run as real processes. If you need callback tracking, `vi.fn()` for simple callbacks is acceptable.
321
344
- When running tests, always pipe the test to a file in /tmp/ then grep it in a second step. You can grep test logs multiple times to search for different log lines.
322
345
- For RivetKit TypeScript tests, run from `rivetkit-typescript/packages/rivetkit` and use `pnpm test <filter>` with `-t` to narrow to specific suites. For example: `pnpm test driver-file-system -t ".*Actor KV.*"`.
346
+
- When RivetKit tests need a local engine instance, start the RocksDB engine in the background with `./scripts/run/engine-rocksdb.sh >/tmp/rivet-engine-startup.log 2>&1 &`.
323
347
- For frontend testing, use the `agent-browser` skill to interact with and test web UIs in examples. This allows automated browser-based testing of frontend applications.
324
348
- If you modify frontend UI, automatically use the Agent Browser CLI to take updated screenshots and post them to the PR with a short comment before wrapping up the task.
325
349
@@ -332,7 +356,7 @@ Data structures often include:
332
356
- When talking about "Rivet Actors" make sure to capitalize "Rivet Actor" as a proper noun and lowercase "actor" as a generic noun
333
357
334
358
### Documentation Sync
335
-
When making changes to the engine or RivetKit, ensure the corresponding documentation is updated:
359
+
- Ensure corresponding documentation is updated when making engine or RivetKit changes:
336
360
-**Limits changes** (e.g., max message sizes, timeouts): Update `website/src/content/docs/actors/limits.mdx`
337
361
-**Config changes** (e.g., new config options in `engine/packages/config/`): Update `website/src/content/docs/self-hosting/configuration.mdx`
338
362
-**RivetKit config changes** (e.g., `rivetkit-typescript/packages/rivetkit/src/registry/config/index.ts` or `rivetkit-typescript/packages/rivetkit/src/actor/config.ts`): Update `website/src/content/docs/actors/limits.mdx` if they affect limits/timeouts
@@ -359,8 +383,8 @@ When making changes to the engine or RivetKit, ensure the corresponding document
359
383
360
384
#### Common Vercel Example Errors
361
385
362
-
After regenerating Vercel examples, you may see typecheck errors like:
386
+
- You may see type-check errors like the following after regenerating Vercel examples:
363
387
```
364
388
error TS2688: Cannot find type definition file for 'vite/client'.
365
389
```
366
-
with warnings about `node_modules missing`. This happens because the regenerated examples need their dependencies reinstalled. Fix by running `pnpm install` before running type checks.
390
+
- You may also see `node_modules missing` warnings; fix this by running `pnpm install` before type checks because regenerated examples need dependencies reinstalled.
0 commit comments