Skip to content
Agentmart
Submit a tool

CLAUDE.md · moltis-org/moltis

CLAUDE.md from moltis-org/moltis: 534 lines covering Cargo Features, Workspace Dependencies, Config Schema and Validation, Rust Style and Idioms and more.

Template by moltis-org

IndexedMIT★ 2,906
Write a review

Install

Works with Claude Code. Read the repository before you give any tool access to your data.

curl -fsSL https://raw.githubusercontent.com/moltis-org/moltis/main/CLAUDE.md -o CLAUDE.md

Read it and adapt it to your project before use.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

The CLAUDE.md file that moltis-org/moltis (2,906 stars) keeps for coding agents. It has 534 lines in 20 sections: Cargo Features; Workspace Dependencies; Config Schema and Validation; Rust Style and Idioms; Build Commands; Web UI (TypeScript + Preact + Vite); API Namespace Convention; Channel Message Handling; Adding Channels; Authentication Architecture; Testing; Code Quality; Sandbox Architecture; Logging Levels; Security; Data and Config Directories; Database Migrations; Provider Implementation; Changelog; Git Workflow. Use it as a model for your own project's instructions.

Use cases: prompt-engineering

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

What's in it

A CLAUDE.md file: project memory Claude Code loads at the start of every session.

For
Claude Code
Length
534 lines
File
CLAUDE.md

Sections

  1. Cargo Features
  2. Workspace Dependencies
  3. Config Schema and Validation
  4. Rust Style and Idioms
  5. Build Commands
  6. Web UI (TypeScript + Preact + Vite)
  7. API Namespace Convention
  8. Channel Message Handling
  9. Adding Channels
  10. Authentication Architecture
  11. Testing
  12. Code Quality
  13. Sandbox Architecture
  14. Logging Levels
  15. Security
  16. Data and Config Directories
  17. Database Migrations
  18. Provider Implementation
  19. Changelog
  20. Git Workflow

