Overview
A bulk migration is just 3xcode pyspark convert pointed at a directory instead of a single file. The CLI discovers every .sql file, schedules them across parallel workers, and tracks the whole batch as a single named session, so you can check status at any time, watch it live, or pick it back up if it's interrupted. The workflow has four steps.
Initialize
Create a workspace to hold input, output, and session state.
Convert
Run pyspark convert --dir with workers and a named session.
Monitor
Watch progress via session status or the local web UI.
Resume
If interrupted, pick the session back up exactly where it stopped.
Prerequisites
Bulk conversion requires an active login and license: every file in the batch calls an LLM provider, so the CLI authenticates and validates your license before starting any work.
# Authenticate first (device flow, or --email/--password) 3xcode login # Confirm everything is wired up correctly 3xcode health
3xcode health checks that the AI engine's required dependencies are installed, the backend is reachable, you're authenticated, an active workspace exists, and reports your machine's CPU/RAM so you know a sensible worker count for step 2.
Step 1: Initialize a Workspace
A workspace is the project folder that holds your input SQL, converted output, and session tracking data. Point it at an empty directory: workspace init creates the input/, output/, .sessions/, and logs/ subfolders for you and sets it as the active workspace.
# Create and activate a workspace 3xcode workspace init ./warehouse-migration --name "warehouse-migration" # Copy (or point) your source SQL files into the workspace's input/ directory, # e.g. cp -r /path/to/legacy-sql/* ./warehouse-migration/input/ # Confirm it's active and see file counts 3xcode workspace status
You can register and switch between multiple workspaces, useful when migrating more than one codebase or environment.
Related workspace commands
| Command | Purpose |
|---|---|
3xcode workspace list | List all registered workspaces; the active one is marked |
3xcode workspace switch <path> | Switch the active workspace |
3xcode workspace status | Session count, input/output file counts, last session ID |
3xcode workspace prune | Remove stale registry entries whose directory no longer exists |
Step 2: Run the Bulk Conversion
Pass --dir instead of a single file path to convert every .sql file underneath it. Give the run a --session name so it's easy to find later, and set --workers to control how many files convert in parallel.
# Bulk convert everything under ./sql/, 4 parallel workers, named session 3xcode pyspark convert --dir ./sql/ --session "warehouse-migration" -w 4 # Let the CLI auto-detect a sensible worker count from CPU/RAM 3xcode pyspark convert --dir ./sql/ --session "warehouse-migration" # Run as a detached background worker that survives closing the terminal 3xcode pyspark convert --dir ./sql/ --session "warehouse-migration" -w 4 --detach
Each file runs the full 5-phase pipeline (discovery, planning, conversion, validation, and auto-fix) independently within the batch.
Key bulk conversion flags
| Flag | Default | Purpose |
|---|---|---|
--dir | N/A | Convert every `.sql` file in this directory (enables bulk mode) |
-w, --workers | 0 (auto-detect) | Number of files to convert in parallel |
--session | None | Name for this batch, used for status/resume lookups |
--schedule | simple-first | Scheduling order: `simple-first` or `complex-first` |
--model | account default | Model to use: `sonnet`, `opus`, or `haiku` |
-d, --detach | False | Run as a background worker that survives CLI exit |
--resume | None | Resume an interrupted session by ID instead of starting fresh |
Detached workers are capped at 3 concurrent runs per machine, regardless of workspace. If you hit that limit, wait for one to finish or run it in the foreground instead.
Step 3: Monitor Progress
A foreground run shows live parallel progress in the terminal. For a detached run (or to check in on a batch from another terminal), use session status or the web UI. Note that --session sets a human-readable name for the batch, but session status, session info, session resume, and pyspark convert --resume all expect the actual session ID, not that name: run 3xcode session list to look it up.
session status
Snapshot of counts by file status, worker phase, current file, and an ETA (baseline supported for the sonnet model). Works whether the session is running or finished.
session status --watch
Tails live JSONL events from a running worker in real time; Ctrl-C to stop watching without affecting the run. Shows the last 20 events if nothing is currently running.
3xcode ui
Local browser-based dashboard (localhost, single-user) with a Sessions page showing live per-file progress, an event stream, and file browsing for completed output.
session list / list-all
`session list` shows every session in the active workspace with state, file counts, and cost. `session list-all` shows currently-running sessions across every workspace on the machine.
# Look up the session ID for this batch (--session only sets the display name) 3xcode session list # One-time status snapshot: use the ID from the list above 3xcode session status <session-id> # Tail live events (Ctrl-C to stop watching) 3xcode session status <session-id> --watch # Full per-file breakdown: status, cost, duration, error messages 3xcode session info <session-id> # Open the local web UI dashboard 3xcode ui
Step 4: Resume After Interruption
Bulk sessions are resumable by design. If a batch is cancelled, loses network connectivity, or the terminal/process is killed mid-run, already-completed files stay completed: you only reconvert what didn't finish.
# Look up the session ID first (--session only sets the display name) 3xcode session list # Resume via the session sub-app 3xcode session resume <session-id> # Equivalent: resume via pyspark convert 3xcode pyspark convert --resume <session-id> # Cancel a running batch cleanly (worker exits at the next phase boundary) 3xcode session cancel <session-id>
session cancel writes a flag the worker polls between pipeline phases (not between files), so it exits cleanly rather than being killed mid-phase: already-completed files remain completed, the file that was in progress at cancel time is marked interrupted, and the session state becomes cancelled until you resume it. Session lookups for status, cancel, delete, and rename search across all registered workspaces, not just the active one, so you can manage a batch from anywhere.
Best Practices
Let workers auto-detect
Leave -w/--workers at its default (0) unless you have a reason to override it. It sizes parallelism from your machine's CPU count and available RAM via a system resource check.
Name every session
Always pass --session with a descriptive name. It's the handle you'll use for status, resume, and cancel later. An unnamed batch is much harder to find again.
Choose a schedule deliberately
Set --schedule to simple-first (the default) or complex-first to control the order files are attempted in.
Detach for large batches
For large directories, run with --detach so the conversion survives closing your terminal or laptop lid, then check back in with session status --watch.
Your source SQL stays local
The CLI talks to your LLM provider directly for conversion: source code is never sent to the 3XDE backend, which only handles auth, licensing, and usage metadata.
Prune stale workspaces
Run workspace prune periodically if you migrate many one-off directories: it clears registry entries whose folder no longer exists so workspace list stays clean.