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:
- Fast regex patterns (default): Detect legacy patterns
- 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
Benefits
- Better migration guidance: Combine syntax patterns + semantic analysis
- Incremental adoption: Start with patterns, add type checks later
- Amp-friendly: Unified results in
.amp/effect-migrate/audit.json
- Performance: Opt-in keeps default fast path
- 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
Summary
Add optional integration with
@effect/language-serviceto provide type-based diagnostics alongside our existing regex-based pattern detection.Context
Currently,
effect-migrateuses fast regex patterns to detect legacy code (async/await, Promise, etc.). The Effect team's@effect/language-serviceprovides more accurate type-based diagnostics (floating Effects, missing error types) using TypeScript's type checker.Research findings:
createProjectService(not just VS Code)ts.Diagnostic[])Key distinction:
Proposed Design
Two-tier detection system:
Architecture decisions:
typeChecks.enabled: truels/prefix (e.g.,ls/floatingEffect)preferTypeOverPatternremoves regex duplicatesConfiguration schema:
Example output:
Implementation Tasks
TypeChecksSchematopackages/core/src/schema/Config.ts@effect/language-serviceandtypescriptoptional peer deps in CLIpackages/cli/src/typechecks/collector.tswith dynamic importls/prefix)preferTypeOverPattern)Benefits
.amp/effect-migrate/audit.jsonReferences
Out of Scope (for now)
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,preferTypeOverPatterndedupe, severity overridesRisk: Monorepo complexity
Mitigation: Document single-tsconfig limitation, allow explicit path