docs: add CLAUDE.md for Claude Code guidance#172
Conversation
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new root-level CLAUDE.md intended to give Claude Code instances quick, high-signal guidance for working effectively in this Yarn 4 workspaces monorepo (commands, architecture/dependency rules, testing workflow, and OpenSpec conventions).
Changes:
- Introduces
CLAUDE.mdwith repo-specific commands and per-package workflows (including OT server Docker notes). - Summarizes the layered package architecture and dependency direction expectations.
- Documents testing conventions (co-located Jest specs, should-notation) and spec-driven development workflow (OpenSpec).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| Run from the repo root (fan out across all workspaces via `yarn workspaces foreach`): | ||
|
|
||
| ```bash | ||
| yarn install # install all workspace deps + set up Husky (pre-commit runs `yarn constraints`) | ||
| yarn build # build every package (tsc --build) | ||
| yarn test # run every package's Jest suite | ||
| yarn lint # lint every package (ESLint, eslint-config-codex) | ||
| yarn lint:fix # lint + auto-fix | ||
| ``` | ||
|
|
||
| Per-package (prefer this while iterating — much faster): | ||
|
|
||
| ```bash | ||
| cd packages/model | ||
| yarn test # Jest | ||
| yarn test path/to/File.spec.ts # single file | ||
| yarn test -t "should do X" # single test by name | ||
| yarn test:coverage | ||
| yarn test:mutations # Stryker mutation testing (only some packages, e.g. model, core) | ||
| yarn lint | ||
| yarn dev # tsc --build --watch | ||
| ``` | ||
|
|
||
| Playground (manual end-to-end testing): `cd packages/playground && yarn dev` | ||
|
|
||
| OT server (Docker): create `.env` at repo root with `WSS_PORT=8080`, then `docker compose up`. |
There was a problem hiding this comment.
Duplicates CONTRIBUTING.md's command list and per-package workflow almost verbatim – same commands, same example package. Only the ESM caveat isn't already there.
Anthropic's own CLAUDE.md guidance is to trim what Claude can already derive from repo docs and keep only what's non-obvious; would a pointer to @CONTRIBUTING.md + that caveat work instead of restating the full list?
| Layered packages with a strict dependency direction. Full detail in `docs/architecture.md` — read the relevant `docs/` page before structural changes. | ||
|
|
||
| - **`model-types`** — foundation layer: shared low-level types, nominal brands, base event classes (`Index`, event classes, `EventBus`). No runtime deps. **Only `model` and `sdk` may depend on it directly.** | ||
| - **`sdk`** — the contract layer (interfaces, `EventBus`, `BlockTool`/`InlineTool`). Re-exports everything from `model`/`model-types` that a tool author legitimately needs. **All tools, plugins, and non-engine packages depend on `sdk`, never on `model` or `model-types` directly.** | ||
| - **`model`** — in-memory document model (`EditorJSModel`, `BlockNode`, `TextNode`, inline-fragments, caret management). The engine backing `EditorJSModel`; consumed directly only by `core` and `ot-server`. No DOM concerns. Free to change internals since it isn't the tool-facing surface. | ||
| - **`dom-adapters`** — binds model nodes to DOM inputs (`DOMBlockToolAdapter`, `CaretAdapter`, `FormattingAdapter`). Observes/applies model changes via public APIs + events; depends only on `sdk`. | ||
| - **`collaboration-manager`** — operational transformation, batching, undo/redo, OT WebSocket client. Depends only on `sdk`. | ||
| - **`core`** — the orchestrator and single owner of service wiring: IoC container (`inversify`), plugin/tool lifecycle, `EditorAPI`, local undo/redo (`UndoRedoManager`). Entry point: services wired in constructor, `core.use(...)` registers UI plugins/tools, `initialize()` prepares tools + model + collaboration. | ||
| - **`ui`** — default UI shell (`EditorjsUI`, `BlocksUI`, `Toolbar`, `InlineToolbar`, `Toolbox`); registered as an `EditorjsPlugin` via `core.use()`. `BlocksUI` owns the `contenteditable`, normalizes browser `beforeinput` into `BeforeInputUIEvent` on the global `EventBus`. | ||
| - **`ot-server`** — standalone Node.js WebSocket OT server (`OTServer`, `DocumentManager`), one `DocumentManager` per `documentId`; transforms/applies/broadcasts operations. Server-side only. | ||
| - **`packages/tools/*`** — built-in block/inline tools (`paragraph`, `bold`, `italic`, `inline-link`), each implementing `BlockTool`/`InlineTool` from `@editorjs/sdk`. | ||
|
|
||
| Avoid direct cross-layer coupling: communicate through `sdk` interfaces/events and mutate via `EditorJSModel`'s public API. |
There was a problem hiding this comment.
Same pattern as the Commands block: this restates docs/architecture.md's package table and dependency rules almost line-for-line.
The part that's actually load-bearing every session is the enforcement rule – sdk only, never model/model-types directly – everything else Claude can pull from docs/architecture.md on demand.
Could this trim to a pointer + the one rule?
Summary
Adds a
CLAUDE.mdat the repo root to give Claude Code instances quick, high-signal guidance when working in this monorepo.Content focuses on what's not trivially discoverable:
yarn build/test/lint) and per-package workflow, including running a single test and the--experimental-vm-modulesESM caveat forcore/ot-server.@editorjs/sdkonly;coreis the sole orchestrator).*.spec.ts/*.integration.spec.ts, TDD, should-notation.Points to
docs/architecture.mdandCONTRIBUTING.mdrather than duplicating them.🤖 Generated with Claude Code