A feature type became shared

Use scan, plan, review, dry-run, and apply when several files now depend on it.

Move one known symbol

Use extract when the declaration and destination are already clear.

Preserve path aliases

Existing baseUrl and paths aliases are kept when they still reach the destination.

Keep simple barrels working

A simple type re-export can be updated. A riskier barrel keeps the original compatibility re-export.

Skip generated sources

Generated files are excluded by default. Include them only when the move is intentional.

Annotate risky candidates

Optional AI review adds notes to the plan without affecting deterministic rewrite logic.

Extract one symbol

extract moves one exported type or interface even when it has fewer referrers than scan would list. The symbol name comes first. --from is the file that declares it. Omit --to to use --placement-style, which defaults to collocation.

shell
pnpm exec type-tune extract OrderSummary \
  --from src/features/order/schema.ts \
  --to src/features/order/types/order.ts \
  --project tsconfig.json \
  --dry-run

The dry run writes the move, runs tsc --noEmit --project, and restores the files when that finishes normally. Repeat the command without --dry-run to keep it. The destination must be a new project-relative TypeScript source file and must differ from --from.

Path aliases and barrels

type-tune reads compilerOptions.baseUrl and compilerOptions.paths. When an existing alias still points at the new file, rewritten imports keep that alias. Otherwise the import becomes a project-relative specifier.

A named type re-export through a simple barrel can be rewritten to the new module. When that edit would be unsafe, including a mixed value re-export or a value wildcard while the source still has other code, the barrel stays unchanged and the original module keeps a type-only compatibility re-export.

That re-export lets unscanned Vue, Svelte, Astro, JavaScript, and external consumers keep importing the old path. It does not typecheck those consumers. Generated files stay out of the scan unless you pass --include-generated.