Legacy Data Migration
Relevant source files
The following files were used as context for generating this wiki page:
PlanQueue implements a robust migration and backward-compatibility layer to handle data transition from earlier iterations of the project. Specifically, it ensures that users who previously used the extension under different names (such as "free-text" or "omp-free-text") can still access their session notes and configurations without manual data movement.
The primary purpose of this system is to maintain a seamless experience while transitioning storage roots to the unified ~/.planqueue/ directory. The system follows a "read-only fallback" strategy, where legacy data is accessible for viewing and loading, but all new writes are directed to the modern directory structure.
Sources: README.md:126-130, CHANGELOG.md:38-40, SECURITY.md:27-31
Migration Architecture
The migration logic is embedded within the core storage and initialization routines. When a session starts or the cross-session browser is opened, the system performs a prioritized search across multiple filesystem roots.
File System Hierarchy
PlanQueue recognizes three distinct storage roots, prioritized from newest to oldest:
- Current Root:
~/.planqueue/ - Legacy Root A:
~/.free-text/ - Legacy Root B:
~/.omp-free-text/
Sources: src/main.ts:8-13, SECURITY.md:27-31, tests/core-integration.test.ts:21-25
Data Flow for Migration
The following diagram illustrates how PlanQueue resolves note paths and handles data retrieval across legacy and current directories.
The system utilizes a fallback chain to ensure that legacy session notes are discovered even if they haven't been migrated to the new root.
Sources: src/main.ts:251-264, README.md:126-130
Key Migration Components
The migration is managed through specific utility functions and logic patterns that abstract the physical location of the files from the rest of the application.
Path Resolution Functions
The system uses specialized functions to generate potential paths for both modern and legacy data.
| Function | Purpose | Related Files |
|---|---|---|
notePathFor | Generates the primary path in the ~/.planqueue/ root. | src/main.ts, tests/core-integration.test.ts |
legacyNotePathsFor | Returns an array of paths in legacy roots (~/.free-text, ~/.omp-free-text). | src/main.ts, tests/core-integration.test.ts |
loadNoteWithFallback | Attempts to load data by iterating through the primary and legacy paths. | src/main.ts |
legacySessionsDirsFor | Resolves directory locations for browsing history in legacy roots. | src/main.ts |
Sources: src/main.ts:24-38, tests/core-integration.test.ts:16-25
Implementation Detail: Session Initialization
During initSession, the extension explicitly requests legacy paths to populate the session content if the primary path is empty.
// From src/main.ts lines 257-260
content = await loadNoteWithFallback(
notePath,
legacyNotePathsFor(loc, homedir()),
);
Sources: src/main.ts:257-260
Cross-Session Browser Integration
The /planqueue command allows users to browse notes from other sessions. The migration logic ensures that legacy sessions are merged into this view.
Merging Strategy
- List Fresh: The system first lists all notes in the current
sessionsDir. - Iterate Legacy: It then iterates through
legacySessionsDirs. - Deduplicate: If a session ID already exists in the "seen" set (from a newer root), the legacy entry is skipped. This ensures that the newest version of a session always "wins."
- Sort: The final list is sorted by modification time (
mtimeMs) before being displayed to the user.
Sources: src/main.ts:88-101, CHANGELOG.md:38-40
The browser merges legacy and modern sessions, providing a unified interface for data retrieval.
Sources: src/main.ts:88-108
Configuration Migration
Global configuration, such as custom shortcuts, follows the same migration pattern. The loadShortcuts function attempts to read from the modern configPathFor and falls back to legacyConfigPathsFor if necessary.
// From src/main.ts lines 212-215
raw = await loadNoteWithFallback(
configPathFor(homedir()),
legacyConfigPathsFor(homedir()),
);
This ensures that user preferences for editNotes, queueStep, and queueToggleAuto shortcuts are preserved across version updates.
Sources: src/main.ts:212-215, README.md:104-124
Summary of Migration Behavior
PlanQueue treats legacy data as immutable sources for modern sessions. While it can read and display data from ~/.free-text/ and ~/.omp-free-text/, any modifications made during a session (including auto-normalizing tasks or marking items as done) are saved exclusively to the new ~/.planqueue/ structure. This ensures a clean transition to the new naming convention while maintaining full data availability for the user.
Sources: README.md:126-130, CHANGELOG.md:38-40, SECURITY.md:27-31