Examples use pnpm exec type-tune after pnpm add -D type-tune. After npm install -D type-tune, use npx type-tune with the same arguments. Installation and the first scan are covered in Getting started .

  1. Scan candidates.

    Inspect shared declarations, referrer counts, destinations, and omission reasons.

    shell
    pnpm exec type-tune scan --project tsconfig.json --verbose --explain
  2. Create a plan.

    These output paths are the defaults. Passing them explicitly makes the later apply command obvious.

    shell
    pnpm exec type-tune plan \
      --project tsconfig.json \
      --out .type-tune/plan.json \
      --markdown .type-tune/plan.md
  3. Review plan.md.

    Candidates start as ignore. review needs an interactive terminal and toggles each candidate between apply and ignore. You can edit the Markdown directly instead. Keep every candidate ID from the generated file.

    shell
    pnpm exec type-tune review --markdown .type-tune/plan.md
    plan.md
    - [apply] abc123def456 `OrderSummary`
      - kind: `typeAlias`
      - from: `src/features/order/schema.ts`
      - to: `src/domains/orders/types/order-summary.ts`
  4. Preview the real rewrite.
    shell
    pnpm exec type-tune apply \
      --plan .type-tune/plan.json \
      --markdown .type-tune/plan.md \
      --dry-run
  5. Apply.
    shell
    pnpm exec type-tune apply \
      --plan .type-tune/plan.json \
      --markdown .type-tune/plan.md
  6. Check the result.

    Read the Git diff, run your formatter, and run the tests or framework build that tsc --noEmit does not cover.

plan.json and plan.md

plan.json is the structured record: candidate identity, source and proposed destination, referrers, local type dependencies, import strategy, a source fingerprint, and the options that produced the plan. Treat it as input for apply. Do not edit its candidate metadata.

plan.md is the review surface. Apply reads two edits from it: the [apply] or [ignore] marker, and the to: path. Every candidate ID in plan.json must still appear exactly once, and each entry needs a to: line. Applying without Markdown requires --accept-unreviewed, which uses the statuses stored in plan.json.

Before writing files, apply scans again and rejects a stale fingerprint, a missing declaration, a duplicate candidate, or a path outside the project.

Destination rules

The default --placement-style is collocation, which proposes a types/ file beside the source. repo-types proposes the equivalent path under the repository types/ directory. Either proposal can be replaced by editing to: in plan.md.

  • The path is project-relative, uses forward slashes, and has no . or .. segments.
  • It ends in .ts, .tsx, .mts, or .cts, and it is not a declaration file.
  • It differs from the source path, and the destination file does not already exist.
  • Approved candidates from the same source file share one destination.
  • Two different declarations with the same symbol name are not written to the same destination.

What the rewrite guarantees

For approved entries, type-tune moves the declaration and its safe same-file type dependencies, updates supported type imports, and validates with tsc --noEmit --project. Relative imports, baseUrl and paths aliases, and simple barrel re-exports are updated when they can be resolved. The original module keeps a type-only compatibility re-export when that is needed to preserve an unresolved star barrel, an external package import, or a consumer the scan does not rewrite.

A normal TypeScript failure rolls the file changes back. --dry-run performs the same write and validation, then restores the files when that process finishes normally. Killing the process, or editing the same files at the same time, is outside that guarantee. If rollback itself fails, the CLI reports the failure instead of claiming the tree was restored.

Optional AI review

AI review runs only when plan --ai-review is set. It can annotate a candidate with apply, ignore, or needs-review. That note does not change source files, and apply does not call a provider.

The default context mode is snippets, which includes declaration text, local type dependencies, and relevant import lines. summary sends metadata and paths. full also sends the involved source files. Redaction covers common secret assignments only as a best effort.

shell
pnpm exec type-tune plan \
  --project tsconfig.json \
  --ai-review \
  --ai-dry-run \
  --ai-request-out .type-tune/ai-request.json

--ai-dry-run does not contact a provider. A later review with OpenAI, OpenAI-compatible, or Anthropic sends that context to the provider. Ollama defaults to a local endpoint at 127.0.0.1:11434. The built-in mock provider reads --ai-response-file and does not make a network call. Provider flags are listed under AI review options .