RuleStack

Configs

Stacks

Compare

Diff

RuleStack

Configs

Stacks

Compare

Diff

Read API

RuleStack

Configs

Stacks

Compare

Diff

Read API

Diff/cherryhq-cherry-studio-packages-provider-registry-claude ↔ cherryhq-cherry-studio-claude

Comparison

A · CLAUDE.md · CherryHQ/cherry-studioB · CLAUDE.md · CherryHQ/cherry-studio
What each file covers, counted
DimensionSharedOnly in AOnly in BOverlap
Sections05300%
Commands03200%
Section tags40736%

What each file covers

Sections

0 shared · 5 only in A · 30 only in B
  • − provider-registry — module instructions
  • − Cardinal rule — NEVER hand-edit `data/*.json`
  • − Source of truth
  • − Rules when editing source
  • − Verify (required before commit)
  • + Guiding Principles (MUST FOLLOW)
  • + Mindset
  • + Operational Rules
  • + Development
  • + Commands
  • + Testing
  • + Patched Dependencies
  • + GitHub
  • + Pull Requests
  • + Code Review
  • + Issues
  • + Conventions
  • + TypeScript
  • + Naming Conventions
  • + Logging
  • + Paths
  • + i18n
  • + UI Design
  • + Architecture
  • + Code Organization
  • + Data
  • + IPC (IpcApi)
  • + Window Manager
  • + Main Process Services (Lifecycle)
  • + Non-Lifecycle Services (Direct-Import Singleton)
  • + v2 Refactoring (In Progress)
  • + Coexistence Mindset
  • + Data Classification Toolchain
  • + Breaking Changes Log
  • + Local Instructions

Commands

0 shared · 3 only in A · 20 only in B
  • − pnpm --filter @cherrystudio/provider-registry generate
  • − pnpm --filter @cherrystudio/provider-registry test
  • − pnpm generate
  • + pnpm lint
  • + pnpm test
  • + pnpm format
  • + git log
  • + git pull
  • + git pull --rebase
  • + git fetch && git rebase origin/<branch>
  • + git push
  • + git fetch
  • + git commit -S --signoff
  • + git cat-file commit HEAD
  • + pnpm install
  • + pnpm build:check
  • + pnpm i18n:sync
  • + pnpm test:lint
  • + vitest.config.*
  • + gh-create-pr
  • + gh-create-issue
  • + pnpm i18n:check
  • + pnpm db:migrations:generate

Section tags

4 shared · 0 only in A · 7 only in B
  • + setup
  • + lint-format
  • + code-style
  • + types
  • + testing-strategy
  • + dependencies
  • + ui
  •   test
  •   git-pr
  •   do-not
  •   agent-behaviour

Line diff

+216 added−27 removed17 unchanged7.3% identical
CherryHQ/cherry-studio · packages/provider-registry/CLAUDE.md
@@ −1 @@
1# provider-registry — module instructions
2 
3The bundled AI **provider + model catalog**. This package has two faces:
4 
5- **Build-time**: a generation pipeline (`src/creators/` + `src/providers/` + `scripts/generate-catalog.ts`) that emits the three `data/*.json` files.
6- **Runtime**: schemas + `registry-loader.ts` that the app reads those JSON files through.
7 
8Full architecture: [docs/architecture.md](docs/architecture.md). Consumer API: [README.md](README.md).
9 
10## Cardinal rule — NEVER hand-edit `data/*.json`
 
 
 
11 
12`data/models.json`, `data/providers.json`, `data/provider-models.json` are **PURE GENERATED ARTIFACTS**. Editing them by hand is always wrong — the next `pnpm generate` silently reverts your change, and **CI rejects it**: the `catalog-hand-edit-check` job fails any PR that touches `data/*.json` without a matching change under `src/` or `scripts/`.
13 
14To change the catalog, edit the **source** and regenerate:
 
 
 
 
 
15 
16| You want to change… | Edit | Then |
17| --- | --- | --- |
18| a model's metadata (capabilities, modalities, context/limits, name) | `src/creators/<creator>.ts` | `pnpm generate` |
19| how a provider connects / which models it serves / its pricing & overrides | `src/providers/<provider>.ts` | `pnpm generate` |
20 
21`pnpm generate` reads the upstream catalogs (models.dev / OpenRouter text + image models) **live**; set `MODELSDEV_CACHE` / `OPENROUTER_CACHE` / `OPENROUTER_IMAGE_CACHE` to local files to cache them during dev. Always commit the **source change and the regenerated `data/*.json` together** — a data change with no source change reads as a hand-edit and CI blocks it.
 
 
 
 
 
 
22 
23## Source of truth
24 
25- **`src/creators/<creator>.ts`** — model **creators** (anthropic, openai, cohere, alibaba, …). Declares *what models exist* and their *intrinsic metadata*. Built with `defineCreator`. A creator is the home for capabilities/modalities/context — **creator owns metadata**.
26- **`src/providers/<provider>.ts`** — serving **providers** / gateways / clouds (dashscope, ppio, tokenhub, openrouter, aws-bedrock, …). Declares *how to connect* and *which models it serves* with per-provider `apiModelId`, pricing, and overrides. Built with `defineProvider` / `openaiCompatible` — **provider owns parameter support** (endpoints/transport, per-provider param sets).
27- **models.dev + OpenRouter** — read live at generation time to enrich metadata/pricing for the models the registry references (not committed; `pnpm generate` fetches them).
 
 
28 
29## Rules when editing source
 
 
 
