Backup · Migration (Export / Import)
When moving Blyck to another computer (e.g. a Windows laptop → a macOS Mac mini), manually copying the userData folder breaks things: chats point at the old PC’s absolute paths, secrets are tied to the OS keychain and won’t unlock, and OS-dependent binaries don’t run.
Backup · Migration packs your things up (export) and unpacks them (import) with a single button, and on unpacking it automatically converts paths so your chat history carries on as is. All four directions of Win↔Mac work.
Why manual copying breaks
Section titled “Why manual copying breaks”| Problem | Details |
|---|---|
| Absolute-path mismatch | The chat points at D:\develope\… but the new PC is /Users/… |
| OS-dependent secrets | DB/SSH passwords and GitHub tokens are encrypted with the OS keychain (safeStorage) and can’t be decrypted on another PC |
| OS-dependent binaries | python venv, LSP servers, etc. don’t run even when copied |
| Huge regenerable cache | The search/embedding index (workspace.sqlite, ~226MB) tags along wholesale |
What gets moved and what gets discarded
Section titled “What gets moved and what gets discarded”🟢 Migration targets (included in the bundle)
Section titled “🟢 Migration targets (included in the bundle)”chats/— chat history (messages included, self-contained)blyck-history.db— change history (VACUUM INTOsnapshot)db-history.json·db-snippets.json— DB query history · snippetslayout.json·blyck-locale.json·embeddings-settings.json— layout · language · settingsconnections.json— DB/SSH connection metadata (secrets stripped in plaintext bundles)attachments/·changeSet-snapshots/— optional
⚫ Excluded — regenerated on the target PC
Section titled “⚫ Excluded — regenerated on the target PC”workspace.sqlite— search/embedding index (~226MB). Most of it is derived from the codebase, so excluding it wholesale shrinks the bundle from 230MB → a few MB, and the indexer auto-reindexes on the target PC.python-venvs/·lsp-servers/— OS binaries (regenerated)- Electron/Chromium runtime caches, logs, etc.
The bundle format .blyckbundle
Section titled “The bundle format .blyckbundle”A ZIP container + manifest.json (schema · app version · source OS · path roots · per-file sha256).
backup-YYYY-MM-DD.blyckbundle├── manifest.json└── files/ # mirror of userData-relative paths ├── chats/index.json, chat_*.json ├── blyck-history.db ├── db-history.json, db-snippets.json ├── layout.json, blyck-locale.json, embeddings-settings.json ├── connections.json # plaintext bundle strips secrets ├── attachments/** # optional └── changeSet-snapshots/** # optionalPath remapping — carrying chats on as is
Section titled “Path remapping — carrying chats on as is”On import, only the authoritative path fields in the chat JSON are substituted.
| Field | Remapping |
|---|---|
projectRoot | ✅ Substituted |
_lastSentProjectRoot | ✅ Substituted |
extraRoots[] | ✅ Each element substituted |
projectRootSftp | ❌ Unchanged (remote is PC-independent) |
messages[] | ❌ Unchanged (history preserved) |
The rule is longest-prefix matching — if a path starts with the source root, only the prefix is swapped to the target root and the remaining separators are converted. Unmapped roots are left as is (the chat opens but only the project stays unresolved, for the user to reopen).
Cross-OS, four directions (every Win↔Mac combination)
Section titled “Cross-OS, four directions (every Win↔Mac combination)”remapPath handles the source separator (for splitting) and the target separator (for joining) separately. The source separator is auto-detected from the source root (\/drive letter → Win, / → POSIX), and the target separator is determined by the target OS.
| Direction | Source path example | Result example |
|---|---|---|
| Win→Win | D:\dev\App\src\a.js | E:\work\App\src\a.js |
| Win→Mac | D:\dev\App\src\a.js | /Users/x/App/src/a.js |
| Mac→Win | /Users/x/dev/App/src/a.js | D:\work\App\src\a.js |
| Mac→Mac | /Users/x/dev/App/src/a.js | /Users/y/App/src/a.js |
Drive-letter/root-agnostic — because it’s a prefix substitution, any root combination such as D:\ ↔ /Users/ is resolved 1:1 from the mapping table.
Encrypted bundle + secrets included
Section titled “Encrypted bundle + secrets included”On export, specifying a password encrypts the entire bundle.
- Method: whole-bundle AES-256-GCM — ZIP’s built-in encryption (ZipCrypto) is weak, so it’s not used; instead the zip is built and then encrypted wholesale with Node’s built-in
crypto(zero external dependencies). The KDF isscrypt, and the cipher isAES-256-GCM(confidentiality + integrity). - A wrong password = GCM auth tag verification failure → “Incorrect password” is detected immediately (no partial decryption, data unchanged).
- A plaintext header (
BLYCKENC1) lets it determine whether a bundle is encrypted up front, without a password.
Secrets are direction-agnostic — decrypt with Win safeStorage → encrypted bundle → re-encrypt with Mac safeStorage (and vice versa) — so all four directions of Win↔Mac hold.
Export flow
Section titled “Export flow”- Quiescence check — refuses if there’s a busy turn (data consistency)
blyck-history.db→ a single snapshot viaVACUUM INTO(safe while the app is running)- Collect the included files + per-file sha256
- Scan chats → record the distinct path roots in
manifest.pathRoots - Secret handling — no password: strip / password specified: include plaintext secrets
- ZIP packaging
- If a password is specified, AES-256-GCM encrypt → write
*.blyckbundle
Import flow
Section titled “Import flow”- inspect — determine whether it’s encrypted via magic bytes. If encrypted, prompt for the password
- decrypt — password → scrypt → AES-256-GCM. Aborts on auth tag failure (data unchanged)
- path-remapping UI — an input field per source root (base name auto-suggested:
D:\develope\Blyck_Web→~/dev/Blyck_Web) - safety backup — preserves the current
chats/·*.dbtouserData/_pre-import-<ts>/ - Extract
files/→ write to userData - apply remapping — longest-prefix substitution of
projectRoot/_lastSentProjectRoot/extraRoots+ separator normalization (projectRootSftp·messagesunchanged) - restore secrets — encrypted bundle: re-encrypt with the target OS safeStorage / plaintext bundle: flag “re-entry required”
- No
workspace.sqlite→ auto-reindex on the next run - Restart prompt
Modes — replace vs merge
Section titled “Modes — replace vs merge”| Mode | Behavior | Use case |
|---|---|---|
| replace | Back up the current chats/ · *.db to _pre-import-<ts>, then replace with the bundle | Migrate wholesale to a new PC |
| merge | Merge into an existing install by chat id (add without replacing) | Gather the work of two PCs into one place |
Merge is safe because chats/ is a separate JSON per id, so they merge without conflict.
Safeguards
Section titled “Safeguards”- Automatic backup of the current data before import (
_pre-import-<ts>) - manifest schema/app-version compatibility gate
- per-file sha256 integrity verification
- import refused while a chat is busy
- explicit user confirmation before replace
- a wrong password on an encrypted bundle → aborts at the decrypt stage (data unchanged)
- secrets not included in plaintext bundles (leak prevention)
Q. Will my chat history open as is on the new PC?
→ Yes. On import, path remapping auto-converts projectRoot and the like to the new PC’s paths, so chats and projects carry on as is.
Q. Do I have to re-enter DB/SSH passwords? → If you export as an encrypted bundle (password specified), secrets are included and re-encrypted for the target OS, so no re-entry is needed. A plaintext bundle omits secrets for security, so re-entry is required.
Q. Can I unpack a bundle made on Windows on a Mac?
→ Yes. All four directions, including Win→Mac and Mac→Win, are supported. Path separators (\↔/) and drive letters/roots are converted automatically.
Q. Why is the bundle so small?
→ The ~226MB workspace.sqlite (search index) can be regenerated from the codebase, so it’s excluded. The indexer auto-reindexes on the target PC, while the chat history itself is preserved as is.
Q. What if I forget the password? → There’s no recovery. AES-256-GCM cannot be decrypted without the password, so keep the encrypted bundle’s password somewhere safe.
Q. What if I want to merge into an existing PC’s work? → Use merge mode. It merges by chat id, adding without deleting existing chats.