First lines (shown under the repo's MIT license)

---
description: "Moltis engineering guide for Claude/Codex agents: Rust architecture, testing, security, and release workflows"
alwaysApply: true
---

# CLAUDE.md

Rust version of openclaw ([docs](https://docs.openclaw.ai), [code](https://github.com/openclaw/openclaw)).
All code must have tests with high coverage. Always check for security.

## Cargo Features

Enable new feature flags **by default** in `crates/cli/Cargo.toml` (opt-out, not opt-in):
```toml
[features]
default = ["foo", ...]
foo = ["moltis-gateway/foo"]
```

## Workspace Dependencies

Add new crates to `[workspace.dependencies]` in root `Cargo.toml`, reference with `{ workspace = true }`.
Never add versions directly in crate `Cargo.toml`. Use latest stable crates.io version.

## Config Schema and Validation

When adding/renaming fields in `MoltisConfig` (`crates/config/src/schema.rs`), also update
`build_schema_map()` in `crates/config/src/validate.rs`. New enum variants for string-typed
fields need updates in `check_semantic_warnings()`.

## Rust Style and Idioms

- **File size limit: 1,500 lines.** CI enforces this via `scripts/check-file-size.sh`. Split large files into modules by domain. Existing oversize files are allowlisted for incremental decomposition.
- Do not add implementation code to `mod.rs` or `lib.rs`. Keep those files for module wiring, exports, and crate setup, move real logic into dedicated sibling modules.
- Use traits for behaviour boundaries. Prefer generics for hot paths, `dyn Trait` for heterogeneous/runtime dispatch.
- Derive `Default` when all fields have sensible defaults.
- Use concrete types (`struct`/`enum`) over `serde_json::Value` wherever shape is known.
- **Match on types, never strings.** Only convert to strings at serialization/display boundaries.
- Prefer `From`/`Into`/`TryFrom`/`TryInto` over manual conversions. Ask before adding manual conversion paths.
- **DRY cross-crate types:** When two crates need the same enum/struct, define it once in the lower-level crate and re-export via `pub type Alias = other_crate::Type` from the higher-level one. Never duplicate enums across crates or round-trip through strings (`parse(&id.to_string())`) to convert between mirror types.
- Prefer streaming over non-streaming API calls.
- Run independent async work concurrently (`tokio::join!`, `futures::join_all`).
- Never use `block_on` inside async context.
- **Forbidden:** `Mutex<()>` / `Arc<Mutex<()>>` — mutex must guard actual state.
- Use `anyhow::Result` for app errors, `thiserror` for library errors. Propagate with `?`.
- **Never `.unwrap()`/`.expect()` in production.** Workspace lints deny these. Use `?`, `ok_or_else`, `unwrap_or_default`, `unwrap_or_else(|e| e.into_inner())` for locks.
- Use `time` crate (workspace dep) for date/time — no manual epoch math or magic constants like `86400`.
- Prefer `chrono` only if already imported in the crate; default to `time` for new code.
- Prefer crates over subprocesses (`std::process::Command`). Use subprocesses only when no mature crate exists.
- Prefer guard clauses (early returns) over nested `if` blocks.
- Prefer iterators/combinators over manual loops. Use `Cow<'_, str>` when allocation is conditional.
- Keep public API surfaces small. Use `#[must_use]` where return values matter.

### Tracing and Metrics

All crates must have `tracing` and `metrics` features, gated with `#[cfg(feature = "...")]`.
Use `tracing::instrument` on async functions. Record metrics at key points (counts, durations, errors).
See `docs/metrics-and-tracing.md`.

## Build Commands

```bash
cargo build                  # Debug build
cargo build --release        # Release build
cargo run / cargo run --release
```

## Web UI (TypeScript + Preact + Vite)

TypeScript/TSX source in `crates/web/ui/src/`, built with Vite to `crates/web/src/assets/dist/`.
CSS and static assets in `crates/web/src/assets/`. Release mode embeds via `include_dir!`.
Generated assets (`dist/`, `css/style.css`, `style.css`, `sw.js`) are gitignored.
Run `just build-web-assets` to generate them (requires Node.js).
A `build.rs` check warns (debug) or fails (release/embedded-assets) if they are missing.
See `docs/src/frontend.md` for the full architecture guide.

### Build Commands

```bash
cd crates/web/ui
npm run build          # Vite: TS/TSX → dist/
npm run build:css      # Tailwind: input.css → ../src/assets/css/style.css
npm run build:sw       # esbuild: src/sw.ts → ../src/assets/sw.js
npm run build:all      # All three above
npm run dev            # Vite watch mode (rebuilds on save)
npx tsc --noEmit       # Type check (strict, must be 0 errors)
```

**After changing TS/TSX files**, always:
1. `biome check --write crates/web/ui/src/`
2. `cd crates/web/ui && npm run build`
3. `cd crates/web/ui && npx tsc --noEmit`

### TypeScript Rules

- **File size limit: 1,500 lines** (same rule as Rust). Split large files into modules by domain.
  - Pages: extract sections/modals into `pages/sections/`, `pages/channels/`, `pages/chat/`, etc.
  - Utilities: extract sub-modules into sibling directories (`providers/`, `sessions/`, `ws/`).
  - Keep shared signals, types, and re-exports in the main file; move logic into sub-modules.
- All UI code is **TypeScript** with **JSX** (Preact). No HTM tagged templates.
- Add typed Props interfaces for all Preact components.
- Use `@preact/signals` with generic type parameters: `signal<string[]>([])`.
- Prefer typed interfaces over `Record<string, unknown>` — define concrete shapes where property access is known.
- Use `targetValue(e)` / `targetChecked(e)` from `typed-events.ts` for form event handlers.
- No `any` types — use `unknown` with type guards or specific interfaces.
- Use shared components from `components/forms/` (TextField, SaveButton, ListItem, Badge, TabBar, etc.).

### CSS Rules

- **Always use Tailwind classes** instead of inline `style="..."`.
- Reuse CSS classes from `components.css`: `provider-btn`, `provider-btn-secondary`, `provider-btn-danger`.
- Match button heights/text sizes when elements sit together.
- **Rebuild Tailwind** after adding new classes: `cd crates/web/ui && npm run build:css`.

### Adding Settings Nav Icons

Settings sidebar icons use `::before` pseudo-elements in `components.css`, **not** the `icon`
JSX property in the `sections` array. When adding a new settings section:

1. Create the SVG mask in `crates/web/src/assets/icons/masks/` with `fill="black"` (not `currentColor`)
2. Add `.icon-<name>` class in `crates/web/ui/input.css` under the mask-image icons section
3. **Also add** `.settings-nav-item[data-section="<id>"]::before` in `crates/web/src/assets/css/components.css`
   pointing to the SVG — without this the icon renders as a black square
4. The `icon: <span className="icon icon-<name>" />` in `SettingsPage.tsx` is a fallback only

### E2E Test Shims

E2E tests dynamically import individual JS modules (`js/state.js`, `js/helpers.js`, etc.).
With Vite bundling, these don't exist as standalone files. Shim files in `src/assets/js/`
proxy to `window.__moltis_modules` (populated by `app.tsx`). When adding new modules that
tests import, add a shim file and expose the module in `app.tsx`.

### Selection Cards

Use clickable cards (`.model-card`, `.backend-card` in `input.css`) instead of dropdowns for option selection.
States: `.selected`, `.disabled`, default. Badges: `.recommended-badge`, `.tier-badge`.

### Provider Config Storage

Provider keys in `~/.config/moltis/provider_keys.json` via `KeyStore` in `provider_setup.rs`.
When adding fields, update: `ProviderConfig` struct, `available()` response, `save_key()`.

### Server-Injected Data (gon pattern)

For server data needed at page load: add to `GonData` in `server.rs` / `build_gon_data()`.
TS side: `import * as gon from "./gon"` — use `gon.get()`, `gon.onChange()`, `gon.refresh()`.
Types in `crates/web/ui/src/types/gon.ts` mirror the Rust `GonData` struct.
Never inject inline `<script>` tags or build HTML in Rust.

### Event Bus

Server events via WebSocket: `import { onEvent } from "./events"`. Returns unsubscribe function.
Do **not** use `window.addEventListener`/`CustomEvent` for server events.

## API Namespace Convention

Each UI tab gets its own API namespace: REST `/api/<feature>/...` and RPC `<feature>.*`.
Never merge features into a single endpoint.

## Channel Message Handling

Signals

Stars
2,906
Forks
359
Open issues
76
Last commit (this folder)
Aug 20, 2026 (2 months ago)
Last release
Oct 23, 2026 (6 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from moltis-org

Cite this page

CLAUDE.md · moltis-org/moltis. Agent Mart. https://agentmart.dev/templates/moltis-org-moltis-claude-md (last updated 2026-10-24)