30 
31- **Hand-list models with full metadata.** A creator model is `{ id, name, capabilities, … }` — never a bare `{ id }`. Add `name` + the relevant `capabilities` / `contextWindow` / `maxOutputTokens` / modalities; without them the model resolves with no capabilities.
32- **`imageGeneration`: creator carries `supports` (the param vocabulary) as the provider-agnostic DEFAULT; the provider carries `vendorTransport` (endpoint routing).** The runtime **replaces** `imageGeneration` wholesale (it does not deep-merge), so a model-level block must never contain a provider-specific `vendorTransport`, and any provider needing a custom endpoint restates the **full** block (supports + transport). See [docs/architecture.md#image-generation-design-b](docs/architecture.md#image-generation-design-b).
33- **`idPrefixes` must be vendor-specific.** A prefix claims every catalog id matching it, so a generic prefix (`rerank`, `embed`) will mis-attribute other vendors' models. Use the creator's own namespace (`rerank-v`, `command`, `c4ai`, …).
34- **A provider override whose `modelId` is not a base model must carry a standalone `name`** (vendor-exclusive). The catalog-invariants test fails on a dangling override (a `modelId` that is neither in `models.json` nor a named standalone).
35 
36## Verify (required before commit)
37 
38```bash
39pnpm --filter @cherrystudio/provider-registry generate # regenerate data/*.json from source + live upstream
40pnpm --filter @cherrystudio/provider-registry test # vitest: schema conformance + catalog invariants
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41```
42 
43Commit the regenerated `data/*.json` alongside your `src/` change. Generation also re-pulls live upstream, so the data diff may include unrelated metadata/pricing drift since the last run — that's expected. CI enforces sync in **both** directions: the `catalog-hand-edit-check` job rejects a `data/*.json` change with no `src/`/`scripts/` change (a hand-edit), and the `catalog-source-sync` test (in `test:provider-registry`) rejects the reverse — a `src/` change you forgot to regenerate — by re-deriving the source-controlled facts (provider connection config, hand-listed creator models + their `ownedBy`/`name`, provider overrides) and diffing them against the committed JSON. It's deterministic (no upstream fetch), so it only covers source-derived data; upstream-enriched fields (pricing, inferred metadata) and overall correctness still rely on the schema/catalog-invariant tests above and code review.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44 
CherryHQ/cherry-studio · CLAUDE.md
@@ +1 @@
1## Guiding Principles (MUST FOLLOW)
2 
3### Mindset
4 
5How to approach any coding task in this repo.
 
6 
7#### Think Before Coding
8 
9- State assumptions explicitly. If uncertain, ask before implementing.
10- When multiple interpretations exist, surface them — do not pick silently.
11- If a simpler approach exists, say so. Push back when warranted.
12- If something is unclear, stop. Name what is confusing. Ask.
13 
14#### Simplicity First
15 
16- Write the minimum code that solves the problem. Nothing speculative.
17- No features beyond what was asked.
18- No abstractions for single-use code.
19- No "flexibility" or "configurability" that was not requested.
20- No error handling for impossible scenarios.
21- If you wrote 200 lines and it could be 50, rewrite it.
22 
23#### Surgical Changes
 
 
 
24 
25- Touch only what the task requires. Do not "improve" adjacent code, comments, or formatting.
26- Do not refactor things that are not broken.
27- Match existing style even if you would do it differently.
28- If you notice unrelated dead code, mention it — do not delete it.
29- Remove imports / variables / functions that **your** changes orphaned. Leave pre-existing dead code alone unless asked.
30- **v1 residue is a standing exception:** during the v2 refactor you may delete (not just flag) v1 dead code in an area you're already editing — see [v2 Refactoring → Coexistence Mindset](#coexistence-mindset). Unrelated v1 code and *fixing* v1 remain out of scope.
31- Every changed line must trace directly to the user's request.
32 
33#### Goal-Driven Execution
34 
35- Convert tasks into verifiable goals before coding:
36 - "Add validation" → "Write tests for invalid inputs, then make them pass."
37 - "Fix the bug" → "Write a test that reproduces it, then make it pass."
38 - "Refactor X" → "Ensure tests pass before and after."
39- For multi-step tasks, state a brief plan with explicit verification per step:
40 
41```
421. [Step] → verify: [check]
432. [Step] → verify: [check]
44```
45 
46### Operational Rules
 
 
 
47 
48Project-specific tools, paths, and conventions.
49 
50- **Keep it clear**: Write code that is easy to read, maintain, and explain.
51- **Read local READMEs first**: Before editing code in a directory, check for a `README.md` in that directory (and its parents) and read it — these files capture local conventions, invariants, and entry points that aren't obvious from the code alone.
52- **Fix upstream, don't hack downstream**: When a new feature hits an existing module's limitation, flag the upstream improvement for the user's decision before proposing a downstream workaround.
53- **Library-first, custom-last**: Before writing custom code, check library/framework docs for built-in options or existing solutions. Write custom code only when no adequate alternative exists.
54- **Build with Tailwind CSS & Shadcn UI**: Use components from `@cherrystudio/ui` (located in `packages/ui`, Shadcn UI + Tailwind CSS) for every new UI component.
55- **Log centrally**: Route all logging through `loggerService` with the right context—no `console.log`.
56- **Access paths centrally**: Use `application.getPath('namespace.key', filename?)` for all main-process filesystem paths—never call `app.getPath()`, `os.homedir()`, or construct paths ad-hoc. Import the singleton via `import { application } from '@application'`.
57- **Lint, test, and format before completion**: Coding tasks are only complete after running `pnpm lint`, `pnpm test`, and `pnpm format` successfully.
58- **Write conventional commits**: Commit small, focused changes using Conventional Commit messages (e.g., `feat(data-api):`, `fix(lifecycle):`, `refactor(quick-assistant):`, `docs(testing):`, `chore(deps):`, `test(window-manager):`). Scope must be a specific kebab-case module, never generic like `main` — when `git log` conflicts with this rule, this rule wins.
59- **Keep history linear**: On shared branches, never use plain `git pull` — it creates merge commits. Always `git pull --rebase` (or `git fetch && git rebase origin/<branch>`). Before `git push`, run `git fetch`; if `origin/<branch>` has advanced, rebase your local commits onto it first. If you notice a merge commit in local history that hasn't been pushed yet, rebase it away — cleaning one up after it's public requires a risky force-push on a shared branch.
60- **Sign commits and sign off**: Every commit must be both cryptographically signed and DCO-signed off. Use `git commit -S --signoff` (not `--signoff` alone), verify the commit object contains a `gpgsig` header with `git cat-file commit HEAD`, and verify the pushed PR commits show `Verified` on GitHub.
61- **Target the right branch**: `main` is the default branch for active development — submit features, refactors, optimizations, and fixes for the current codebase here. v1 maintenance fixes (hotfixes and subsequent v1 releases) must branch from and target the `v1` branch (never `main`); a v1 fix does not auto-carry to `main`, so forward-port it with a separate PR if the bug also exists on `main`. See [v2 Refactoring](#v2-refactoring-in-progress).
62 
63## Development
64 
65### Commands
66 
67Run `pnpm install` first (Node and pnpm versions are pinned in `package.json` — let it enforce them). For every other script, read `package.json` — the ones you must know:
68 
69- `pnpm lint` — oxlint + eslint fix + typecheck + i18n check + format (writes files)
70- `pnpm test` — run all Vitest tests
71- `pnpm format` — Biome format + lint (write mode)
72- `pnpm build:check` — **REQUIRED before commits**. If it fails on i18n sort, run `pnpm i18n:sync` first; on formatting, run `pnpm format` first; on broken doc links, fix the link.
73- `pnpm test:lint` — the CI-equivalent lint gate: it denies oxlint warnings that `pnpm lint` / `pnpm build:check` silently tolerate; run it when CI must pass.
74 
75### Testing
76 
77- Tests run with Vitest 3 (see `vitest.config.*` for project setup).
78- **Frontend Tests — MUST READ**: [Frontend Testing Guidelines](docs/references/testing/frontend-testing.md).
79- **Test Mocking**: Use the unified mock system — do NOT create ad-hoc mocks for `application`, services, or data layers. See [tests/__mocks__/README.md](tests/__mocks__/README.md) for available mocks, usage patterns, and best practices.
80- **Database Tests**: For any service/handler/seeder that reads or writes SQLite, use `setupTestDatabase()` from `@test-helpers/db` — it provides a real file-backed DB with production migrations. Do NOT hand-write `CREATE TABLE` SQL, override `@application`, or stub Drizzle chains. See [docs/references/testing/database-testing.md](docs/references/testing/database-testing.md).
81 
82### Patched Dependencies
83 
84Before upgrading any dependency, check `patches/` for custom patches.
85 
86## GitHub
87 
88### Pull Requests
89 
90Use the `gh-create-pr` skill. Fallback: read `.agents/skills/gh-create-pr/SKILL.md` directly.
91 
92### Code Review
93 
94When reviewing a GitHub PR, do NOT run `pnpm lint` / `pnpm test` / `pnpm format` locally — its CI already ran them; inspect via `gh` instead.
95 
96### Issues
97 
98Use the `gh-create-issue` skill. Fallback: read `.agents/skills/gh-create-issue/SKILL.md` directly.
99 
100## Conventions
101 
102### TypeScript
103 
104- Cross-process types belong in `src/shared/`; renderer-only shared types in `src/renderer/types/` (see [Shared Layer Architecture](docs/references/shared-layer-architecture.md)).
105 
106### Naming Conventions
107 
108**MUST READ**: [docs/references/naming-conventions.md](docs/references/naming-conventions.md) — files, directories, identifiers, and singular/plural rules.
109 
110### Logging
111 
112```typescript
113import { loggerService } from "@logger";
114const logger = loggerService.withContext("moduleName");
115// Renderer only: loggerService.initWindowSource('windowName') first
116logger.info("message", CONTEXT);
117logger.warn("message");
118logger.error("message", error);
119```
120 
121### Paths
122 
123**MUST READ**: [src/main/core/paths/README.md](src/main/core/paths/README.md) — namespaces, naming, adding new keys, testing patterns. (Rule stated in Guiding Principle "Access paths centrally".)
124 
125### i18n
126 
127- All user-visible strings must use `i18next` — never hardcode UI strings
128- Run `pnpm i18n:check` to validate; `pnpm i18n:sync` to add missing keys
129- Locale files in `src/renderer/i18n/`
130 
131### UI Design
132 
133For any UI component or page style work, read [DESIGN.md](./DESIGN.md) first and follow its colors, fonts, spacing, and component specs strictly.
134 
135## Architecture
136 
137### Code Organization
138 
139Where each file and directory belongs — read the doc for the process you're touching before adding code or opening a directory. Each process root's top level is a **closed set**: route new code into an existing category, never a new top-level directory ([Naming Conventions §4.8](docs/references/naming-conventions.md)).
140 
141A directory's `index.ts` is a **barrel** — an enforced encapsulation boundary re-exporting one cohesive public API (internals private, outsiders import through it): re-export only (no logic / `export *`), no nesting, and it exists only if lint can seal off deep imports — else no barrel. `index.tsx` is always banned ([Naming Conventions §6.4](docs/references/naming-conventions.md)).
142 
143- [Main Process Architecture](docs/references/main-process-architecture.md) — `src/main/` directories (`core`/`ipc`/`data`/`ai`/`features`/`services`/`utils`/`i18n`) and dependency direction.
144- [Renderer Architecture](docs/references/renderer-architecture.md) — `src/renderer/` two-axis (type × domain) layout and downward-only layering.
145- [Shared Layer Architecture](docs/references/shared-layer-architecture.md) — what belongs in `@shared` (cross-process + no mutable runtime state) and its closed top-level set.
146 
147### Data
148 
149**MUST READ**: [docs/references/data/README.md](docs/references/data/README.md) for system selection, architecture, and patterns.
150 
151| System | Use Case | APIs |
152| ---------------------------------------------------------- | ----------------------------------- | ---------------------------------------------------------- |
153| [BootConfig](docs/references/data/boot-config-overview.md) | Early boot settings (pre-lifecycle) | `bootConfigService.get()`, `usePreference('BootConfig.*')` |
154| [Cache](docs/references/data/cache-overview.md) | Temp data (can lose) | `useCache`, `useSharedCache`, `useSharedCacheValue`, `usePersistCache` |
155| [Preference](docs/references/data/preference-overview.md) | User settings | `usePreference` |
156| [DataApi](docs/references/data/data-api-overview.md) | Business data (**critical**) | `useQuery`, `useMutation` |
157 
158Scope:
159 
160- **BootConfig**: sync file-based; direct in main (pre-lifecycle), via `usePreference('BootConfig.*')` otherwise
161- **Cache**: memory / shared (cross-window) / persist tiers; memory + shared on both main and renderer; persist on both too but as **independent** stores (renderer = localStorage, main = JSON file at `{userData}/cache.json`), never shared — main additionally relays renderer persist sync between windows
162- **Preference**: cross-process (main + renderer); auto-syncs across windows
163- **DataApi**: SQLite-backed; no auto-sync, fetch on demand from renderer
164 
165Database: SQLite via **better-sqlite3** + Drizzle ORM — the driver is **synchronous** (queries and transactions run inline with no `await`, unlike the app's otherwise-async data layers), so `getDb()` queries and `withWriteTx(fn)` callbacks must be written synchronously. Schemas in `src/main/data/db/schemas/`, migrations via `pnpm db:migrations:generate`
166 
167**Write atomicity**: use `application.get('DbService').withWriteTx(fn)` to commit multiple writes (or a read-then-write) all-or-nothing in one synchronous `BEGIN IMMEDIATE` transaction; `fn` must be synchronous. A single write doesn't need it — better-sqlite3 runs each statement atomically on its one connection. See [Database Patterns — Write Serialization](docs/references/data/database-patterns.md#write-serialization-dbservicewritewritetx).
168 
169**DataApi boundary rule**: DataApi is for SQLite-backed business data only. No database table → no DataApi endpoint; use IPC instead. See [Scope & Boundaries](docs/references/data/api-design-guidelines.md#dataapi-scope--boundaries).
170 
171### IPC (IpcApi)
172 
173**MUST READ**: [docs/references/ipc/README.md](docs/references/ipc/README.md) — paradigm boundary (RPC vs REST), schema/router/preload/facade layering, `IpcContext`, error model, security.
174 
175Non-data command IPC (window/system/shell/notification/external/file) goes through **IpcApi** — the fifth subsystem alongside BootConfig/Cache/Preference/DataApi, RPC-over-IPC with single-point schemas (`schema + handler` to add a route; `ipcApi.request('namespace.action', input)` to call; `IpcApiService.broadcast`/`send` + `useIpcOn` for events). Legacy command IPC still coexists, so you'll encounter both. Decision: SQLite data → DataApi; user setting → Preference; losable/shared → Cache; everything else imperative → IpcApi.
176 
177### Window Manager
178 
179**MUST READ**: [docs/references/window-manager/README.md](docs/references/window-manager/README.md) — lifecycle modes, pool mechanics, API reference.
180 
181All `BrowserWindow` goes through `WindowManager` with one of three modes (`default` / `singleton` / `pooled`), declared per type in `src/main/core/window/windowRegistry.ts`.
182 
183- **Consumer API**: use only `open()` / `close()` — never `create()` / `destroy()` in business code.
184- **Attach listeners in `onWindowCreated`**, not after `open()` — reused windows skip the latter.
185- **Renderer reads init data via `useWindowInitData`**.
186 
187### Main Process Services (Lifecycle)
188 
189**MUST READ**: [docs/references/lifecycle/README.md](docs/references/lifecycle/README.md) — architecture, decision guides, usage patterns, and migration steps.
190 
191All main-process services that own long-lived resources or register persistent side effects **must** use the lifecycle system:
192 
193- **Extend `BaseService`**, apply `@Injectable`, `@ServicePhase`, `@DependsOn` decorators
194- **Register in `serviceRegistry.ts`** (`src/main/core/application/serviceRegistry.ts`) — one line per service
195- **Use `@DependsOn` for same-phase dependencies only** — do NOT declare dependencies on BeforeReady services (`PreferenceService`, `DbService`, `CacheService`, `DataApiService`) from WhenReady services; phase ordering is auto-enforced by the container
196- **Access via `application.get('Name')`** (or `getOptional()` for `@Conditional` services)
197- **Use `this.ipcHandle()` / `this.ipcOn()`** for IPC — auto-cleaned on stop/destroy, returns `Disposable`
198- **Use `this.registerInterval()`** for recurring timers — auto-unref'd, exception-isolated, auto-cleaned on stop/destroy, returns `Disposable`
199- **Use `this.registerDisposable()`** for cleanup tracking — accepts `Disposable` objects or `() => void` cleanup functions
200- **Use `Emitter<T>` / `Event<T>`** for inter-service events, **`Signal<T>`** for one-shot completion
201- **Implement `Activatable`** for services with heavy on-demand resources (IPC stays registered, resources load/release via `onActivate()`/`onDeactivate()`)
202- **Do NOT** use `new` or manual singleton patterns — the container manages instantiation, ordering, and shutdown
203 
204For detailed code examples, see [Usage Guide](docs/references/lifecycle/lifecycle-usage.md). For migrating legacy services, see [Migration Guide](docs/references/lifecycle/lifecycle-migration-guide.md).
205 
206### Non-Lifecycle Services (Direct-Import Singleton)
207 
208Services without long-lived resources or persistent side effects: use **named export singleton** (`export const x = new X()`). No `getInstance()` patterns. See [Decision Guide](docs/references/lifecycle/lifecycle-decision-guide.md) for criteria.
209 
210## v2 Refactoring (In Progress)
211 
212> **Current state — read before contributing.** v1 and v2 code **coexist** on `main` while the refactor works through its cleanup stage — code you touch may still be deleted or reshaped. Before touching subsystems being replaced, read [docs/references/data](docs/references/data/README.md) to learn which are being deleted, and heed `@deprecated` annotations in the code — they mark call sites slated for removal. (For where v1 fixes land, see **Target the right branch** in Operational Rules.)
213 
214### Coexistence Mindset
215 
216**v1 residue is throwaway.** v1 data reaches v2 only through the migrators in `src/main/data/migration/v2/` — never add fallbacks, dual-writes, or guards for v1 save / read / loss. When you're already editing an area, delete the v1 residue you touch (dead legacy-stack call sites, disabled v1 code blocks, now-unused modules) instead of leaving it in place. Don't go hunting for v1 code to delete in unrelated PRs, never delete code still wired into live v2 behavior (flag it instead), and don't fix v1 bugs on `main` — they go to the `v1` branch.
217 
218**The migration chain is no longer throwaway.** It was consolidated into a single clean initial migration and shipped with `v2.0.0-rc.1`, so `migrations/sqlite-drizzle/` now runs against databases holding real user rows. Never wipe or rewrite an already-shipped migration, and never tell a user to delete their database: schema changes go in as new appended migrations generated by `pnpm db:migrations:generate`. `src/main/data/db/schemas/` still changes freely — but every change must survive a migrate-forward on a populated database.
219 
220**Resolving migration merge conflicts: regenerate, never rename.** When an upstream migration conflicts with your local one, delete your local `.sql` + its `meta/*_snapshot.json` and re-run `pnpm db:migrations:generate`. Renaming/renumbering instead silently reuses the snapshot's random `id`, forking the chain for everyone — and `drizzle-kit generate` still exits `0`; only `pnpm db:migrations:check` catches it. CI enforces both the chain check and a schema↔migration generate-and-diff step.
221 
222### Data Classification Toolchain
223 
224`v2-refactor-temp/tools/data-classify/` is the code generation pipeline for the v2 data layer; `classification.json` is the single source of truth (see its README). Four files are **auto-generated — NEVER edit them by hand**: `src/shared/data/preference/preferenceSchemas.ts`, `src/shared/data/bootConfig/bootConfigSchemas.ts`, and `PreferencesMappings.ts` + `BootConfigMappings.ts` in `src/main/data/migration/v2/migrators/mappings/`. To change them, edit `classification.json` or `target-key-definitions.json` (both in `data/`), then run `cd v2-refactor-temp/tools/data-classify && npm run generate`.
225 
226### Breaking Changes Log
227 
228When a v2 change is user-perceivable and affects how users use the app, add an entry under `v2-refactor-temp/docs/breaking-changes/`. See [v2-refactor-temp/docs/breaking-changes/README.md](v2-refactor-temp/docs/breaking-changes/README.md) for conventions.
229 
230## Local Instructions
231 
232If `CLAUDE.local.md` exists in the repository root (gitignored, may be absent), read it in full before acting on anything in this file — it holds the developer's private instructions and **OVERRIDES this file wherever they conflict**. Tools that auto-load it (e.g. Claude Code) need not re-read it.
233 
@@ −1 +1 @@
1−# provider-registry — module instructions
1+## Guiding Principles (MUST FOLLOW)
22  
3−The bundled AI **provider + model catalog**. This package has two faces:
3+### Mindset
44  
5−- **Build-time**: a generation pipeline (`src/creators/` + `src/providers/` + `scripts/generate-catalog.ts`) that emits the three `data/*.json` files.
6−- **Runtime**: schemas + `registry-loader.ts` that the app reads those JSON files through.
5+How to approach any coding task in this repo.
76  
8−Full architecture: [docs/architecture.md](docs/architecture.md). Consumer API: [README.md](README.md).
7+#### Think Before Coding
98  
10−## Cardinal rule — NEVER hand-edit `data/*.json`
9+- State assumptions explicitly. If uncertain, ask before implementing.
10+- When multiple interpretations exist, surface them — do not pick silently.
11+- If a simpler approach exists, say so. Push back when warranted.
12+- If something is unclear, stop. Name what is confusing. Ask.
1113  
12−`data/models.json`, `data/providers.json`, `data/provider-models.json` are **PURE GENERATED ARTIFACTS**. Editing them by hand is always wrong — the next `pnpm generate` silently reverts your change, and **CI rejects it**: the `catalog-hand-edit-check` job fails any PR that touches `data/*.json` without a matching change under `src/` or `scripts/`.
14+#### Simplicity First
1315  
14−To change the catalog, edit the **source** and regenerate:
16+- Write the minimum code that solves the problem. Nothing speculative.
17+- No features beyond what was asked.
18+- No abstractions for single-use code.
19+- No "flexibility" or "configurability" that was not requested.
20+- No error handling for impossible scenarios.
21+- If you wrote 200 lines and it could be 50, rewrite it.
1522  
16−| You want to change… | Edit | Then |
17−| --- | --- | --- |
18−| a model's metadata (capabilities, modalities, context/limits, name) | `src/creators/<creator>.ts` | `pnpm generate` |
19−| how a provider connects / which models it serves / its pricing & overrides | `src/providers/<provider>.ts` | `pnpm generate` |
23+#### Surgical Changes
2024  
21−`pnpm generate` reads the upstream catalogs (models.dev / OpenRouter text + image models) **live**; set `MODELSDEV_CACHE` / `OPENROUTER_CACHE` / `OPENROUTER_IMAGE_CACHE` to local files to cache them during dev. Always commit the **source change and the regenerated `data/*.json` together** — a data change with no source change reads as a hand-edit and CI blocks it.
25+- Touch only what the task requires. Do not "improve" adjacent code, comments, or formatting.
26+- Do not refactor things that are not broken.
27+- Match existing style even if you would do it differently.
28+- If you notice unrelated dead code, mention it — do not delete it.
29+- Remove imports / variables / functions that **your** changes orphaned. Leave pre-existing dead code alone unless asked.
30+- **v1 residue is a standing exception:** during the v2 refactor you may delete (not just flag) v1 dead code in an area you're already editing — see [v2 Refactoring → Coexistence Mindset](#coexistence-mindset). Unrelated v1 code and *fixing* v1 remain out of scope.
31+- Every changed line must trace directly to the user's request.
2232  
23−## Source of truth
33+#### Goal-Driven Execution
2434  
25−- **`src/creators/<creator>.ts`** — model **creators** (anthropic, openai, cohere, alibaba, …). Declares *what models exist* and their *intrinsic metadata*. Built with `defineCreator`. A creator is the home for capabilities/modalities/context — **creator owns metadata**.
26−- **`src/providers/<provider>.ts`** — serving **providers** / gateways / clouds (dashscope, ppio, tokenhub, openrouter, aws-bedrock, …). Declares *how to connect* and *which models it serves* with per-provider `apiModelId`, pricing, and overrides. Built with `defineProvider` / `openaiCompatible` — **provider owns parameter support** (endpoints/transport, per-provider param sets).
27−- **models.dev + OpenRouter** — read live at generation time to enrich metadata/pricing for the models the registry references (not committed; `pnpm generate` fetches them).
35+- Convert tasks into verifiable goals before coding:
36+ - "Add validation" → "Write tests for invalid inputs, then make them pass."
37+ - "Fix the bug" → "Write a test that reproduces it, then make it pass."
38+ - "Refactor X" → "Ensure tests pass before and after."
39+- For multi-step tasks, state a brief plan with explicit verification per step:
2840  
29−## Rules when editing source
41+```
42+1. [Step] → verify: [check]
43+2. [Step] → verify: [check]
44+```
3045  
31−- **Hand-list models with full metadata.** A creator model is `{ id, name, capabilities, … }` — never a bare `{ id }`. Add `name` + the relevant `capabilities` / `contextWindow` / `maxOutputTokens` / modalities; without them the model resolves with no capabilities.
32−- **`imageGeneration`: creator carries `supports` (the param vocabulary) as the provider-agnostic DEFAULT; the provider carries `vendorTransport` (endpoint routing).** The runtime **replaces** `imageGeneration` wholesale (it does not deep-merge), so a model-level block must never contain a provider-specific `vendorTransport`, and any provider needing a custom endpoint restates the **full** block (supports + transport). See [docs/architecture.md#image-generation-design-b](docs/architecture.md#image-generation-design-b).
33−- **`idPrefixes` must be vendor-specific.** A prefix claims every catalog id matching it, so a generic prefix (`rerank`, `embed`) will mis-attribute other vendors' models. Use the creator's own namespace (`rerank-v`, `command`, `c4ai`, …).
34−- **A provider override whose `modelId` is not a base model must carry a standalone `name`** (vendor-exclusive). The catalog-invariants test fails on a dangling override (a `modelId` that is neither in `models.json` nor a named standalone).
46+### Operational Rules
3547  
36−## Verify (required before commit)
48+Project-specific tools, paths, and conventions.
3749  
38−```bash
39−pnpm --filter @cherrystudio/provider-registry generate # regenerate data/*.json from source + live upstream
40−pnpm --filter @cherrystudio/provider-registry test # vitest: schema conformance + catalog invariants
50+- **Keep it clear**: Write code that is easy to read, maintain, and explain.
51+- **Read local READMEs first**: Before editing code in a directory, check for a `README.md` in that directory (and its parents) and read it — these files capture local conventions, invariants, and entry points that aren't obvious from the code alone.
52+- **Fix upstream, don't hack downstream**: When a new feature hits an existing module's limitation, flag the upstream improvement for the user's decision before proposing a downstream workaround.
53+- **Library-first, custom-last**: Before writing custom code, check library/framework docs for built-in options or existing solutions. Write custom code only when no adequate alternative exists.
54+- **Build with Tailwind CSS & Shadcn UI**: Use components from `@cherrystudio/ui` (located in `packages/ui`, Shadcn UI + Tailwind CSS) for every new UI component.
55+- **Log centrally**: Route all logging through `loggerService` with the right context—no `console.log`.
56+- **Access paths centrally**: Use `application.getPath('namespace.key', filename?)` for all main-process filesystem paths—never call `app.getPath()`, `os.homedir()`, or construct paths ad-hoc. Import the singleton via `import { application } from '@application'`.
57+- **Lint, test, and format before completion**: Coding tasks are only complete after running `pnpm lint`, `pnpm test`, and `pnpm format` successfully.
58+- **Write conventional commits**: Commit small, focused changes using Conventional Commit messages (e.g., `feat(data-api):`, `fix(lifecycle):`, `refactor(quick-assistant):`, `docs(testing):`, `chore(deps):`, `test(window-manager):`). Scope must be a specific kebab-case module, never generic like `main` — when `git log` conflicts with this rule, this rule wins.
59+- **Keep history linear**: On shared branches, never use plain `git pull` — it creates merge commits. Always `git pull --rebase` (or `git fetch && git rebase origin/<branch>`). Before `git push`, run `git fetch`; if `origin/<branch>` has advanced, rebase your local commits onto it first. If you notice a merge commit in local history that hasn't been pushed yet, rebase it away — cleaning one up after it's public requires a risky force-push on a shared branch.
60+- **Sign commits and sign off**: Every commit must be both cryptographically signed and DCO-signed off. Use `git commit -S --signoff` (not `--signoff` alone), verify the commit object contains a `gpgsig` header with `git cat-file commit HEAD`, and verify the pushed PR commits show `Verified` on GitHub.
61+- **Target the right branch**: `main` is the default branch for active development — submit features, refactors, optimizations, and fixes for the current codebase here. v1 maintenance fixes (hotfixes and subsequent v1 releases) must branch from and target the `v1` branch (never `main`); a v1 fix does not auto-carry to `main`, so forward-port it with a separate PR if the bug also exists on `main`. See [v2 Refactoring](#v2-refactoring-in-progress).
62+ 
63+## Development
64+ 
65+### Commands
66+ 
67+Run `pnpm install` first (Node and pnpm versions are pinned in `package.json` — let it enforce them). For every other script, read `package.json` — the ones you must know:
68+ 
69+- `pnpm lint` — oxlint + eslint fix + typecheck + i18n check + format (writes files)
70+- `pnpm test` — run all Vitest tests
71+- `pnpm format` — Biome format + lint (write mode)
72+- `pnpm build:check` — **REQUIRED before commits**. If it fails on i18n sort, run `pnpm i18n:sync` first; on formatting, run `pnpm format` first; on broken doc links, fix the link.
73+- `pnpm test:lint` — the CI-equivalent lint gate: it denies oxlint warnings that `pnpm lint` / `pnpm build:check` silently tolerate; run it when CI must pass.
74+ 
75+### Testing
76+ 
77+- Tests run with Vitest 3 (see `vitest.config.*` for project setup).
78+- **Frontend Tests — MUST READ**: [Frontend Testing Guidelines](docs/references/testing/frontend-testing.md).
79+- **Test Mocking**: Use the unified mock system — do NOT create ad-hoc mocks for `application`, services, or data layers. See [tests/__mocks__/README.md](tests/__mocks__/README.md) for available mocks, usage patterns, and best practices.
80+- **Database Tests**: For any service/handler/seeder that reads or writes SQLite, use `setupTestDatabase()` from `@test-helpers/db` — it provides a real file-backed DB with production migrations. Do NOT hand-write `CREATE TABLE` SQL, override `@application`, or stub Drizzle chains. See [docs/references/testing/database-testing.md](docs/references/testing/database-testing.md).
81+ 
82+### Patched Dependencies
83+ 
84+Before upgrading any dependency, check `patches/` for custom patches.
85+ 
86+## GitHub
87+ 
88+### Pull Requests
89+ 
90+Use the `gh-create-pr` skill. Fallback: read `.agents/skills/gh-create-pr/SKILL.md` directly.
91+ 
92+### Code Review
93+ 
94+When reviewing a GitHub PR, do NOT run `pnpm lint` / `pnpm test` / `pnpm format` locally — its CI already ran them; inspect via `gh` instead.
95+ 
96+### Issues
97+ 
98+Use the `gh-create-issue` skill. Fallback: read `.agents/skills/gh-create-issue/SKILL.md` directly.
99+ 
100+## Conventions
101+ 
102+### TypeScript
103+ 
104+- Cross-process types belong in `src/shared/`; renderer-only shared types in `src/renderer/types/` (see [Shared Layer Architecture](docs/references/shared-layer-architecture.md)).
105+ 
106+### Naming Conventions
107+ 
108+**MUST READ**: [docs/references/naming-conventions.md](docs/references/naming-conventions.md) — files, directories, identifiers, and singular/plural rules.
109+ 
110+### Logging
111+ 
112+```typescript
113+import { loggerService } from "@logger";
114+const logger = loggerService.withContext("moduleName");
115+// Renderer only: loggerService.initWindowSource('windowName') first
116+logger.info("message", CONTEXT);
117+logger.warn("message");
118+logger.error("message", error);
41119 ```
42120  
43−Commit the regenerated `data/*.json` alongside your `src/` change. Generation also re-pulls live upstream, so the data diff may include unrelated metadata/pricing drift since the last run — that's expected. CI enforces sync in **both** directions: the `catalog-hand-edit-check` job rejects a `data/*.json` change with no `src/`/`scripts/` change (a hand-edit), and the `catalog-source-sync` test (in `test:provider-registry`) rejects the reverse — a `src/` change you forgot to regenerate — by re-deriving the source-controlled facts (provider connection config, hand-listed creator models + their `ownedBy`/`name`, provider overrides) and diffing them against the committed JSON. It's deterministic (no upstream fetch), so it only covers source-derived data; upstream-enriched fields (pricing, inferred metadata) and overall correctness still rely on the schema/catalog-invariant tests above and code review.
121+### Paths
122+ 
123+**MUST READ**: [src/main/core/paths/README.md](src/main/core/paths/README.md) — namespaces, naming, adding new keys, testing patterns. (Rule stated in Guiding Principle "Access paths centrally".)
124+ 
125+### i18n
126+ 
127+- All user-visible strings must use `i18next` — never hardcode UI strings
128+- Run `pnpm i18n:check` to validate; `pnpm i18n:sync` to add missing keys
129+- Locale files in `src/renderer/i18n/`
130+ 
131+### UI Design
132+ 
133+For any UI component or page style work, read [DESIGN.md](./DESIGN.md) first and follow its colors, fonts, spacing, and component specs strictly.
134+ 
135+## Architecture
136+ 
137+### Code Organization
138+ 
139+Where each file and directory belongs — read the doc for the process you're touching before adding code or opening a directory. Each process root's top level is a **closed set**: route new code into an existing category, never a new top-level directory ([Naming Conventions §4.8](docs/references/naming-conventions.md)).
140+ 
141+A directory's `index.ts` is a **barrel** — an enforced encapsulation boundary re-exporting one cohesive public API (internals private, outsiders import through it): re-export only (no logic / `export *`), no nesting, and it exists only if lint can seal off deep imports — else no barrel. `index.tsx` is always banned ([Naming Conventions §6.4](docs/references/naming-conventions.md)).
142+ 
143+- [Main Process Architecture](docs/references/main-process-architecture.md) — `src/main/` directories (`core`/`ipc`/`data`/`ai`/`features`/`services`/`utils`/`i18n`) and dependency direction.
144+- [Renderer Architecture](docs/references/renderer-architecture.md) — `src/renderer/` two-axis (type × domain) layout and downward-only layering.
145+- [Shared Layer Architecture](docs/references/shared-layer-architecture.md) — what belongs in `@shared` (cross-process + no mutable runtime state) and its closed top-level set.
146+ 
147+### Data
148+ 
149+**MUST READ**: [docs/references/data/README.md](docs/references/data/README.md) for system selection, architecture, and patterns.
150+ 
151+| System | Use Case | APIs |
152+| ---------------------------------------------------------- | ----------------------------------- | ---------------------------------------------------------- |
153+| [BootConfig](docs/references/data/boot-config-overview.md) | Early boot settings (pre-lifecycle) | `bootConfigService.get()`, `usePreference('BootConfig.*')` |
154+| [Cache](docs/references/data/cache-overview.md) | Temp data (can lose) | `useCache`, `useSharedCache`, `useSharedCacheValue`, `usePersistCache` |
155+| [Preference](docs/references/data/preference-overview.md) | User settings | `usePreference` |
156+| [DataApi](docs/references/data/data-api-overview.md) | Business data (**critical**) | `useQuery`, `useMutation` |
157+ 
158+Scope:
159+ 
160+- **BootConfig**: sync file-based; direct in main (pre-lifecycle), via `usePreference('BootConfig.*')` otherwise
161+- **Cache**: memory / shared (cross-window) / persist tiers; memory + shared on both main and renderer; persist on both too but as **independent** stores (renderer = localStorage, main = JSON file at `{userData}/cache.json`), never shared — main additionally relays renderer persist sync between windows
162+- **Preference**: cross-process (main + renderer); auto-syncs across windows
163+- **DataApi**: SQLite-backed; no auto-sync, fetch on demand from renderer
164+ 
165+Database: SQLite via **better-sqlite3** + Drizzle ORM — the driver is **synchronous** (queries and transactions run inline with no `await`, unlike the app's otherwise-async data layers), so `getDb()` queries and `withWriteTx(fn)` callbacks must be written synchronously. Schemas in `src/main/data/db/schemas/`, migrations via `pnpm db:migrations:generate`
166+ 
167+**Write atomicity**: use `application.get('DbService').withWriteTx(fn)` to commit multiple writes (or a read-then-write) all-or-nothing in one synchronous `BEGIN IMMEDIATE` transaction; `fn` must be synchronous. A single write doesn't need it — better-sqlite3 runs each statement atomically on its one connection. See [Database Patterns — Write Serialization](docs/references/data/database-patterns.md#write-serialization-dbservicewritewritetx).
168+ 
169+**DataApi boundary rule**: DataApi is for SQLite-backed business data only. No database table → no DataApi endpoint; use IPC instead. See [Scope & Boundaries](docs/references/data/api-design-guidelines.md#dataapi-scope--boundaries).
170+ 
171+### IPC (IpcApi)
172+ 
173+**MUST READ**: [docs/references/ipc/README.md](docs/references/ipc/README.md) — paradigm boundary (RPC vs REST), schema/router/preload/facade layering, `IpcContext`, error model, security.
174+ 
175+Non-data command IPC (window/system/shell/notification/external/file) goes through **IpcApi** — the fifth subsystem alongside BootConfig/Cache/Preference/DataApi, RPC-over-IPC with single-point schemas (`schema + handler` to add a route; `ipcApi.request('namespace.action', input)` to call; `IpcApiService.broadcast`/`send` + `useIpcOn` for events). Legacy command IPC still coexists, so you'll encounter both. Decision: SQLite data → DataApi; user setting → Preference; losable/shared → Cache; everything else imperative → IpcApi.
176+ 
177+### Window Manager
178+ 
179+**MUST READ**: [docs/references/window-manager/README.md](docs/references/window-manager/README.md) — lifecycle modes, pool mechanics, API reference.
180+ 
181+All `BrowserWindow` goes through `WindowManager` with one of three modes (`default` / `singleton` / `pooled`), declared per type in `src/main/core/window/windowRegistry.ts`.
182+ 
183+- **Consumer API**: use only `open()` / `close()` — never `create()` / `destroy()` in business code.
184+- **Attach listeners in `onWindowCreated`**, not after `open()` — reused windows skip the latter.
185+- **Renderer reads init data via `useWindowInitData`**.
186+ 
187+### Main Process Services (Lifecycle)
188+ 
189+**MUST READ**: [docs/references/lifecycle/README.md](docs/references/lifecycle/README.md) — architecture, decision guides, usage patterns, and migration steps.
190+ 
191+All main-process services that own long-lived resources or register persistent side effects **must** use the lifecycle system:
192+ 
193+- **Extend `BaseService`**, apply `@Injectable`, `@ServicePhase`, `@DependsOn` decorators
194+- **Register in `serviceRegistry.ts`** (`src/main/core/application/serviceRegistry.ts`) — one line per service
195+- **Use `@DependsOn` for same-phase dependencies only** — do NOT declare dependencies on BeforeReady services (`PreferenceService`, `DbService`, `CacheService`, `DataApiService`) from WhenReady services; phase ordering is auto-enforced by the container
196+- **Access via `application.get('Name')`** (or `getOptional()` for `@Conditional` services)
197+- **Use `this.ipcHandle()` / `this.ipcOn()`** for IPC — auto-cleaned on stop/destroy, returns `Disposable`
198+- **Use `this.registerInterval()`** for recurring timers — auto-unref'd, exception-isolated, auto-cleaned on stop/destroy, returns `Disposable`
199+- **Use `this.registerDisposable()`** for cleanup tracking — accepts `Disposable` objects or `() => void` cleanup functions
200+- **Use `Emitter<T>` / `Event<T>`** for inter-service events, **`Signal<T>`** for one-shot completion
201+- **Implement `Activatable`** for services with heavy on-demand resources (IPC stays registered, resources load/release via `onActivate()`/`onDeactivate()`)
202+- **Do NOT** use `new` or manual singleton patterns — the container manages instantiation, ordering, and shutdown
203+ 
204+For detailed code examples, see [Usage Guide](docs/references/lifecycle/lifecycle-usage.md). For migrating legacy services, see [Migration Guide](docs/references/lifecycle/lifecycle-migration-guide.md).
205+ 
206+### Non-Lifecycle Services (Direct-Import Singleton)
207+ 
208+Services without long-lived resources or persistent side effects: use **named export singleton** (`export const x = new X()`). No `getInstance()` patterns. See [Decision Guide](docs/references/lifecycle/lifecycle-decision-guide.md) for criteria.
209+ 
210+## v2 Refactoring (In Progress)
211+ 
212+> **Current state — read before contributing.** v1 and v2 code **coexist** on `main` while the refactor works through its cleanup stage — code you touch may still be deleted or reshaped. Before touching subsystems being replaced, read [docs/references/data](docs/references/data/README.md) to learn which are being deleted, and heed `@deprecated` annotations in the code — they mark call sites slated for removal. (For where v1 fixes land, see **Target the right branch** in Operational Rules.)
213+ 
214+### Coexistence Mindset
215+ 
216+**v1 residue is throwaway.** v1 data reaches v2 only through the migrators in `src/main/data/migration/v2/` — never add fallbacks, dual-writes, or guards for v1 save / read / loss. When you're already editing an area, delete the v1 residue you touch (dead legacy-stack call sites, disabled v1 code blocks, now-unused modules) instead of leaving it in place. Don't go hunting for v1 code to delete in unrelated PRs, never delete code still wired into live v2 behavior (flag it instead), and don't fix v1 bugs on `main` — they go to the `v1` branch.
217+ 
218+**The migration chain is no longer throwaway.** It was consolidated into a single clean initial migration and shipped with `v2.0.0-rc.1`, so `migrations/sqlite-drizzle/` now runs against databases holding real user rows. Never wipe or rewrite an already-shipped migration, and never tell a user to delete their database: schema changes go in as new appended migrations generated by `pnpm db:migrations:generate`. `src/main/data/db/schemas/` still changes freely — but every change must survive a migrate-forward on a populated database.
219+ 
220+**Resolving migration merge conflicts: regenerate, never rename.** When an upstream migration conflicts with your local one, delete your local `.sql` + its `meta/*_snapshot.json` and re-run `pnpm db:migrations:generate`. Renaming/renumbering instead silently reuses the snapshot's random `id`, forking the chain for everyone — and `drizzle-kit generate` still exits `0`; only `pnpm db:migrations:check` catches it. CI enforces both the chain check and a schema↔migration generate-and-diff step.
221+ 
222+### Data Classification Toolchain
223+ 
224+`v2-refactor-temp/tools/data-classify/` is the code generation pipeline for the v2 data layer; `classification.json` is the single source of truth (see its README). Four files are **auto-generated — NEVER edit them by hand**: `src/shared/data/preference/preferenceSchemas.ts`, `src/shared/data/bootConfig/bootConfigSchemas.ts`, and `PreferencesMappings.ts` + `BootConfigMappings.ts` in `src/main/data/migration/v2/migrators/mappings/`. To change them, edit `classification.json` or `target-key-definitions.json` (both in `data/`), then run `cd v2-refactor-temp/tools/data-classify && npm run generate`.
225+ 
226+### Breaking Changes Log
227+ 
228+When a v2 change is user-perceivable and affects how users use the app, add an entry under `v2-refactor-temp/docs/breaking-changes/`. See [v2-refactor-temp/docs/breaking-changes/README.md](v2-refactor-temp/docs/breaking-changes/README.md) for conventions.
229+ 
230+## Local Instructions
231+ 
232+If `CLAUDE.local.md` exists in the repository root (gitignored, may be absent), read it in full before acting on anything in this file — it holds the developer's private instructions and **OVERRIDES this file wherever they conflict**. Tools that auto-load it (e.g. Claude Code) need not re-read it.
44233  
RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack

RuleStack

Built by

Kynth Studio

Directory

Configs
Stacks
Compare formats
Diff two configs
Best AGENTS.md examples

Formats

AGENTS.md
CLAUDE.md
Cursor rules
Copilot instructions

Reference

Read API
Corpus health
Privacy Policy
Terms

RuleStack