Skip to content
Merged
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"permissions": {
"allow": ["Skill(code-review)", "Skill(glossary)"],
"deny": ["Read(**/.env)", "Read(**/.env.*)"]
}
}
17 changes: 17 additions & 0 deletions .claude/skills/code-review/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: code-review
description: How to review code; a pull request, feature branch, local changes etc.
---

When asked to review code, whether a PR on GitHub or some local changes, provide feedback on:

- Code quality and best practices
- Potential bugs or issues
- Performance considerations
- Security concerns
- Test coverage

Use the repository's CLAUDE.md for guidance on style and conventions.
If you encounter terms that should be added to the glossary, invoke the glossary
skill using: Skill tool with skill="glossary"
Be constructive and helpful in your feedback.
14 changes: 14 additions & 0 deletions .claude/skills/glossary/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
name: glossary
description: How to add entries to the glossary
---

The [glossary](../../docs/glossary.md) explains terms with specific meanings in this
project. When a new term is introduced—or an old term without a glossary entry discovered—
consider adding the term to the glossary.

When doing so:

- Include links to relevant implementation files using `[term](../path/to/file.ts)` syntax
- Use cross-references with `[term](#term)` syntax to link related concepts
- Consider how new terms relate to existing architectural concepts
198 changes: 63 additions & 135 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,148 +1,76 @@
Code style and structure:

- Write concise, accurate JavaScript/TypeScript with modern ES Module syntax.
- Always use TypeScript unless otherwise specified.
- Use a class-based structure where applicable.
- Use `harden()` from `@endo/ses` for object security.
- Use object capability (ocap) design patterns.
- Use `@metamask/superstruct` for validation.
- Use TypeDoc for documentation.
- Use the following naming conventions:
- camelCase for functions and variables.
- PascalCase for classes, types, interfaces, and enums.
- kebab-case for package and file names (`@ocap/test-utils`, `kernel-worker.js`, `vat.js`).
- Nouns for variable names (e.g. `isKernelActive`, `hasVatAccess`, `unresolvedMessages`)
- Verbs for function names (e.g. `startVat`, `stopKernel`)
- Use explicit return types for all functions.

Testing and debugging:

- Use `vitest` for testing.
- Prefer `toStrictEqual()` for deep object comparisons in tests.
- Use `it.each()` for parameterized tests.
- Use descriptive test blocks with proper nesting.
- 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', ...)`).
- For negative cases, use "does not" instead of "should not" (e.g., `it('does not duplicate relays', ...)`).
- Mock functions with `vi.fn()` and explicit return types.
- Aim for high test coverage, including unit and integration tests.
- Mock external dependencies using vitest's `vi.mock()`.

TypeScript usage:
Documentation:

- Use types for defining message structures and data contracts. Do not use `interface` declarations.
- Leverage union types and type guards for robust runtime checks.
- Use `Readonly<T>` for immutable data structures.
- Follow strict mode settings for TypeScript.
- Never use the `any` type.
- Prefer `#` private fields over `private` class fields.
- Check the [glossary](./docs/glossary.md) for definitions of unclear terms.

File and directory structure:
Development workflows:

- Maintain a monorepo structure using Yarn workspaces.
- Place package source files under `<package-root>/src/`.
- Co-locate a package's unit tests with their covered source files in the `<package-root>/src/` directory (e.g. `ocap-kernel/src/kernel-worker.ts` should be tested in `ocap-kernel/src/kernel-worker.test.ts`).
- Test utilities used by a single package should be separated into that package's `<package-root>/test/` directory.
- If the utility is small, it can be in-lined in the test file.
- Test utilities used by multiple packages should be relocated into the dedicated `test-utils` package.
- Use `yarn` and `yarn workspace` to run package scripts:
- `lint:fix` for linting
- `test:dev` for unit tests, `test` to include coverage
- e2e tests invoked separately via `test:e2e`, if available
- `build` from root is cached using Turborepo

Kernel architecture:
General conventions:

- Ensure clear separation of concerns between Kernel, Vat, and Supervisor components.
- Use streams from the `streams` package for message passing / IPC.
- 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()`
- 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`
- 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 `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)
- If an object is to be made remotable, turn it into an exo using the internal `makeDefaultExo`
which builds on `@endo/exo`
- Do not use `Far` from `@endo/far`
- It's fine to use `E()` on local objects that aren't exos

Testing:

- Use `vitest` for testing
- Always use `toStrictEqual()` for deep object comparisons
- Use `it.each()` for parameterized tests
- Use logically nested `describe()` blocks
- 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

TypeScript:

- Prefer `type`; do not use `interface` declarations
- Prefer `#` private fields over `private` class fields
- Never use the `any` type
- Never use `enum`:s; always use string literal unions instead

