

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
1# CLAUDE.md23Guidance for Claude Code (claude.ai/code) when working in this repository.45## Critical Rules (read first)67### Keep Commit Messages and CHANGELOG Entries Short89**One-sentence commit subject. One-sentence CHANGELOG bullet.** Commit bodies may include short bullets for distinct key changes — one line each, no prose paragraphs, no root-cause explanations unless the diff truly can't explain itself. Match the existing voice in `[Unreleased]` and recent `git log --oneline`. If your draft is longer than the surrounding entries, cut it before submitting.1011**One feature = one CHANGELOG bullet, no matter how many commits built it.** A multi-commit feature (e.g. a whole panel landed over a dozen PRs) gets a single user-facing line, not one bullet per commit. Do NOT append a new bullet for every follow-up commit to the same feature — edit the existing bullet instead. The `[Unreleased]` section must read like a short release summary, not a commit log.1213**Never put internal scaffolding in the CHANGELOG.** No table/column names, IPC channel names, service/store class names, env-var plumbing, migration registration, poll intervals, or "internal scaffolding for the upcoming X" bullets. The changelog answers "what can I now do / what's fixed" for a user — if a line names a symbol or a file, it's wrong. Internal-only changes (typecheck, tests, refactors, doc/agent tweaks, lint, dep bumps with no behavior change) get NO entry.1415**At release time, condense — don't ship the dev-time bullets verbatim.** `[Unreleased]` accumulates verbose per-commit bullets during development. Before tagging, collapse them: merge a feature's scattered bullets into one line, drop scaffolding, squash near-duplicates. If the release notes are longer than the equivalent section in a recent shipped version, cut harder.1617### Write and Run Tests for Behavioral Changes1819**Any change to runtime behavior ships with a unit test** — a new test, or an extension of an existing one. Pure refactors already covered by tests, formatting, docs, and config-only changes are exempt. Before pushing, run the gate locally: `npm run typecheck && npm run test:prepush`. The repo's pre-push hook runs this automatically; it installs on `npm install` (or `npm run hooks:install`). Never push to `main` with a red suite — CI on `main` is a backstop, not the gate. For high-risk areas (sync/collab, main-process init, IPC, restart-to-verify bugs) the test comes **first** and must fail before the fix — see [end-to-end-verification.md](./.claude/rules/end-to-end-verification.md).2021**A test's job is to catch a regression a reader cannot see.** The test corpus is ~2M tokens, and every future session pays to read the tests next to the code it touches. A test that only re-states what is obvious on screen is pure cost. Write fewer, denser tests:2223- **No presentation-only tests** — icon names, exact title strings, tab ordering, hardcoded element counts. If a human would notice the breakage in one second of looking at the screen, it does not need a unit test. Purely visual changes (label, spacing, color) need no test at all.24- **Never assert on component source text** via `readFileSync` + `toContain`/`toMatch`. Render it or don't test it. Genuine architectural invariants belong in a `scripts/` gate, not the vitest suite.25- **Never assert CSS through jsdom by injecting the CSS you are about to assert on** — that is circular. Assert the `className`, or cover it in E2E where real styles load.26- **Mock the narrowest module, never the `@nimbalyst/runtime` barrel.** Importing that barrel costs ~2.6s of module-import CPU per test file because it drags in the whole Lexical editor tree. `vi.mock('@nimbalyst/runtime/ui/icons/MaterialSymbol', …)` is cheap; `vi.mock('@nimbalyst/runtime', async (importOriginal) => ({ ...await importOriginal(), … }))` is the expensive shape — the spread forces the real barrel to load. Import from the deep path in source too, so the barrel never enters the graph. See NIM-2374.27- **A `vi.mock()` whose specifier the module under test no longer imports is a silent no-op.** Moving a source import (barrel → deep path, or any rename) without repointing every mock of it lets the *real* module load, and the failure surfaces far from the edit — six `MetaAgentService` test files kept `vi.mock('@nimbalyst/runtime', …)` after the service moved to deep repository paths, and 22 tests died on `Session store adapter has not been provided`. When you change an import specifier in source, grep the test tree for the old specifier in the same commit.28- **Prefer extending an existing test file** over creating a new one — but do not merge unrelated tests into a mega-file. Small and focused is correct; total volume is the enemy, not file count.29- **Add `// @vitest-environment node` as the first line of any test that never touches the DOM.** The jsdom environment costs ~270ms per file for nothing.30- **Don't write `expect(getBy*(...)).toBeTruthy()`** — `getBy*` already throws.3132### Use @floating-ui/react for All Popover/Tooltip/Menu Positioning3334See [floating-ui.md](./.claude/rules/floating-ui.md). Never manually calculate `position: fixed` coordinates — always use `@floating-ui/react` with `FloatingPortal`.3536### No Dynamic Imports in Electron Main Process3738**NEVER convert static imports to dynamic `await import()`** unless absolutely necessary (confirmed circular reference) AND the user has approved it. Dynamic imports cause `__ELECTRON_LOG__` double-registration crashes and side-effect timing issues. All MCP servers and services in `index.ts` use static top-level imports. The only allowed exception is `bootstrap.ts` importing `index.ts` (see [MAIN_PROCESS_INIT.md](./packages/electron/MAIN_PROCESS_INIT.md)).3940### CollabV3 Data Isolation — DOs for Customer Data, D1 for Entity Management Only4142**Never store customer, org, or team-sensitive data in the D1 shared database.** Customer data (team metadata, member roles, key envelopes, tracker items, documents, sessions) must live in Durable Objects where each entity gets its own isolated SQLite instance. D1 is only for cross-entity management lookups (e.g., git remote hash → org ID mapping). See `packages/collabv3/CLAUDE.md` for the full policy.4344### Never Use Environment Variables as Implicit API Key Sources4546**NEVER read API keys from `process.env` as a fallback for provider authentication.** API keys must come only from values the user explicitly configured in Nimbalyst settings (the electron-store `apiKeys` object or project-level overrides).4748Past incident: a user had `ANTHROPIC_API_KEY` in a `.env` file for unrelated work. Nimbalyst silently picked it up via `process.env`, auto-persisted it, and billed the user's personal Anthropic account $100+ instead of their Nimbalyst subscription.4950- No env fallbacks in `getApiKeyForProvider` — only `globalApiKeys[provider]` or project-level overrides51- No auto-import into the settings store52- Provider availability checks must only consider explicitly-stored keys5354If you are tempted to add `|| process.env.SOME_API_KEY` as a convenience fallback, **stop**.5556### Personal JWT vs Team JWT — Never Interchange Them5758Stytch B2B gives a user a **different member id per org**. The **personal JWT** (`getPersonalSessionJwt()` / `personalUserId`) is for **personal sync ONLY** (the personal index room + session/prompt/draft/settings sync to the **mobile app**). The **team JWT** (`getSessionJwt()` / `getOrgScopedJwt(orgId)`) authorizes **ALL team collaboration** (tracker rooms, schema sync, document rooms, team room, project-access gate). Conflating them is this codebase's most-repeated sync bug.5960Use the branded types in `packages/runtime/src/auth/jwtScopes.ts` so a mix-up is a compile error. When "a second client can't see shared data", first check it's actually authenticated (an expired session is silently logged out → no team JWT).6162### Database Access Rules6364**Nimbalyst currently supports BOTH PGLite and better-sqlite3.** The migration is in progress; both backends are active in the codebase and the user's machine may be running either. Never write code that assumes one backend. Anywhere you touch the database — schema, queries, JSON handling, write paths — read [packages/electron/DATABASE.md](./packages/electron/DATABASE.md) for the divergent behaviors first.6566The biggest gotcha: **JSONB sub-extraction (`data->'someKey'`) returns a parsed object on PGLite but a JSON string on SQLite.** Either select the whole `data` column and parse it, or defensively parse the sub-extracted value with the standard `typeof x === 'string' ? JSON.parse(x) : x` idiom. A real bug from this divergence corrupted tracker `labelsMap` rows on 2026-06-02 because `applyRemoteItem` trusted the sub-extraction was already an object.6768**NEVER directly open or query the database files using Node.js or command-line tools.** PGLite at `~/Library/Application Support/@nimbalyst/electron/pglite-db` uses PID-based locking; better-sqlite3 takes its own exclusive lock. In both cases, opening from a second process risks corruption.6970**ALWAYS use the MCP database query tool instead:**71- Use `mcp__nimbalyst-extension-dev__database_query` for all database queries72- NEVER use `node -e "const { PGlite } = require(...)"` or sqlite CLI7374**For sync/collab bugs, local PGLite ≠ server collab state.** `tracker_body_cache`, `documents`, and other sync-related tables only reflect the local side. The authoritative state for shared trackers/documents lives in Cloudflare Workers (`packages/collabv3/` DurableObjects) and must be inspected separately via `wrangler tail` against the prod sync worker, or via wrangler-backed E2E tests (`tracker-content-collab.spec.ts` / `tracker-sync-collab.spec.ts` patterns, `RUN_COLLAB_TESTS=1`, `document-sync:open-test` IPC for Stytch bypass). Confirming "the body is in PGLite" is not the same as confirming "the body is on the server." See `feedback_local_state_vs_server_state.md`.7576### Always Run Your Own Observation Commands — Don't Push Logs/Curl/Tail to the User7778**Never ask the user to run `curl`, `wrangler tail`, `tail -f`, `gh` commands, or paste logs.** The agent has direct tool access to all of these.7980- Logs: `mcp__nimbalyst-extension-dev__get_main_process_logs` and `get_renderer_debug_logs`81- Database: `mcp__nimbalyst-extension-dev__database_query`82- HTTP: `Bash` with `curl` — the agent runs it83- Cloudflare workers: `Bash` with `wrangler tail` — the agent runs it (long-running tails can use `run_in_background`)84- GitHub: `Bash` with `gh`85- Runtime DOM / renderer state: `mcp__nimbalyst-extension-dev__renderer_eval`8687Past incident: session `702519e3` spent 23 turns debugging a Stytch JWKS rotation because the agent kept handing back commands for the user to run. The user finally said "run tail yourself!" and "you curl it!". If you catch yourself drafting "could you run X and paste the output?", stop and run X.8889Detailed patterns: [DEBUGGING_LOGS.md](./docs/DEBUGGING_LOGS.md).9091### End-to-End Verification Before Declaring Victory9293For any bug whose verification requires a `/restart` or a user manually exercising a UI flow, the **first** deliverable is a failing test that the fix must make pass. Never announce "fixed" before observing the bug go from broken to working — either via a test that flips red→green, or via logs showing the failing step now succeeding. See [end-to-end-verification.md](./.claude/rules/end-to-end-verification.md).9495Past incident: the 2026-05-20 tracker-body workstream announced "fixed" at least four times before the user finally said "you're killing me." Each announcement was based on "the code path looks right" or "tests pass," neither of which is the same as "the user can open the tracker and see the body."9697## Codebase Overview9899Nimbalyst is an extensible, AI-native workspace that supports multiple editor types through a unified extension system. While it originated as a Lexical-based markdown editor, the architecture is evolving toward a fully pluggable model where **all editors** — Lexical, Monaco, spreadsheets, diagrams, custom visual editors — are provided through extensions.100101This monorepo contains the Electron desktop app, runtime services (including the Lexical editor), extension SDK, native iOS app, and mobile support via Capacitor.102103## Extension Architecture104105See [EXTENSION_ARCHITECTURE.md](./docs/EXTENSION_ARCHITECTURE.md) for the EditorHost contract, supported editor types (Monaco, Lexical, custom React), the manifest format, and extension development guidelines.106107## Monorepo Structure108109```110packages/111 electron/ # Desktop app (Electron)112 runtime/ # Cross-platform runtime services (AI, sync, Lexical editor)113 ios/ # Native iOS app (SwiftUI)114 core/ # Shared utilities115 collabv3/ # Collaboration server (Cloudflare Workers)116 extension-sdk/ # Extension development kit117 extensions/ # Built-in extensions118```119120- **Install**: `npm install` at repository root121- **npm workspaces** (not pnpm); packages reference each other via workspace protocol122- **Preserve `peer: true` flags in package-lock.json** — Some `npm install` configurations strip these flags, breaking CI for optional native dependencies (e.g., esbuild platform binaries). Investigate before committing if you see them disappearing.123124Package-specific docs: `/packages/electron/CLAUDE.md`, `/packages/runtime/CLAUDE.md`, `/packages/ios/CLAUDE.md`, `/packages/collabv3/CLAUDE.md`.125126## Development Commands127128**Electron app:**129- Start dev: `cd packages/electron && npm run dev` (user runs this — don't do it yourself)130- Build for Mac: `npm run build:mac:local` or `npm run build:mac:notarized`131- Main process log: `~/Library/Application Support/@nimbalyst/electron/logs/main.log`132133**Testing:**134- Unit: `npm run test:unit` (vitest), or `npm run test:unit:ui`135- E2E: see [E2E_TESTING.md](./docs/E2E_TESTING.md)136137**Marketing screenshots & videos:** See [MARKETING_SCREENSHOTS.md](./docs/MARKETING_SCREENSHOTS.md). Quick: `cd packages/electron && npm run marketing:screenshots` (requires dev server on port 5273).138139**Multiple dev instances** (for collab/sync testing): `cd packages/electron && npm run dev:user2` uses an isolated `NIMBALYST_USER_DATA_DIR`, `VITE_PORT=5274`, and `--outDir=out2` to prevent file-watcher cross-talk. Worktrees auto-derive a per-worktree userData dir via `crystal-run.sh`.140141**Other packages:** iOS — `npm run ios:test:swift`, `npm run ios:build:transcript`. Collab server — `npm run collabv2:dev`, `npm run collabv2:deploy`.142143## Releases144145See [RELEASING.md](./RELEASING.md). Use `/release-alpha [patch|minor|major]`. All release notes go in the `[Unreleased]` section of `CHANGELOG.md`; the script creates versioned entries and annotated git tags.146147## Cross-Cutting Patterns148149- **Error handling** — fail fast, validate at boundaries, workspace-scoped IPC takes `workspacePath` explicitly. See [ERROR_HANDLING.md](./docs/ERROR_HANDLING.md).150- **Naming conventions** — `camelCase` for wire protocol/JSON; `snake_case` only for SQL columns. See [NAMING_CONVENTIONS.md](./docs/NAMING_CONVENTIONS.md).151- **React DOM markers** — Tailwind utilities don't replace semantic class names. Every meaningful component needs a stable kebab-case class on its root. See [REACT_DOM_MARKERS.md](./docs/REACT_DOM_MARKERS.md).152153## Data Persistence154155The app uses **PGLite** (PostgreSQL in WebAssembly) for all data storage.156157- **Never use `localStorage` in the renderer.** Use app-settings store (global), workspace-settings store (per-project), or PGLite (complex data like AI sessions/document history).158- **All database timestamps must use `TIMESTAMPTZ`.** Never create `TIMESTAMP` (without timezone) columns; migrate legacy tables.159160See [DATABASE.md](./packages/electron/DATABASE.md) for tables, locations, shutdown rules, and timestamp handling.161162## Transcript Storage163164Two-tier architecture — `ai_agent_messages` (raw append-only log, sole source of truth) → `ai_transcript_events` (canonical, provider-agnostic, derived). The `TranscriptTransformer` is the single writer of canonical events; providers only write raw. See [TRANSCRIPT_ARCHITECTURE.md](./docs/TRANSCRIPT_ARCHITECTURE.md).165166## Documentation Reference167168**Read the relevant doc in its entirety before making changes in that area.** These contain authoritative patterns, anti-patterns, and architectural decisions.169170| File | Read when… |171| --- | --- |172| [EXTENSION_ARCHITECTURE.md](./docs/EXTENSION_ARCHITECTURE.md) | Working on extensions, creating editors, modifying editor↔host communication, adding new editor types. |173| [IPC_LISTENERS.md](./docs/IPC_LISTENERS.md) | Adding IPC events, debugging stale closures / race conditions in event handling, or seeing `MaxListenersExceededWarning`. |174| [IPC_GUIDE.md](./docs/IPC_GUIDE.md) | Writing main-process IPC handlers, adding `electronAPI` methods, or debugging main↔renderer IPC. |175| [EDITOR_STATE.md](./docs/EDITOR_STATE.md) | Working on editor components or TabEditor infrastructure; debugging editor state. |176| [JOTAI.md](./docs/JOTAI.md) | Working with Jotai atoms, debugging UI/state divergence, or adding new atoms. |177| [STATE_PERSISTENCE.md](./docs/STATE_PERSISTENCE.md) | Adding fields to any persisted state, or debugging "Cannot read properties of undefined" on app load. |178| [UI_PATTERNS.md](./docs/UI_PATTERNS.md) | Writing UI components, styling with CSS/Tailwind, or adding responsive behavior. |179| [ERROR_HANDLING.md](./docs/ERROR_HANDLING.md) | Writing IPC handlers or service methods that take required parameters or handle workspace state. |180| [NAMING_CONVENTIONS.md](./docs/NAMING_CONVENTIONS.md) | Designing wire protocols, sync code, or SQL schemas. |181| [AI_PROVIDER_TYPES.md](./docs/AI_PROVIDER_TYPES.md) | Working on AI integration, adding providers, or modifying model selection. |182| [TRANSCRIPT_ARCHITECTURE.md](./docs/TRANSCRIPT_ARCHITECTURE.md) | Working on transcript rendering, parsers, the canonical event pipeline, or mobile transcript sync. |183| [CONTEXT_WINDOW_USAGE_TRACKING.md](./docs/CONTEXT_WINDOW_USAGE_TRACKING.md) | Working on context-usage display, token tracking, or `ClaudeCodeProvider` streaming. |184| [INTERNAL_MCP_SERVERS.md](./docs/INTERNAL_MCP_SERVERS.md) | Adding MCP server functionality or new tools for AI agents. |185| [CUSTOM_TOOL_WIDGETS.md](./docs/CUSTOM_TOOL_WIDGETS.md) | Creating visual displays for MCP tool results or customizing tool rendering. |186| [INTERACTIVE_PROMPTS.md](./docs/INTERACTIVE_PROMPTS.md) | Working on durable prompts (AskUserQuestion, ExitPlanMode, GitCommitProposal, ToolPermission). |187| [WORKTREES.md](./docs/WORKTREES.md) | Working on worktree features, session isolation, or session↔worktree linkage. |188| [SESSION_HIERARCHY.md](./docs/SESSION_HIERARCHY.md) | Creating/parenting sessions or debugging session grouping in the left pane. |189| [HELP_WALKTHROUGHS.md](./docs/HELP_WALKTHROUGHS.md) | Adding help tooltips, creating walkthroughs, or modifying help content. |190| [REACT_DOM_MARKERS.md](./docs/REACT_DOM_MARKERS.md) | Working on React UI, adding components, or improving testability/devtools navigation. |191| [WALKTHROUGHS.md](./docs/WALKTHROUGHS.md) | Creating multi-step walkthroughs or debugging walkthrough flow. |192| [E2E_TESTING.md](./docs/E2E_TESTING.md) | Writing/debugging E2E tests, or running them as an AI agent (especially in worktrees). |193| [DIALOGS.md](./docs/DIALOGS.md) | Adding or modifying modal dialogs. |194| [AGENT_PERMISSIONS.md](./docs/AGENT_PERMISSIONS.md) | Working on agent permissions, approval flows, or runtime permission checks. |195| [ANALYTICS_GUIDE.md](./docs/ANALYTICS_GUIDE.md) | Adding/modifying PostHog events, or using PostHog MCP tools. |196| [POSTHOG_EVENTS.md](./docs/POSTHOG_EVENTS.md) | Adding, modifying, or removing any PostHog analytics event — keep this in sync. |197| [POSTHOG_MCP_INTEGRATION.md](./docs/POSTHOG_MCP_INTEGRATION.md) | Using PostHog MCP tools or extending PostHog functionality. |198| [THEMING.md](./packages/electron/THEMING.md) | Working on themes or color schemes. |199| [RELEASING.md](./RELEASING.md) | Preparing a release or debugging release scripts. |200| [MARKETING_SCREENSHOTS.md](./docs/MARKETING_SCREENSHOTS.md) | Adding marketing screenshots/videos or modifying capture choreography. |201| [ANDROID_MARKETING_SCREENSHOTS.md](./docs/ANDROID_MARKETING_SCREENSHOTS.md) | Capturing Play Store screenshots or the reviewer screencast for the Android app. |202| [FILE_WATCHING_AND_CHANGE_TRACKING.md](./docs/FILE_WATCHING_AND_CHANGE_TRACKING.md) | Working on file watchers, AI change detection, diff display, or the FilesEditedSidebar. |203| [WEEKLY_DASHBOARD.md](./docs/WEEKLY_DASHBOARD.md) | Adding/modifying insights on the Weeklys PostHog dashboard. |204| [VOICE_MODE.md](./docs/VOICE_MODE.md) | Working on voice mode, voice-agent prompts, audio pipeline, or session lifecycle. |205| [TRACKER_WORKFLOWS.md](./docs/TRACKER_WORKFLOWS.md) | Creating decision or bug tracker items as part of a fix or design decision. |206| [ARCHITECTURE_DIAGRAMS.md](./docs/ARCHITECTURE_DIAGRAMS.md) | Considering whether a change is complex enough to warrant an Excalidraw diagram. |207| [DEBUGGING_LOGS.md](./docs/DEBUGGING_LOGS.md) | Investigating bugs — use the log access tools, don't ask the user to paste logs. |208| [RENDER_PERFORMANCE.md](./docs/RENDER_PERFORMANCE.md) | Chasing excessive React re-renders, or adding a render-budget test to a hot surface. |209| [MAIN_PROCESS_INIT.md](./packages/electron/MAIN_PROCESS_INIT.md) | Working on Electron main-process bootstrap, singleton init, or IPC handler registration. |210| [DATABASE.md](./packages/electron/DATABASE.md) | Working with PGLite tables, shutdown, or timestamp handling. |211212## AI Features (quick reference)213214- **AI Chat Panel**: multi-provider (Claude, OpenAI, LM Studio, Claude Code), document-aware; Cmd+Shift+A215- **Session Manager**: global view (Cmd+Alt+S); search, export, delete216- **Model Configuration**: dynamic from provider APIs; no hardcoded models217- **Git Worktrees**: isolated AI coding sessions via "New Worktree" button218219## Tracker Workflows220221Tracker sharing model: **a tracker is personal or it is the team's; if it is the team's, the server owns it — schema and items together — and `.nimbalyst/trackers/*.yaml` is the local copy.** Read [TRACKER_SCHEMA_SHARING.md](./docs/TRACKER_SCHEMA_SHARING.md) before changing a tracker schema or sharing and numbering behavior.222223When choosing between alternatives (libraries, patterns, deciding NOT to do something), log a **decision** tracker item. When fixing a bug, ensure a **bug** tracker item exists before writing fix code. See [TRACKER_WORKFLOWS.md](./docs/TRACKER_WORKFLOWS.md) for the exact `tracker_create` calls and lifecycle.224225### `NIM-###` Keys Are Tracker-Scoped — Cite GitHub Issues in Source226227**`NIM-###` issue keys are scoped to the tracker room for a Nimbalyst workspace or team project. They do not resolve anywhere else** — peer installs in the same room share an identity, but the same key can point at a different item in an unrelated workspace. In a public repo they are worse than no reference: a reader who looks one up can land on an unrelated item and believe it is authoritative.228229- **Code comments and runtime log strings** reference the GitHub issue: `// #1146: typed workstream containers are always roots`. If there is no GitHub issue, write the reason in prose instead of citing a key.230- **Commit messages** keep `Fixes NIM-123` — that trailer is what `CommitTrackerLinker` uses to auto-close the item, and it never ships inside the product. Add `Fixes #123` alongside it when a GitHub issue also exists.231- **Existing `NIM-###` references in source stay put.** This applies to new code; there is no retro sweep.232233A contributed PR carrying a `NIM-###` reference is always wrong — it came from *their* tracker. Strip it or map it to the GitHub issue before merging.234235## Architecture Diagrams for Decisions236237**Default: no diagram.** Only when a change rearranges how three or more components relate — and the topology is genuinely non-obvious from prose — create an Excalidraw diagram in `nimbalyst-local/architecture/` and share the file link. Never diagram linear sequences, phased rollouts, single components, bug fixes, or a restatement of your own section headings. See [ARCHITECTURE_DIAGRAMS.md](./docs/ARCHITECTURE_DIAGRAMS.md) for the full bar.238239## Verifying Development Mode240241Before making code changes, use `mcp__nimbalyst-extension-dev__get_environment_info` to verify Nimbalyst is running in dev mode. If the user is running a packaged build, code changes won't take effect — tell them to start the dev server.242243## Debugging with Log Access Tools244245See the Critical Rules block above ("Always Run Your Own Observation Commands"). Detailed patterns: [DEBUGGING_LOGS.md](./docs/DEBUGGING_LOGS.md).246247## General Development Guidelines248249- **Never use emojis** — not in commits, code, or documentation, unless explicitly requested250- **Never use overly enthusiastic phrases** ("Perfect!", "Terrific!", etc.)251- **Never commit changes unless explicitly asked**252- **Never commit files under `nimbalyst-local/`** — gitignored, local-only working files253- **Never provide time or effort estimates**254- **Don't disable tests without asking first**255- **Don't run `npm run dev` yourself** — user does that256- **Never release without being explicitly instructed**257- **Don't `git reset` or `git add -A` without asking**258- **Don't add `Co-Authored-By` lines to commit messages**259- **Never restart Nimbalyst without explicit permission** — always ask before `restart_nimbalyst`260- **Never mark work done before the user approves it — but a commit IS their approval.** Until the work is committed, set tracker items to `in-review` and session phase to `validating`, never `done` / `complete`. Once the user commits the work, they have reviewed it and agreed it's finished: put a closing reference (`Fixes NIM-123`) in the commit message and the item closes itself; also set session phase to `complete`. Do not leave finished, committed work parked in `in-review`. `approved` on the review lane remains human-only.261262**Keyboard Shortcuts**: when adding or modifying shortcuts, update `KeyboardShortcutsDialog.tsx`.263264## Support265266User support docs live in `support/`. Notable: `force-restore-database-backup.md` for manual database restore.267if i ask you to propose a commit, first update the `CHANGELOG.md` (at the repo root) and include it in the commit proposal268if a commit is intended to fix a github issue, include the issue number and a closing reference in the commit message when appropriate (fixes #123 or closes #123)269
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.5k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 14 days ago | |
| nimbalyst/nimbalystpackages/electron/CLAUDE.md · 1.5k | CLAUDE.md | buildtestgitapi+2 | 83/100 | 14 days ago | |
| nimbalyst/nimbalystpackages/ios/CLAUDE.md · 1.5k | CLAUDE.md | setupbuildtestarch+3 | 82/100 | 14 days ago | |
| nimbalyst/nimbalystpackages/runtime/CLAUDE.md · 1.5k | CLAUDE.md | agent-behaviour | 44/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| bagisto/bagistoCLAUDE.md · 28k | CLAUDE.md | setupbuildteststyle+5 | 100/100 | 7 days ago | |
| Adit-Jain-srm/NightmareNetCLAUDE.md · 46 | CLAUDE.md | buildtestlint-formatstyle+6 | 100/100 | 14 days ago | |
| tyrchen/geektime-bootcamp-aiw7/genslides/backend/CLAUDE.md · 230 | CLAUDE.md | testlint-formatstylearch+6 | 100/100 | 9 days ago | |
| nimbalyst/nimbalystpackages/android/CLAUDE.md · 1.5k | CLAUDE.md | setupbuildstylearch+2 | 100/100 | 14 days ago | |
| dotCMS/corecore-web/CLAUDE.md · 949 | CLAUDE.md | teststylearchtesting-strategy+3 | 100/100 | 14 days ago | |
| microsoft/playwrightCLAUDE.md · 95k | CLAUDE.md | buildtestlint-formatstyle+7 | 100/100 | 7 days ago | |
| tphakala/birdnet-goCLAUDE.md · 1.6k | CLAUDE.md | buildtestlint-formatstyle+8 | 100/100 | today | |
| dotCMS/coreCLAUDE.md · 949 | CLAUDE.md | setupbuildteststyle+7 | 99/100 | today |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/nimbalyst-nimbalyst-claude)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.