AGENTS.md · git:20261029.6ceb570 · 2026-10-29 · sha256 de9d4a845d6278c4
AGENTS.md git:20261029.6ceb570A
Immutable. This exact content never changes and is served at /api/v1/blob/de9d4a845d6278c4.
Agent chat UI powered by Claude Agent SDK, Bun, React, and Tailwind. ## Structure - `server/` — Bun server, agent backends, WebSocket, state persistence; see [server/README.md](server/README.md) for module ownership and storage paths - `client/` — React SPA, components, hooks, styles - `lib/` — Shared types between server and client ## Agent context layout `AGENTS.md` files (root, `client/`, `server/`) are the canonical instructions. Claude Code v2.1.277+ reads them directly when no `CLAUDE.md` or `CLAUDE.local.md` exists in the working directory or above it. Keep project instructions in `AGENTS.md`. Rules and skills live in agent-neutral directories, with symlinks for Claude Code: - `.agents/rules/` — topic rules (canonical). `.claude/rules` is a symlink to it, so Claude Code auto-loads them. **Other agents: read the relevant rule before editing matching files:** - `product-language.md` (always) — `Moi` casing, sentence case, terminology, and action copy - `typescript.md` (`*.ts`, `*.tsx`) — props types, no `any`, `type` over `interface` - `tailwind.md` (`*.tsx`, `*.css`) — Tailwind-only styling, no inline styles, `cn()` - `icons.md` (`*.tsx`) — `@tabler/icons-react` only, sizing and stroke conventions - `animations.md` (`*.tsx`, `*.css`) — `tw-animate-css` utilities, no custom keyframes - `bun.md` — Bun instead of Node/npm/vite, Bun-native APIs - `pull-requests.md` (before creating or updating a PR) — description format, length budget, update-on-pivot - `README.md` — format for writing new rules - `.agents/skills/` — skills in the `SKILL.md` [Agent Skills](https://agentskills.io) format (canonical). Codex and other tools that follow the standard discover this directory natively; Claude Code loads them via per-skill symlinks in `.claude/skills/`. When adding a skill, put it in `.agents/skills/<name>/` and add a matching symlink in `.claude/skills/`. Claude-only config (`.claude/settings.json` hooks, `.claude/launch.json`) stays in `.claude/`. ## File naming and references - Use kebab-case for repo-owned files and folders, including components, hooks, utilities, and tests: `chat-panel.tsx`, `use-chat.ts`, `chat-panel.test.tsx`. Keep suffixes such as `.test.ts`, `.server.ts`, and `.d.ts`. - Keep React components and types in PascalCase (`ChatPanel`, `ChatPanelProps`), and functions, hooks, and variables in camelCase (`useChat`). Filename casing does not change exported identifiers. - Preserve established instruction/document names (`AGENTS.md`, `README.md`, `SKILL.md`, `DESIGN.md`, `TESTING.md`, `NOTES.md`, `LICENSE`), bundled skill reference names, established fixture folders such as `__fixtures__`, and vendored files. These are explicit exceptions. - When moving, renaming, or deleting files, update imports, lazy imports, test mocks, scripts, comments, and documentation references in the same change. Search for both the old full path and filename, including hidden agent instructions and skills. Historical notes may retain old paths when clearly marked as historical and paired with current guidance. - Use relative Markdown links for local documentation and source references. Check that their targets and heading fragments still exist after a move or deletion. Use full URLs for external documentation. - Run `bun run check:repo` after file changes. It checks naming and local Markdown links, images, and heading fragments, including hidden skills. It does not check external URLs or paths written as plain text/code; review those with `rg` too. Run typecheck and relevant tests for source renames. ## Data flow - Each workspace added/imported to Moi stores its settings in a `.moi/.workspace.json` file in the workspace folder (hidden filename; `server/workspaces/layout.ts` is its sole reader/writer). - Workspace source and shared configuration under `.moi/` can be committed. `.build/` (bundler output) and `.cache/` (derived artifacts such as applet thumbnails, see `server/applets/thumbnails.ts`) are re-creatable and safe to delete or gitignore. `.scratchpad/` holds the image/video bytes referenced by `.scratchpad.json`; preserve both when sharing or backing up a canvas. Those assets cannot be recreated from the snapshot alone. - Prefer `.moi/.workspace.json` for state that describes the workspace itself rather than the person or device using it — e.g. chat/thread settings, widget layout, connectors. Litmus test: anyone who clones the workspace should get the same value. - Store per-user app state that should follow the local Moi installation in the server-side `DATA_DIR`. Expose it through the API and use React Query for client caching and optimistic updates. - Store per-browser or per-device UI preferences in `client/store/ui.ts`. - Decide ownership before adding persistence. Selected sessions and other user-specific choices do not belong in `.moi/`. ## Main app design `DESIGN.md` is the canonical design guidance for the main app frontend. Before editing host app UI in `client/` (`*.tsx` or `*.css`), read `DESIGN.md` together with `client/AGENTS.md` and the relevant `.agents/rules/` files. It applies to the app shell, chat, settings, menus, workspace list, tabs, panels, and host widget/view chrome. It does **not** govern workspace widget/view internals or generated applets; use workspace-local design guidance for those. ## Tests Read [TESTING.md](TESTING.md) when deciding what test coverage a change needs. ## Commands - `bun run dev` — Start the dev server on port 13337 (alias for `bun server/cli.ts start --dev`). ### Dev mode Use the Bun version in `package.json`'s `packageManager` field or newer. `bun run dev` starts a small supervisor that runs the server **without `bun --hot`**: - **Frontend (`client/`)** — changes refresh components or reload the page automatically. No server restart needed. - **Server (`server/`, `lib/`)** — the supervisor watches these and does a **full process restart** on change (graceful `SIGTERM` → close servers, kill function workers, respawn). Module state is rebuilt cleanly each time. Do **not** use `bun --hot server/web.ts`; it can leave the browser serving stale frontend bundles. `moi start --dev` uses the same supervisor as `bun run dev`. Only one server runs at a time — it binds port 13337 (HTTP) and 13059 (control). To restart, kill the existing `bun run dev` process and start it again; a second instance fails on the control port. ### Running `moi` globally (three ways) - **Dev link**: `bun link` in the repo → `moi` runs current source. Keep `dist/` deleted — if `dist/index.html` exists the server silently serves that stale prebuilt client (`server/static.ts`); only `bun run dev` ignores it (`MOI_DEV`). - **Prod test before publish**: `bun pm pack` (prepack builds the client) → `bun install -g ./moi-computer-<version>.tgz`. Tests the real artifact: `files` whitelist, prebuilt `dist/`, production React, global install tree. - **Published**: `bun install -g moi-computer@latest`. All three overwrite `~/.bun/bin/moi` — last action wins; `readlink ~/.bun/bin/moi` shows which. Kill the running server before switching (single port 13337). ## Browser testing in Codex desktop When the Browser plugin is available, use it first for local UI testing. Reuse the current in-app browser tab when it already shows the target app. Use the vendored `agent-browser` skill only when the Browser plugin is unavailable or when running in Claude Code on the web. ## Browser testing in cloud sandboxes To drive the app in a browser inside Claude Code on the web, use the vendored **agent-browser skill** (`.agents/skills/agent-browser/`). Cloud-specific setup — server startup, `AGENT_BROWSER_EXECUTABLE_PATH`, Playwright alternative, egress-relay caveats — is in `docs/browser-testing-cloud.md`. For OpenClaw protocol details and replay-test conventions, see `server/harness/openclaw/NOTES.md`. The old sandbox setup guide is no longer included; verify the installed OpenClaw runtime and gateway configuration before attempting a live test. ## Session Storage Notes Claude Code stores sessions as `.jsonl` files under: - **macOS/Linux**: `~/.claude/projects/<encoded-path>/` - **Windows**: `%USERPROFILE%\.claude\projects\<encoded-path>\` Path encoding: each `/` (or `\` on Windows) in the working directory path is replaced with `-`. Example: `/Users/foo/my-project` → `-Users-foo-my-project` Potential use: auto-discover workspaces by listing `~/.claude/projects/` and decoding folder names back to paths.