Web extensions:
File and directory structure:

- Use the latest manifest version (v3) for Chrome.
- Minimize permissions in `manifest.json`, using optional permissions where feasible.
- Apply Content Security Policies (CSP) in `manifest.json`.
- Maintain a monorepo structure using Yarn workspaces
- Place package source files under `<package-root>/src/`
- Co-locate a package's unit tests with their covered source files in the `<package-root>/src/` directory (e.g. `ocap-kernel/src/kernel-worker.ts` should be tested in `ocap-kernel/src/kernel-worker.test.ts`)
- 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:

- Create responsive designs for UI components like popups or settings.
- Use Flexbox or CSS Grid for layout consistency.
- Use plain CSS, HTML, and JavaScript for UI components. Do not use React or other frameworks.
- For React UI components, prefer CSS classes (e.g., `className="bg-section p-4 rounded mb-4"`) over inline styles.
- Use inline styles only for dynamic values or when CSS classes are not available.
- Structure layouts with semantic containers and proper spacing.
- Use design system components (BadgeStatus, TextComponent, etc.) consistently.
- Group related UI elements in logical sections with descriptive comments.
- Maintain consistent spacing patterns (e.g., `gap-12`, `mb-4`, `mt-2`).
- Use responsive classes and proper flex layouts for different screen sizes.
- 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.
- Packages like `extension` (browser) and `cli` (Node.js) are platform-specific.
- Implement graceful degradation for environment-specific features.

Type safety:

- Prefer `@metamask/superstruct` when defining object types.
- Use runtime type guards, not type assertions, when type narrowing is required.
- Define object types for all data structures.
- Avoid redundant type declarations.

Error handling:

- Use structured error classes with inheritance, error codes, and messages.
- Implement error marshaling and unmarshaling.
- Use type guards for error checking.

Documentation:

- Check the [glossary](./docs/glossary.md) for definitions of unclear terms.
- Use JSDoc and TypeDoc for public APIs.
- Include examples and document error cases.
- When adding glossary entries:
- Include links to relevant implementation files using `[term](../path/to/file.ts)` syntax
- Use cross-references with `[term](#term)` syntax to link related concepts
- Consider how new terms relate to existing architectural concepts

PR review:

- Check if new terms, concepts, or architectural patterns are introduced that should be added to the glossary for AI agent accessibility.
- Consider adding glossary entries for:
- New technical terms or abbreviations
- Core architectural components
- Important data structures or types
- Communication patterns or protocols
- System operations or processes
- Include links to relevant implementation files when adding glossary entries.

Changelog management:

- Follow Keep a Changelog v1.0.0 format (https://keepachangelog.com/en/1.0.0/) for all CHANGELOG.md files.
- For release PRs, categorize "### Uncategorized" entries into:
- "### Added" for new features and functionality (entries starting with "feat:")
- "### Changed" for changes to existing functionality (entries starting with "chore:" or breaking changes)
- "### Deprecated" for soon-to-be removed features
- "### Removed" for now removed features
- "### Fixed" for bug fixes and corrections (entries starting with "fix:" or "refactor:")
- "### Security" in case of vulnerabilities
- Each changelog should describe changes specific to that package
- Skip dependency updates unless they cause downstream changes; if so, describe the actual changes instead
- Remove prefixes like "feat:", "chore:", "fix:", "refactor:" from changelog entries
- Use clean, descriptive language without technical prefixes
- When running in agent mode, fetch GitHub PR descriptions to better understand:
- The actual impact of each change on the specific package
- Whether dependency updates introduce breaking changes or new functionality
- More context for writing accurate, descriptive changelog entries
- Use PR descriptions to determine if changes should be:
- Skipped entirely (pure dependency bumps with no package impact)
- Rewritten to focus on user-facing changes rather than implementation details
- Moved to different categories based on actual impact
- Example transformations:
- "feat(ocap-kernel): Add kernel command 'revoke'" → "Add kernel command 'revoke'"
- "chore: bump endo dependencies" → Remove (unless it causes package-specific changes)
- "fix: make Revoke button refresh object registry" → "Make Revoke button refresh object registry"

Context-aware development:

- Align new code with existing project structure for consistency.
- Prioritize modular, reusable components.

Code output:

- Provide complete, self-contained examples.
- Include necessary imports and context for code snippets.
- Document significant changes, especially for Endo-specific patterns or Chrome APIs.
- Libraries should be platform-agnostic and run in any environment unless otherwise specified
- Packages like `extension` (browser) and `cli` (Node.js) are platform-specific
Loading