packages/shared was never a real pnpm workspace package (no package.json); it was referenced only through the @shared TypeScript path alias. Relocate it under src/ via git mv (143 files, detected as pure renames).
Repoint the @shared alias and include globs to src/shared across electron.vite.config.ts, tsconfig.{json,node,web}.json and vitest.config.ts; update scripts/check-custom-exts.ts, scripts/update-languages.ts, the eslint.config.mjs generated-file globs, the data-classify generator output targets, .github/CODEOWNERS path rules, and CLAUDE.md/docs/source-comment references.
The @shared alias name is unchanged, so all 1403 @shared/* import sites resolve without modification. Verified with typecheck:node, typecheck:web and the full test suite (700 files, 9739 tests passing).
Add a 'configfile' source kind to BootConfigMigrator so the v1 home config
file's `appDataPath` is migrated into a new BootConfig key
`app.user_data_path: Record<string, string>`, keyed by executable path.
v1's `~/.cherrystudio/config/config.json` is conceptually "early-boot
configuration that must be readable before userData is decided" — the same
category as BootConfig. v1 `config/config.json` will eventually be replaced
entirely by BootConfig; this PR establishes the data migration path, and a
follow-up will rewire `initAppDataDir()` to read from BootConfig instead.
Key pieces:
- New `LegacyHomeConfigReader` — sync fs read, normalizes both the legacy
string and the array-of-{executablePath,dataPath} v1 formats into a
`Record<string, string>`. Returns `null` (not `{}`) for "no data" so the
migrator's null-skip guard distinguishes "missing" from "empty record"
and doesn't write a spurious empty entry.
- BootConfigMigrator: new 'configfile' branch in `prepare()`; inline
`configFileMappings` local const with `targetKey: BootConfigKey` type
annotation (regen safety net — schema loses `app.user_data_path` →
compile error at the declaration site). `defaultValue: null` on
config-file items so "no v1 file" skips the item rather than falling
back to the schema default `{}`.
- Type tightening: `MigrationItem.targetKey` and `PreparedData.targetKey`
narrowed from `string` to `BootConfigKey`; all 6 `as BootConfigKey`
assertions deleted. This removes a silent "regen drops the key" failure
mode where the assertions previously suppressed compile errors.
- Generator updates: `generate-boot-config.js` gains a
`MANUAL_BOOT_CONFIG_ITEMS` list that flows through the same sort/emit
pipeline as classification-derived items, keeping `bootConfigSchemas.ts`
as a fully auto-generated single-interface file (no manual sections, no
declaration merging, no preservation logic). `generate-migration.js`
tightens the 3 BootConfig mapping arrays to `targetKey: BootConfigKey`.
- Tests: new `LegacyHomeConfigReader.test.ts` covers 9 scenarios (7 null
returns + 2 populated records); new `BootConfigMigrator.test.ts` covers
the configfile source end-to-end plus a redux-source regression.
- Docs: per-migrator `README-BootConfigMigrator.md` created per the
convention in `v2-migration-guide.md`. `v2-migration-guide.md`,
`boot-config-overview.md`, `boot-config-schema-guide.md`, and
`src/main/data/migration/v2/README.md` updated to mention
BootConfigMigrator, `LegacyHomeConfigReader`, and the 'configfile'
source kind. The AppImage/Windows-portable `executablePath`
normalization gap is documented as a known limitation that must be
addressed in the follow-up read-side PR.
Explicitly out of scope:
- Rewiring `initAppDataDir()` / `updateAppDataConfig()` to read/write
BootConfig — the v1 home config file keeps working unchanged.
- Adding a 'configfile' category to classification.json — the
data-classify toolchain isn't modelled for file sources yet.
- Deleting the v1 home config file post-migration — left intact.
Verified end-to-end on a real v1 config.json: the migrator produced
`"app.user_data_path": { [executablePath]: dataPath }` in
`~/.cherrystudio/boot-config.json`, verbatim-preserving the v1 data.
Signed-off-by: fullex <0xfullex@gmail.com>
### What this PR does
Before this PR:
The v2 migration system only supports ElectronStore and Redux as data
sources for preference migration. Dexie IndexedDB `settings` table (a
simple KV store used by the renderer for translate settings, pinned
models, etc.) has no migration path.
After this PR:
- Adds `DexieSettingsReader` that pre-loads the Dexie `settings` table
into memory for synchronous KV access, consistent with
`ElectronStoreReader` and `ReduxStateReader`
- Extends `MigrationContext` with a `dexieSettings` data source (makes
`createMigrationContext` async to pre-load the table)
- `PreferencesMigrator` now reads from `'dexie-settings'` source for
both simple and complex mappings
- `DEXIE_SETTINGS_MAPPINGS` is auto-generated into
`PreferencesMappings.ts` from `classification.json`'s new
`dexieSettings` section
- All generator scripts (`generate-migration.js`,
`generate-preferences.js`, `classificationUtils.js`) support
`dexieSettings` as a data source with priority-based deduplication
### Why we need it and why it was done in this way
The following tradeoffs were made:
- `DEXIE_SETTINGS_MAPPINGS` is integrated into `PreferencesMappings.ts`
(not a separate file) to keep all preference mapping exports in one
auto-generated file and simplify imports.
- `dexieSettings` priority is set to 2 (same as `localStorage`, below
`redux` at 3). If the same `targetKey` exists in both `redux` and
`dexieSettings`, redux wins — this is intentional since redux data is
typically more up-to-date.
- Dynamic keys (`image://`, `mcp:provider:*`) are explicitly excluded
from this path. They will be handled by dedicated migrators in future
PRs.
The following alternatives were considered:
- Generating a separate `DexieSettingsMappings.ts` file — rejected in
favor of consolidating all mappings into one file for simpler imports
and unified statistics.
Links to places where the discussion took place:
https://github.com/CherryHQ/cherry-studio/issues/10162
### Breaking changes
None.
### Special notes for your reviewer
- The `classification.json` `dexieSettings.settings` array is currently
empty (skeleton only). Actual key classifications will be added in
follow-up PRs.
- The architecture supports dynamic keys via
`DexieSettingsReader.keys()` prefix filtering, but dynamic key migrators
are out of scope for this PR.
- Source identifier in `PreferencesMigrator` uses `'dexie-settings'`
(with hyphen) to distinguish from the Dexie export reader
(`dexieExport`) used by `ChatMigrator`.
### Checklist
- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [ ] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. Check this only
when the PR introduces or changes a user-facing feature or behavior.
- [ ] Self-review: I have reviewed my own code (e.g., via
[`/gh-pr-review`](/.claude/skills/gh-pr-review/SKILL.md), `gh pr diff`,
or GitHub UI) before requesting review from others
### Release note
```release-note
NONE
```
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Add data-classify tools for data inventory extraction and code generation
- Include consolidated Chinese documentation (README.md)
- Update generated file path references
This temporary directory will be removed after V2 refactor is complete.