feat(native): docker-migration helpers — Docker → PGlite wizard pure-TS core (#176 sub-task 7)#205
Merged
Merged
Conversation
…TS core (#176 sub-task 7) Implements the pure-TS building blocks for the native-app first-run "Import from Docker install" wizard described in docs/native-migration-spike.md. Three pure functions + one helper, all unit-tested: - stripPsqlDirectives(sql): removes \restrict / \unrestrict / \connect lines that modern pg_dump emits but PGlite's exec() cannot parse. Conservative line-prefix match preserves SQL whose string literals happen to contain the directive token. - applyDumpToPGlite(pg, rawDump): single-shot restore of a stripped full pg_dump output into a fresh PGlite (precondition: empty, no migrations applied — the dump carries its own schema, dodging the circular-FK warning called out in the spike §3). - countTables(pg, tables): row counts behind an identifier-regex guard so the helper is safe to expose to less-trusted callers. - verifyMigration(source, target): row-equality check the wizard uses post-restore to assert no data loss before persisting the dataDir or rolling back. Out of scope (lives in the Tauri shell, sub-task 3 of #176): - probing for an existing Docker stack (psql / docker ps shell-out) - invoking pg_dump (docker exec shell-out) - writing the .migrated-from-docker.json marker - user-facing migration card 10/10 new tests pass under node --test. Full mcp-server suite still green (1032 pass, 0 fail, 1 pre-existing skip). Atomic and conflict-free with PR #202 (data-dir root) and PR #203 (Tauri shell scaffold) — different files in mcp-server/src/native/. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dewinator
added a commit
that referenced
this pull request
May 4, 2026
The previous "0 PRs offen" snapshot is stale: the agent itself opened a 4-PR queue in the last 4 ticks (#208 standalone + #209→#210→#211 stack). Refresh the Aktiver-Code-Bestand block to credit landed sub-tasks (#202 DATA_DIR, #203 Tauri shell, #204 CI gate, #205 migration helpers) and add a Queue-Stand note that names the open stack, the linear merge constraint, and the ~19 still-supabase-direct services that the DbClient migration sub-story will work through atomically. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dewinator
added a commit
that referenced
this pull request
May 4, 2026
…sks 1/2/3-most/4/5/7-core landed The 09024a2 (tick 103) snapshot is two days stale: 9 of the 9 PRs in its "recommended merge order" have merged, plus #197/#198/#201/#202/#203/#204/ #205/#206/#207 landed in the same window. Refresh the doc that "is the canonical entry point for the native-app initiative" so a fresh reader does not get a 79-tick-old picture. Concrete changes: - Phase line: "spike phase complete · gated on PR-queue drain" → "implementation underway · sub-tasks 1, 2, 3 (most), 4, 5, 7 (core) landed; 5 PRs open, ~26 h Reed-lag since #202–#207". - End-state installer list: ".dmg / .msi / .AppImage" → ".pkg / .msi / .AppImage", with the 2026-05-04 epic-body decision (.pkg, not .dmg) cited. - Sub-task table: legend (✅ landed, 🔄 PR open, ⏳ spike-only) plus per-row PR status reflecting the current main: - Row 1 picks up #204 (79-migration walk as CI gate). - Row 3 picks up #202, #203, #206, #207 as landed and #208–#211 as open. Row was "_none yet_". - Row 4 / 5 reframed as "inherent" (PGlite is one WASM binary; node-llama-cpp ships per-platform bindings). - Row 7 picks up #205 (Docker → PGlite migration helpers core). - New "DbClient sub-story" subsection: 22 services touch Supabase directly on main; 2 in flight (Skills, SwarmPin); 20 remain after the open stack lands. Pattern: one service per PR. - "Recommended merge order — open PR queue (9 deep)" section replaced with "Open PR queue (5 deep, all CLEAN+MERGEABLE)" — the 9 it documented have all merged. - "Post-drain implementation gate" → "Post-stack implementation gate": parallel tracks (DbClient long-tail of 20 services + the sub-tasks 6/8/9 release-pipeline triangle on tauri-plugin-updater per #207). Doc-only, zero risk, direct-to-main per the standing rule for this file shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Implements the pure-TS building blocks for the native-app first-run "Import from Docker install" wizard described in
docs/native-migration-spike.md. Sub-task 7 of #176 (native standalone app, prio 0.98 / Wave 1).After this lands, the orchestrator (
migrateFromDocker()) that lives in the Tauri shell can call into these helpers without re-implementing dump-handling. The shell-bound steps (probe +docker exec pg_dump) stay where they belong (sub-task 3 / PR #203 follow-up).What's in this PR
mcp-server/src/native/docker-migration.ts— three pure functions + one helper:stripPsqlDirectives(sql)\\restrict/\\unrestrict/\\connectlines that modern pg_dump emits but PGlite'sexec()can't parseapplyDumpToPGlite(pg, rawDump)countTables(pg, tables)verifyMigration(source, target)The stripper is conservative — only line-prefix matches are dropped, so SQL whose string literals happen to contain the directive token (e.g.
'please \\restrict me') is preserved verbatim.Tests
mcp-server/src/__tests__/native/docker-migration.test.ts— 10 new tests, all green:stripPsqlDirectivesdrops the three known directives, preserves literals containing the token, idempotentapplyDumpToPGliterestores a synthetic dump (CREATE EXTENSION vector, CREATE TABLE withvector(4), INSERTs,\\restrict/\\unrestrictbook-end) — row count + vector + TEXT[] all round-tripcountTablesreturns counts for populated + empty tables, rejects injection attempts (`memories"; DROP TABLE x; --`, leading-digit names, dashes, empty)verifyMigrationok=true on equality, reports drift, treats missing target tables as 0, ignores extra target tables (PGlite metadata is allowed)Out of scope (intentional)
These belong in the Tauri shell follow-ups, NOT here:
psql -lqt/docker ps) — shell-boundpg_dump(docker exec ... pg_dump) — shell-bound.migrated-from-docker.jsonpost-success markerDocumented in the file header so the next PR knows where the boundary is.
Test plan
cd mcp-server && npm test— full suite greencd mcp-server && node --test dist/__tests__/native/docker-migration.test.js— 10/10 passstripPsqlDirectivesis idempotent on its own outputConflict-free with the queue
Touches only new files under
mcp-server/src/native/andmcp-server/src/__tests__/native/. Zero file overlap with:data-dir.ts— also new file in same dir, but different name)app/— Tauri shell, separate top-level dir)pglite-migration-walk.test.ts— different test file)Merge order between #202 / #203 / #204 / this PR is independent.
Related
docs/native-migration-spike.md(the design this implements)🤖 Generated with Claude Code