Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 18 additions & 24 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,38 @@ Documentation:

Development workflows:

- This is a Node.js monorepo managed with Yarn workspaces
- Published packages are prefixed with `@metamask/`, private packages with `@ocap/`
- Use `yarn` and `yarn workspace` to run package scripts:
- `lint:fix` for linting
- `test:dev:quiet` for unit tests, add `--coverage=true` to include coverage
- if available, integration and e2e tests invoked separately via
`test:integration` and `test:e2e`, respectively
- `build` and `test:dev` from root are cached using Turboerpo (`turbo`)
- `build`, `build:dev`, `test:dev`, and `test:dev:quiet` from root are cached using Turborepo (`turbo`)
- No other scripts use `turbo`
- When adding another monorepo package as a dependency, also add it to
`references` in both `tsconfig.json` and `tsconfig.build.json`

General conventions:

- Use `@metamask/superstruct` for runtime type checking and to define object types
- Use TypeDoc for documentation
- Naming conventions:
- Nouns for variable names (e.g. `isKernelActive`, `hasVatAccess`, `unresolvedMessages`)
- Verbs for function names (e.g. `startVat`, `stopKernel`)
- kebab-case for package and file names (`@ocap/test-utils`, `kernel-worker.js`, `vat.js`)
- Factory methods: `X.make()`
- Factory functions: `makeX()`
- kebab-case for package and file names (`@ocap/test-utils`, `kernel-worker.js`, `vat.js`)
- If a function has more than two arguments or could be expected to grow thereto,
give it an options bag (i.e. named parameters)

Object capability (ocap) patterns:

- Production code should run under "lockdown" from `@endo/lockdown`
- Production code must run under "lockdown" from `@endo/lockdown` / `ses` via the local `@metamask/kernel-shims` package
— Many `@endo/*` packages fail silently or throw in non-locked-down environments
- Lockdown must be the first thing that runs in the given JavaScript realm for it to work
- Use `harden()` from `@endo/ses` for immutability where feasible
- Including object literals, class instances, class prototypes, etc.
- Use "development" mode (per-package) only for local debugging; it disables lockdown and
coverage and does not run in CI
- Some tests use a mock shim from `@ocap/repo-tools/test-utils/mock-endoify` for test runner compatibility
- Use `harden()` (globally available via lockdown) for immutability where feasible:
- Harden class instances: `harden(this)` at the end of constructors
- Harden classes: `harden(ClassName)` after the class definition
- Harden returned object literals inline: `return harden({ ... })`
- Use `E()` from `@endo/eventual-send` to:
- Communicate with objects between vats or between processes with a CapTP connection
- Queue messages on a promise (that resolves to some object with methods)
Expand All @@ -44,16 +49,11 @@ Testing:
- Use `vitest` for testing
- Avoid introducing global state in tests
- If you need a mock object of type `Foo`, add a utility like `const makeFoo = () => { ... }`
- Always use `toStrictEqual()` for deep object comparisons
- If testing all properties of an object, use a single `toStrictEqual()` on the entire object
instead of multiple `expect()` calls
- Use `it.each()` for parameterized tests
- Use logically nested `describe()` blocks
- If testing all properties of an object, use a single `toStrictEqual()` on the entire object
instead of multiple `expect()` calls
- Prefer `it.each()` for parameterized tests
- Test titles should use concise verb forms without "should" (e.g., `it('creates and starts libp2p node', ...)` not `it('should create and start libp2p node', ...)`)
- Avoid negative cases, but if you must, use "does not" instead of "should not" (e.g., `it('does not duplicate relays', ...)`)
- Mock functions with `vi.fn()` and explicit return types
- Mock external dependencies using vitest's `vi.mock()`
- Aim for complete unit test coverage when writing tests
- Check the local package `@ocap/test-utils` (`packages/test-utils`) for test utilities before creating new ones
- Use `vi.useFakeTimers()` for tests that rely on timers

Expand All @@ -72,12 +72,6 @@ File and directory structure:
- Test utilities used by a single package should be separated into that package's `<package-root>/test/` directory
- Test utilities used by multiple packages should be relocated into the dedicated `test-utils` package

UI and styling:

- For React UI components, prefer CSS classes (e.g., `className="bg-section p-4 rounded mb-4"`) over inline styles
- Use design system components (BadgeStatus, TextComponent, etc.) consistently
- Maintain consistent spacing patterns (e.g., `gap-12`, `mb-4`, `mt-2`)

Cross-environment compatibility:

- Libraries should be platform-agnostic and run in any environment unless otherwise specified
Expand Down
Loading