Repository navigation
feat: keep Tcode's data in ~/.tcode on every platform - #601
Merged
Merged
Conversation
The data directory is ~/.tcode on macOS, Windows and Linux, with TCODE_DATA_DIR still overriding it; one function owns the resolution. At startup an older build's directory (LEGACY_TCODE_DATA_DIR, else the platform data directory) is moved in before anything opens the store: entries are renamed, or copied and verified across filesystems, a name present on both sides stops the move without touching anything, a cancelled or interrupted move is continued by the next start, and the emptied directory is removed. Once the store opens, legacy/ from the JSONL migration is deleted. The move reports through the same progress dialog as the migration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Maintainer decisions: the data directory is
~/.tcodeon every platform, an older build's directory is moved there at startup with nothing left behind, andlegacy/from the JSONL migration (#594) is removed once the store opens.Behaviour
tcode_services::store::data_dir()→TCODE_DATA_DIR(empty counts as unset), else~/.tcode; no home directory is an error namingTCODE_DATA_DIR. The traverse native host, the UI's client data dir, headless and the desktop app all use it; traverse's duplicate resolution and itsdirsdependency are gone. iOS keeps its sandbox Application Support (its data is a client's pairing files, not a host data dir); Android keepsfilesDir.SessionStore::migrate(), aRelocatingphase before the JSONL migration, under the new dir's ownership lock. Source:LEGACY_TCODE_DATA_DIRif set (even withTCODE_DATA_DIR/--data-dir), else the platform directory an older build used (~/Library/Application Support/tcode,$XDG_DATA_HOME/tcode,%APPDATA%\tcode) unless the data dir was chosen explicitly. It runs when the new dir holds no data (tcode.db,sessions.json,settings.json,secrets.json,traverse.json,device.json,*.jsonl; an existingworktrees/does not count) and the old one does. Every entry is renamed; on the first cross-device error the rest are copied in 8 MiB chunks, verified by length and byte comparison, retired, published, then deleted. A name on both sides stops the move before anything is touched. Cancel is checked per entry and per chunk; the next start resumes from atcode.relocating/marker, re-copies a partial file and publishes a verified one. The old dir's lock file and.DS_Storeare deleted with the emptied directory.open_liverefuses to open while a move is due (an early open would createtcode.dbin the empty new dir and make the move look done); desktop--pairand headlessset-passwordrefuse while a move is pending so no pre-move write turns into a collision.legacy/is removed after every successful open, so users who migrated under feat: keep thread metadata and event logs in a Turso database #594 are cleaned up too; a failed open keeps it.serveruns preparation before--passwordand the bind check; its banner and phase lines cover the move. Dialog strings no longer claim the originals are kept; both locale files updated. Docs: README, docs/remote.md, CONTRIBUTING ("Verifying real behaviour":LEGACY_TCODE_DATA_DIR).Evidence
~/.tcode/worktrees/, scratch paths viaTCODE_DATA_DIR/LEGACY_TCODE_DATA_DIR: same-volume rename of all entries in under a second, then the JSONL migration (3,026 threads, 111 s, byte-identical), shell opened, threads render; old dir gone, nolegacy/, no marker; 15,028/15,030 non-thread files hash-identical (the other two aresettings.jsonand the model manifest, rewritten by the running app), 26 symlinks identical,worktrees/untouched.profile-homes(919 MB, 947 read-only directories) copied with every permission identical — this run found a bug (read-only directories broke the source deletion), fixed with a regression test.Tests
Added: collision stops before anything moves; a cancelled move keeps what it moved and the next start finishes; a copied entry (nested dirs, multi-chunk file, empty file, symlink, read-only tree) arrives verified with permissions preserved and its source deleted; an interrupted copy re-copies a partial file and publishes a verified one; the same directory under another name is not moved; and at the host entry point, a real child process (
open_host→needs_migration→migrate→open, as the app does) moves an older data dir in, migrates it and leaves nothing behind, with phases in order.Changed (contract "originals kept in
legacy/" removed by decision): the migration helper assertslegacy/absent after open, with the database still compared byte for byte against the sources; one test fixture rewrites its sources instead of restoring them fromlegacy/; the refused-database test now also proveslegacy/survives a failed open; the runtime timeline test drops itslegacy/content assertion (owned by the store tests). No test removed. Not tested by design: "TCODE_DATA_DIRonly → no relocation", because a regression would move a developer's real data into a temp dir.Checks run
cargo fmt --all --check,cargo clippy --workspace --all-targets --locked -- -D warnings,cargo nextest run --workspace --locked(911 passed, 11 skipped),cargo machete, Web, iOS simulator and Android (cargo ndk) checks with-D warnings, locale parity, the ignoredmigration_survives_sigkill. Not run: Windows and Linux (the%APPDATA%→%USERPROFILE%\.tcodepath, Windows symlink creation and NTFS read-only removal are checked against std's source only).PROTOCOL_VERSIONbump: a note was added under "Unreleased" above theconstant in
crates/protocol/src/lib.rs(the number itself changes onlywhen the release is cut — CONTRIBUTING.md, principle 9).