Skip to content

feat: optional @effect/language-service integration for type-based diagnostics #38

Description

@aridyckovsky

Summary

Add optional integration with @effect/language-service to provide type-based diagnostics alongside our existing regex-based pattern detection.

Context

Currently, effect-migrate uses fast regex patterns to detect legacy code (async/await, Promise, etc.). The Effect team's @effect/language-service provides more accurate type-based diagnostics (floating Effects, missing error types) using TypeScript's type checker.

Research findings:

  • Language-service can run programmatically via createProjectService (not just VS Code)
  • Provides 36+ diagnostic rules with structured output (ts.Diagnostic[])
  • Uses lightweight Nano runtime (Effect-like, but synchronous)
  • CLI command proves standalone usage: diagnostics.ts

Key distinction:

  • effect-migrate: Pre-migration detection ("what to migrate")
  • language-service: Post-migration correctness ("using Effect correctly")
  • Together: Comprehensive guidance

Proposed Design

Two-tier detection system:

  1. Fast regex patterns (default): Detect legacy patterns
  2. Type-based checks (opt-in): Deep semantic analysis

Architecture decisions:

  • Optional: Default disabled, requires typeChecks.enabled: true
  • Lazy load: Dynamic import only when enabled
  • Merged output: Results use ls/ prefix (e.g., ls/floatingEffect)
  • Dedupe: preferTypeOverPattern removes regex duplicates
  • Minimal deps: Make language-service optional peer dependency

Configuration schema:

// In effect-migrate.config.ts
export default {
  typeChecks: {
    enabled: true,  // Opt-in
    tsconfig: "./tsconfig.json",  // Auto-detect if omitted
    diagnostics: ["floatingEffect", "missingEffectError"],
    severity: { floatingEffect: "error", missingEffectError: "warning" },
    preferTypeOverPattern: true  // Dedupe conflicts
  }
}

Example output:

$ effect-migrate audit --amp-out .amp/effect-migrate
✓ Found 15 async/await patterns (regex)
✓ Found 3 floating Effects (type-based)
✓ Generated .amp/effect-migrate/index.json

Implementation Tasks

  • Add TypeChecksSchema to packages/core/src/schema/Config.ts
  • Make @effect/language-service and typescript optional peer deps in CLI
  • Create packages/cli/src/typechecks/collector.ts with dynamic import
  • Wire type-check results into audit command (merge with ls/ prefix)
  • Add deduplication logic (preferTypeOverPattern)
  • Update README and config documentation
  • Add tests with real diagnostics
  • Update AGENTS.md with integration notes

Benefits

  1. Better migration guidance: Combine syntax patterns + semantic analysis
  2. Incremental adoption: Start with patterns, add type checks later
  3. Amp-friendly: Unified results in .amp/effect-migrate/audit.json
  4. Performance: Opt-in keeps default fast path
  5. Future-proof: Leverage Effect team's diagnostic evolution

References

Out of Scope (for now)

  • Multi-tsconfig/monorepo support (simple path: one tsconfig)
  • Watch mode / incremental caching
  • Automatic code fix application (diagnostics include fixes, but won't apply them yet)
  • Promoting to first-class Rule in RuleRunner (simpler to keep separate initially)

Risks & Mitigations

Risk: Heavy TypeScript compiler startup cost
Mitigation: Opt-in, lazy import, single project service per run

Risk: Version mismatches (TS / language-service)
Mitigation: Optional peers with runtime validation + clear error messages

Risk: Duplicate/noisy findings
Mitigation: ls/ prefix, preferTypeOverPattern dedupe, severity overrides

Risk: Monorepo complexity
Mitigation: Document single-tsconfig limitation, allow explicit path

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    amp:threadsThread URL tracking and threads.json managementeffect-tsEffect-TS patterns and usagepkg:cliIssues related to @effect-migrate/cli packagepkg:coreIssues related to @effect-migrate/core packagetype:featureNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions