Installation
SOVR Patch runs as a CLI tool. Install globally or use via npx.
# Install globally (recommended for frequent use)
npm install -g sovr-patch
# Verify installation
sovr-patch --help# Run directly with npx (always latest version)
npx sovr-patch run --rule field-rename \
--from "config.baseUrl" --to "config.apiBaseUrl" \
--repo ./my-project- Node.js 18+ (LTS recommended)
- TypeScript project with tsconfig.json
- No network required for scanning (offline-first)
Quick Start
This walkthrough takes you from zero to a completed migration in under 5 minutes. We'll rename config.baseUrl to config.apiBaseUrl across a real TypeScript project.
Your team decided to rename the API config field from baseUrl to apiBaseUrl for clarity. The field is referenced in type definitions, property access, destructuring patterns, and this. chains across 22 files. Manual rename would take hours and risk missing references. SOVR Patch does it in seconds.
Step 1: Install SOVR Patch
Install globally for repeated use, or run directly with npx.
# Option A: Install globally
npm install -g sovr-patch
# Option B: Run without installing (always latest)
npx sovr-patch --helpStep 2: Dry-run scan (free, no files changed)
Run a dry-run to discover every reference. No files are modified — this is always free.
sovr-patch run --rule field-rename \
--from "config.baseUrl" \
--to "config.apiBaseUrl" \
--repo ./my-project \
--reportStep 3: Review the output
The engine shows every hit with its classification. Safe hits get patches. Ambiguous hits are flagged for manual review.
Rule: field-rename
Repo: /projects/my-project
Scanning 22 TypeScript files...
Hits: 13
safe: 12
ambiguous: 1
unsafe: 0
Patches: 12
Changed files: 3
Verify: PASS
Applied: no (dry-run)
─── src/api/client.ts ───
L4: const url = `${this.config.baseUrl}${path}` [SAFE → PATCH]
L12: return this.config.baseUrl [SAFE → PATCH]
─── src/config.ts ───
L4: baseUrl: "https://api.example.com" [SAFE → PATCH]
─── src/types.ts ───
L2: baseUrl: string [SAFE → PATCH]
Dry-run complete.
Safe apply is locked on the free plan.
Unlock options:
Safe TS Migration Pack — $99
Full Engine — $249
→ sovr.app/patch/pricingStep 4: Activate your license
After purchasing, download your license.json and activate it. The license is verified locally — no network call needed.
# Download license.json from your purchase confirmation page
# Then activate it:
sovr-patch activate license.json
# Expected output:
# License activated successfully.
# Plan: Safe TS Migration Pack
# Email: [email protected]
# Rules: field-rename, nullish-fallback
# Expires: 3/7/2027
# Verify activation:
sovr-patch statusStep 5: Apply with safe-apply
Add --apply to write changes. The engine copies your project to a temp directory, applies patches, runs tsc --noEmit, and only writes to your real files if the compiler says yes.
sovr-patch run --rule field-rename \
--from "config.baseUrl" \
--to "config.apiBaseUrl" \
--repo ./my-project \
--applyRule: field-rename
Repo: /projects/my-project
Scanning 22 TypeScript files...
Hits: 13
Patches: 12
Changed files: 3
Verify: PASS ✓
Applied: yes (3 files written)
Done. All patches applied and verified.Step 6: Verify and commit
Check the diff, run your own tests, and commit.
# Review what changed
git diff
# Run your project's tests
npm test
# If something went wrong, rollback instantly
sovr-patch rollback
# All good? Commit.
git add -A && git commit -m "refactor: rename config.baseUrl → config.apiBaseUrl"- →Try
sovr-patch audit --pack safe-ts-migration --repo ./my-projectto scan for all migration opportunities - →Use
--jsonflag to pipe output into your CI pipeline - →Check
sovr-patch status --verboseto see all unlocked rules - →Read the AI Tool Integration section to use with Cursor, Claude Code, or Copilot
Commands
Complete reference for every CLI command.
sovr-patch run
Run a rule against a repository. By default performs a dry-run (no file changes). Add --apply to write patches after verification.
| Parameter | Type | Required | Description |
|---|---|---|---|
| --rule | string | required | Rule to execute (e.g., field-rename, nullish-fallback) |
| --repo | path | default: . | Path to target repository |
| --tsconfig | path | default: <repo>/tsconfig.json | Path to tsconfig.json |
| --apply | flag | optional | Apply patches to real files (requires license + tsc verification) |
| --no-verify | flag | optional | Skip tsc verification in dry-run mode |
| --json | flag | optional | Output results as JSON |
| --report | flag | optional | Print summary report |
| --report-file | path | optional | Write JSON report to file |
# Basic dry-run with report
sovr-patch run --rule field-rename \
--from "config.baseUrl" --to "config.apiBaseUrl" \
--repo ./my-project --report
# Apply with safe-apply verification
sovr-patch run --rule field-rename \
--from "plan.yearlyPrice" \
--to "plan.prices.find(p => p.interval === 'year')?.amount" \
--fallback "0" --repo ./my-project --apply
# Output as JSON for CI integration
sovr-patch run --rule nullish-fallback \
--target "response.data" --fallback "null" \
--repo ./api-server --json
# Save report to file
sovr-patch run --rule field-rename \
--from "user.name" --to "user.displayName" \
--repo ./app --report-file ./migration-report.jsonsovr-patch scan
Alias for run without --apply. Always performs a dry-run. Accepts the same parameters as run.
# Equivalent to: sovr-patch run --rule field-rename ...
sovr-patch scan --rule field-rename \
--from "config.baseUrl" --to "config.apiBaseUrl" \
--repo ./my-projectsovr-patch audit
Audit a repository to quantify migration debt before changing code. Supports single-rule and pack modes.
| Parameter | Type | Required | Description |
|---|---|---|---|
| --rule | string | optional | Single rule to audit (e.g., design-token) |
| --pack | string | optional | Audit pack to run (safe-ts-migration or frontend-refactor) |
| --repo | path | default: . | Path to target repository |
| --tsconfig | path | default: <repo>/tsconfig.json | Path to tsconfig.json |
| --json | flag | optional | Output audit report as JSON |
| --report-file | path | optional | Write JSON audit report to file |
# Audit a single rule
sovr-patch audit --rule design-token \
--repo ./web-app \
--map "#ff0000:var(--sovr-danger),#00ff88:var(--sovr-success)"
# Audit an entire pack
sovr-patch audit --pack frontend-refactor --repo ./web-app
# Export audit report as JSON
sovr-patch audit --pack safe-ts-migration \
--repo ./api-server --json
# Save audit report to file
sovr-patch audit --pack safe-ts-migration \
--repo ./api-server --report-file ./audit-report.jsonsovr-patch status
Check your current license status, plan, available rules, and expiry date.
| Parameter | Type | Required | Description |
|---|---|---|---|
| --json | flag | optional | Output license status as JSON |
| --verbose | flag | optional | Show additional details (file path, signature info) |
# Check license status
sovr-patch status
# JSON output (for scripts)
sovr-patch status --json
# Verbose output with file path and signature details
sovr-patch status --verbose SOVR Patch — License Status
─────────────────────────────────
Plan: Full Engine
Email: [email protected]
Expires: 2027-03-07
Status: Active ✓
Licensed rules:
✓ field-rename
✓ nullish-fallback
✓ design-token
✓ inline-stylesovr-patch activate
Activate a signed license file to unlock safe-apply. The license is verified locally using Ed25519 signature — no network required.
| Parameter | Type | Required | Description |
|---|---|---|---|
| <license.json> | path | required | Path to the signed license file downloaded after purchase |
| --key | string | optional | Legacy: verify key against API (deprecated) |
| --status | flag | optional | Check current license (alias for 'status' command) |
| --deactivate | flag | optional | Remove current license from this machine |
# Activate with signed license file (recommended)
sovr-patch activate license.json
# Activate from a specific path
sovr-patch activate ~/Downloads/sovr-license.json
# Check current license status
sovr-patch activate --status
# Remove license from this machine
sovr-patch activate --deactivatesovr-patch list-rules
List all available rules with their descriptions and required parameters.
sovr-patch list-rulesAvailable rules:
field-rename
Safe TypeScript field rename across value refs, property keys, and type fields.
nullish-fallback
Inject ?? fallback for repeated property access targets.
design-token
Replace hardcoded hex color values with CSS custom property references.
inline-style
Convert JSX inline style objects to className strings.sovr-patch ci-gate
CI enforcement gate. Fails the build if migration debt exceeds the threshold. Requires Full Engine or Enterprise license.
| Parameter | Type | Required | Description |
|---|---|---|---|
| --rules | string | required | Comma-separated rules to check |
| --max-hits | number | default: 0 | Max allowed hits before failing |
| --repo | path | default: . | Path to target repository |
| --report-file | path | optional | Write combined JSON report to file |
| --json | flag | optional | Output results as JSON |
# Block PRs with any migration debt
sovr-patch ci-gate \
--rules field-rename,nullish-fallback \
--repo ./my-project --max-hits 0
# Allow up to 5 hits (gradual migration)
sovr-patch ci-gate \
--rules field-rename \
--max-hits 5 --repo ./my-project
# Save CI report for artifact upload
sovr-patch ci-gate \
--rules field-rename,nullish-fallback \
--repo ./my-project \
--report-file ./sovr-ci-report.json# .github/workflows/sovr-gate.yml
name: SOVR Migration Gate
on: [pull_request]
jobs:
migration-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npx sovr-patch ci-gate \
--rules field-rename,nullish-fallback \
--max-hits 0 \
--report-file sovr-report.json
- uses: actions/upload-artifact@v4
if: always()
with:
name: sovr-migration-report
path: sovr-report.jsonsovr-patch rollback
Rollback applied patches using automatically created checkpoints. Every --apply creates a checkpoint before writing.
| Parameter | Type | Required | Description |
|---|---|---|---|
| --list | flag | optional | List all available checkpoints |
| --checkpoint | string | optional | Timestamp of the checkpoint to restore |
| --repo | path | default: . | Path to target repository |
| --json | flag | optional | Output results as JSON |
# List available checkpoints
sovr-patch rollback --list --repo ./my-project
# Rollback to a specific checkpoint
sovr-patch rollback \
--checkpoint "2026-03-07T10:30:00.000Z" \
--repo ./my-projectRules Reference
Detailed reference for each rule, including what it detects, how it classifies hits, and the required configuration.
field-rename
Safe TypeScript field rename across value refs, property keys, type fields, this. chains, destructuring patterns, and shorthand properties. Handles all AST node types that reference the target field.
| Parameter | Type | Required | Description |
|---|---|---|---|
| --from | string | required | Source field path (e.g., "config.baseUrl", "plan.yearlyPrice") |
| --to | string | required | Target field path (e.g., "config.apiBaseUrl") |
| --fallback | string | optional | Fallback value for nullish coalescing (e.g., "0") |
| --include-this | flag | optional | Also scan this.<from> chains |
// All of these are detected and renamed:
config.baseUrl // property access
this.config.baseUrl // this. chain (with --include-this)
const { baseUrl } = config; // destructuring
type Config = { baseUrl: string } // type field
interface IConfig { baseUrl: string } // interface field
{ baseUrl: config.baseUrl } // shorthand propertysovr-patch run --rule field-rename \
--from "config.baseUrl" \
--to "config.apiBaseUrl" \
--include-this \
--repo ./my-project \
--apply --reportnullish-fallback
Inject ?? fallback for repeated property access targets. Chain-aware: wraps entire optional chains. Operator-precedence-aware: adds parentheses in binary expressions.
| Parameter | Type | Required | Description |
|---|---|---|---|
| --target | string | required | Target property access (e.g., "response.data", "plan.yearlyPrice") |
| --fallback | string | required | Fallback value (e.g., "null", "0", "[]") |
// Before:
return response.data?.items;
if (plan.yearlyPrice > 100) {
// After:
return (response.data ?? null).items;
if ((plan.yearlyPrice ?? 0) > 100) {sovr-patch run --rule nullish-fallback \
--target "response.data" \
--fallback "null" \
--repo ./api-server \
--applydesign-token
Replace hardcoded hex color values with CSS custom property references. Supports dual-mode: audit mode discovers all hex colors zero-config, run mode applies replacements using presets or custom maps.
| Parameter | Type | Required | Description |
|---|---|---|---|
| --map | string | optional | Comma-separated hex:token pairs. Required for run mode. (e.g., "#ff0000:var(--sovr-danger)") |
| --preset | string | optional | Use a built-in preset instead of --map. Available: sovr-core, all-hex |
# Discover all hardcoded hex colors — no map needed
sovr-patch audit --rule design-token --repo ./web-app
# Use a preset for smarter classification
sovr-patch audit --rule design-token --preset sovr-core --repo ./web-app// Before:
const errorColor = "#ff0000";
const successColor = "#00FF88";
const style = `color: #ff0000`;
// After:
const errorColor = "var(--sovr-danger)";
const successColor = "var(--sovr-success)";
const style = `color: var(--sovr-danger)`;# Use built-in sovr-core preset (maps common colors to CSS vars)
sovr-patch run --rule design-token --preset sovr-core --repo ./web-app --apply
# Or use a custom map
sovr-patch run --rule design-token \
--map "#ff0000:var(--sovr-danger),#00ff88:var(--sovr-success)" \
--repo ./web-app --applyAvailable presets:
inline-style
Convert JSX inline style objects to className strings. Supports dual-mode: audit mode discovers all inline styles zero-config, run mode applies replacements using presets or custom maps. Full-match produces a safe replace. Partial-match is flagged as ambiguous.
| Parameter | Type | Required | Description |
|---|---|---|---|
| --map | string | optional | Comma-separated style:class pairs. Required for run mode. (e.g., "color:red:text-red") |
| --preset | string | optional | Use a built-in preset instead of --map. Available: tailwind-common |
# Discover all inline styles — no map needed
sovr-patch audit --rule inline-style --repo ./web-app
# Use tailwind-common preset for smarter classification
sovr-patch audit --rule inline-style --preset tailwind-common --repo ./web-app// Before:
<div style={{ color: "red" }}>Error</div>
<span style={{ fontSize: "14px" }}>Small text</span>
// After:
<div className="text-red">Error</div>
<span className="text-sm">Small text</span># Use built-in tailwind-common preset
sovr-patch run --rule inline-style --preset tailwind-common --repo ./web-app --apply
# Or use a custom map
sovr-patch run --rule inline-style \
--map "color:red:text-red,color:blue:text-blue" \
--repo ./web-app --applyAvailable presets:
Presets
Presets are built-in mapping tables that eliminate the need to manually specify --map arguments. They provide curated color-to-token and style-to-class mappings for common frameworks and design systems.
sovr-core
Maps 12 common hex colors to SOVR CSS custom properties. Ideal for projects adopting a SOVR-style design system.
# Audit with preset
sovr-patch audit --rule design-token --preset sovr-core --repo ./app
# Run with preset
sovr-patch run --rule design-token --preset sovr-core --repo ./app --applyIncluded mappings (12 colors):
tailwind-common
Maps 20+ common CSS inline style patterns to Tailwind CSS utility classes. Covers color, font-size, display, text-align, font-weight, and more.
# Audit with preset
sovr-patch audit --rule inline-style --preset tailwind-common --repo ./app
# Run with preset
sovr-patch run --rule inline-style --preset tailwind-common --repo ./app --applySample mappings:
Custom presets
You can always override presets with --map. When both --preset and --map are provided, the custom map takes precedence. Custom preset files are planned for a future release.
Licensing
SOVR Patch uses offline signed licenses. No license server. No phone-home. Your license is a JSON file verified locally with Ed25519 cryptography.
How it works
license.json from the confirmation pagesovr-patch activate license.json~/.sovr-patch/license.jsonPlans
| Plan | Price | Rules | Safe Apply |
|---|---|---|---|
| Free | $0 | All (dry-run only) | No |
| Pack A | $99 | field-rename, nullish-fallback | Yes |
| Pack B | $99 | design-token, inline-style | Yes |
| Full Engine | $249 | All rules | Yes |
| Enterprise | Custom | All + custom rules | Yes + CI gate |
Environment variables
| Parameter | Type | Required | Description |
|---|---|---|---|
| SOVR_LICENSE_PATH | path | optional | Override the default license file location (~/.sovr-patch/license.json) |
| SOVR_NO_UPDATE_CHECK | 0|1 | optional | Set to 1 to disable automatic update checks |
Configuration
SOVR Patch is zero-config by default. All configuration is passed via CLI flags. No config files needed.
TypeScript Configuration
SOVR Patch reads your tsconfig.json to understand your project structure. It uses the same file resolution as tsc.
# Use a specific tsconfig
sovr-patch run --rule field-rename \
--from "config.baseUrl" --to "config.apiBaseUrl" \
--tsconfig ./tsconfig.build.json \
--repo ./my-projectLicense Storage
AI Tool Integration
SOVR Patch works with AI coding tools like Cursor, Claude Code, GitHub Copilot, and Windsurf.
Cursor / Claude Code
Add SOVR Patch to your AI tool's context by including it in the project rules or system prompt:
When performing TypeScript field renames or migrations:
1. Use sovr-patch instead of manual find-and-replace
2. Run: npx sovr-patch run --rule field-rename --from "<old>" --to "<new>" --repo . --report
3. Review the output before applying
4. Apply with: npx sovr-patch run --rule field-rename --from "<old>" --to "<new>" --repo . --applyCI/CD Integration
Use the ci-gate command to block PRs that introduce migration debt:
# Store license.json as a CI secret
# Set the path in your CI environment:
export SOVR_LICENSE_PATH=/path/to/license.json
# Disable update checks in CI
export SOVR_NO_UPDATE_CHECK=1
# Run the gate
npx sovr-patch ci-gate \
--rules field-rename,nullish-fallback \
--max-hits 0Troubleshooting
Common Issues
The license.json file may have been modified after download. Re-download from your Orders page and activate again.
Licenses include 1 year of updates. After expiry, you can still use the version you have, but --apply will be locked. Purchase a renewal to continue.
Safe-apply detected type errors after patching. This means the migration would break your code. Review the tsc output, adjust your rule config, or fix the underlying type issue first.
SOVR Patch requires a TypeScript project. Ensure tsconfig.json exists at the repo root, or specify it with --tsconfig.
Some rules need specific parameters. Use sovr-patch list-rules to see required config for each rule, or check the Rules Reference above.