You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ddec531
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: CLAUDE.md
+3-28Lines changed: 3 additions & 28 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,9 +6,9 @@ This file (also `AGENTS.md`) holds the repo-wide rules. Area detail lives in `.c
6
6
7
7
-**Package manager**: `bun` and `bunx`, never `npm` and `npx`.
8
8
-**Logging**: `createLogger` from `@sim/logger`; `logger.info` / `logger.warn` / `logger.error`, never `console.log`. Inside `withRouteHandler` the logger already carries the request ID — no manual `withMetadata({ requestId })`.
9
-
-**Comments**: name things so the code explains itself. TSDoc documents exported APIs and non-obvious modules. An inline `//` is only for a terse, non-obvious *why*, or for a script-enforced `// <tag>: <reason>` annotation (`boundary-raw-fetch`, `double-cast-allowed`, `boundary-raw-json`, `untyped-response`, `rq-lint-allow`, `client-boundary-allow`, `utils-lint-allow`, …). A comment never narrates what the next line does, restates a name or type, or records change history ("moved from X", "previously", "now uses Y") — history belongs in the commit message. No `====` separators. The `/you-might-not-need-a-comment` skill applies this to a diff.
9
+
-**Comments**: name things so the code explains itself. TSDoc documents exported APIs and non-obvious modules. An inline `//` is only for a terse, non-obvious *why*, or for a script-enforced `// <tag>: <reason>` annotation (`boundary-raw-fetch`, `double-cast-allowed`, `boundary-raw-json`, `untyped-response`, `rq-lint-allow`, `client-boundary-allow`, `utils-lint-allow`, …). History belongs in the commit message. No `====` separators or commented-out code (`check:comment-hygiene` enforces this). The `/you-might-not-need-a-comment` skill applies this to a diff.
10
10
-**ID generation**: `generateId()` (UUID v4, the default) or `generateShortId(size?)` (URL-safe, 21 chars by default) from `@sim/utils/id` — never `crypto.randomUUID()`, `nanoid`, or `uuid`. Both use `crypto.getRandomValues()`, so they also work in non-secure (HTTP) browsers.
11
-
-**Common utilities**: use the shared helpers from `@sim/utils` instead of inline implementations:
11
+
-**Common utilities**: use the shared helpers from `@sim/utils` instead of inline implementations (`check:utils` flags the inline forms):
12
12
-`sleep(ms)` from `@sim/utils/helpers` — never `new Promise(resolve => setTimeout(resolve, ms))`
13
13
-`toError(e)` from `@sim/utils/errors` — normalize caught values to `Error`; never `e instanceof Error ? e : new Error(String(e))`
14
14
-`getErrorMessage(e, fallback?)` from `@sim/utils/errors` — never `e instanceof Error ? e.message : 'fallback'`
@@ -86,7 +86,7 @@ The `'use client'` server boundary, the app/worker runtime env split, and featur
86
86
-**Imports**: absolute (`@/...`) only, never relative (a barrel `index.ts` re-exports its own siblings relatively). A folder with 3+ exports gets an `index.ts` barrel; never re-export from a non-barrel file. `import type` for type-only imports. Order and lazy-loading through barrels: `.claude/rules/sim-imports.md`.
87
87
-**TypeScript**: no `any` and no non-null `!` (use precise types or `unknown` with guards; `check:explicit-any` ratchets both); no export nothing imports (`check:unused-exports`); a props interface for every component; `as const` for constant objects/arrays; explicit ref types (`useRef<HTMLDivElement>(null)`).
88
88
-**Unused bindings** fail lint (biome `noUnusedVariables`, `noUnusedFunctionParameters`): delete the dead variable, import, or parameter and update callers; write `catch {}` when the error is unused. Prefix `_` only for a parameter that must hold its position because a later one is used. `const { a, ...rest } = obj` to omit keys is allowed. The rules carry no autofix, so `bun run lint` will not rename anything for you.
89
-
-**Components**: `'use client'` only for hooks or browser APIs. Structure order, extraction thresholds, and list-render rules: `.claude/rules/sim-components.md`. Render-performance idioms (lazy-init refs, hoisting, `Map` pre-indexing, `[...arr].sort()` never `toSorted()` on client paths): `.claude/rules/sim-react-performance.md`. For effect/state/memo/callback anti-patterns use the `/you-might-not-need-*` skills and verify against the running UI.
89
+
-**Components**: `'use client'` only for hooks or browser APIs (`check:client-boundary` guards the server boundary). Structure order, extraction thresholds, and list-render rules: `.claude/rules/sim-components.md`. Render-performance idioms (lazy-init refs, hoisting, `Map` pre-indexing, `[...arr].sort()` never `toSorted()` on client paths): `.claude/rules/sim-react-performance.md`. For effect/state/memo/callback anti-patterns use the `/you-might-not-need-*` skills and verify against the running UI.
90
90
-**State ownership**: React Query owns server data — never `useState` + `fetch`; shareable client view-state (tabs, filters, search, pagination, selected id) lives in the URL via `nuqs`; Zustand owns global client state; `useState` owns UI-only state. Hooks: `.claude/rules/sim-hooks.md`. Stores (`devtools`, `persist` only with an explicit `partialize` whitelist, workflow value invariants): `.claude/rules/sim-stores.md`. URL state: `.claude/rules/sim-url-state.md`.
91
91
-**Utils**: inline a helper with one consumer; create `utils.ts` when 2+ files share it — in `lib/` (app-wide) or `feature/utils/` (feature-scoped). Check `lib/` before writing a new one.
92
92
-**Lists and menus** mirror the order the user already reads elsewhere (toolbar, settings nav), encoded in one exported order constant (resource menus share `RESOURCE_MENU_ORDER`, a product order that does not mirror the sidebar); a separator marks only a change in what the action acts on (typically one, before the destructive action): `.claude/rules/sim-list-ordering.md`.
@@ -149,28 +149,3 @@ bun run apps/sim/scripts/check-block-registry.ts origin/staging
149
149
```
150
150
151
151
CI also runs `bun run check:migrations <base>` (it needs a base ref, so it is not in `check:audits`; run it with `origin/staging` when you touch `packages/db/migrations/**`), checks that `drizzle-kit generate` in `packages/db` produces no new migration, and runs a non-blocking `bun audit`. When an audit fails, its output and its script's header say what the rule protects; fix the code, never the check. Ratchet baselines (`scripts/*baseline.json`) only shrink: regenerate one with the update flag its failure output names (`--update` or `--update-baseline`) after removing violations, never to admit new debt. The one exception is `check:tool-registry-boundary`, whose module-count baseline is re-recorded when growth is deliberate (see its skill).
152
-
153
-
| Written rule | Enforced by |
154
-
| --- | --- |
155
-
| Formatting, lint, no `nanoid`/`uuid` imports, no unused variables or parameters |`bun run lint` (biome) |
| Route contracts, no `zod` in routes or clients, `requestJson`, boundary annotations |`check:api-validation:strict`, `check:api-contract-routes`, `check:route-verbs`|
159
-
| Application authorization funnel stays light; principal and capability policy |`check:application-graph`, `check:principal-kind-parity`, `check:capability-subject`, `check:actorless-executor-operations`, `check:permission-group-enforcement`|
160
-
|`'use client'` server boundary |`check:client-boundary`|
| No `any` or non-null `!` (ratcheted), no suppressions of either |`check:explicit-any`|
171
-
| kebab-case file names; no file repeating its folder's name |`check:file-names`|
172
-
| No banner separators or commented-out code |`check:comment-hygiene`|
173
-
| Skills and rules projections in sync; guidance references resolve |`check:skills`, `check:guidance-refs`|
174
-
| Generated artifacts fresh (tool metadata, deployment config, docs, catalog, agent stream docs; CLI/MCP/OpenAPI surfaces) | the five `*:check` entries in `check:audits`; `check:cli-api`, `check:mcp-operations`, `check:openapi`|
175
-
176
-
Rules not in this table (logging, the rest of comment style and naming, imports, styling, state ownership, caching) are enforced by review only; follow them as written.
0 commit comments