Skip to content

Latest commit

 

History

History
3017 lines (1854 loc) · 166 KB

File metadata and controls

3017 lines (1854 loc) · 166 KB

@effect/language-service

0.71.2

Patch Changes

  • #625 422087d Thanks @mattiamanzati! - Fix CLI patching to target emitFilesAndReportErrors function instead of emitFilesAndReportErrorsAndGetExitStatus, updating the injection approach to replace the diagnostics property in the return statement's object literal.

0.71.1

Patch Changes

  • #624 d279457 Thanks @mattiamanzati! - Add ignoreEffectSuggestionsInTscExitCode option (default: true) to control whether Effect-related suggestions affect the TSC exit code. When enabled, suggestions won't cause tsc to return a non-zero exit code.

  • #622 5eab20a Thanks @mattiamanzati! - Add ignoreEffectWarningsInTscExitCode option to allow Effect-related warnings to not affect the TSC exit code. When enabled, tsc will compile successfully even if Effect warnings are emitted. This is useful for CI/CD pipelines where Effect diagnostics should be informational rather than blocking.

0.71.0

Minor Changes

  • #619 f171350 Thanks @mattiamanzati! - Add effectSucceedWithVoid diagnostic to suggest using Effect.void instead of Effect.succeed(undefined) or Effect.succeed(void 0).

    The diagnostic detects calls to Effect.succeed where the argument is exactly undefined or void 0 (including parenthesized variants) and suggests replacing them with the more idiomatic Effect.void. A quick fix is provided to automatically apply the replacement.

    Before:

    Effect.succeed(undefined);
    Effect.succeed(void 0);

    After:

    Effect.void;

Patch Changes

  • #621 74ef937 Thanks @mattiamanzati! - Improve diagnostic messages for globalErrorInEffectFailure and globalErrorInEffectCatch to be more concise and actionable.

    Before:

    The global Error type is used in an Effect failure channel. It's not recommended to use the global Error type in Effect failures as they can get merged together. Instead, use tagged errors or custom errors with a discriminator property to get properly type-checked errors.
    

    After:

    Global 'Error' loses type safety as untagged errors merge together in the Effect failure channel. Consider using a tagged error and optionally wrapping the original in a 'cause' property.
    

0.70.0

Minor Changes

  • #618 ed689f8 Thanks @mattiamanzati! - Improve globalErrorInEffectFailure diagnostic to detect global Error type in any Effect failure channel.

    The diagnostic now works by finding new Error() expressions and checking if they end up in an Effect's failure channel, rather than only checking Effect.fail calls. This means it will now detect global Error usage in:

    • Effect.fail(new Error(...))
    • Effect.gen functions that fail with global Error
    • Effect.mapError converting to global Error
    • Effect.flatMap chains that include global Error

    The diagnostic now reports at the new Error() location for better precision.

Patch Changes

  • #616 b32da44 Thanks @mattiamanzati! - Improve missedPipeableOpportunity diagnostic message to show the suggested subject for .pipe(...).

    Before:

    Nested function calls can be converted to pipeable style for better readability.
    

    After:

    Nested function calls can be converted to pipeable style for better readability; consider using addOne(5).pipe(...) instead.
    

0.69.2

Patch Changes

  • #612 2b49181 Thanks @mattiamanzati! - Improve effectFnIife diagnostic message to suggest Effect.withSpan with the trace name when available

    When Effect.fn("traceName") is used as an IIFE, the diagnostic now suggests using Effect.gen with Effect.withSpan("traceName") piped at the end to maintain tracing spans. For Effect.fnUntraced, it simply suggests using Effect.gen without the span suggestion.

  • #615 ae4f054 Thanks @mattiamanzati! - Improve effectFnOpportunity diagnostic with more specific messages and configurable fixes

    • Add new effectFn configuration option to control which code fix variants are offered: "untraced", "span", "inferred-span", "no-span" (defaults to ["span"])
    • Diagnostic message now shows the exact expected signature for the rewrite
    • Distinguish between explicit trace from Effect.withSpan vs inferred trace from function name
    • Skip functions with return type annotations to avoid issues with recursive functions

    Before:

    This function could benefit from Effect.fn's automatic tracing...
    

    After:

    Can be rewritten as a reusable function: Effect.fn("myFunction")(function*() { ... })
    

0.69.1

Patch Changes

  • #610 990ccbc Thanks @mattiamanzati! - Improve effectFnOpportunity diagnostic message to mention that quickfixes are available in the editor or via the CLI quickfixes command.

0.69.0

Minor Changes

  • #608 bc7da1e Thanks @mattiamanzati! - Add effectFnIife diagnostic to warn when Effect.fn or Effect.fnUntraced is used as an IIFE (Immediately Invoked Function Expression).

    Effect.fn is designed to create reusable functions that can take arguments and provide tracing. When used as an IIFE, Effect.gen is more appropriate.

    Example:

    // Before (triggers warning)
    const result = Effect.fn("test")(function* () {
      yield* Effect.succeed(1);
    })();
    
    // After (using Effect.gen)
    const result = Effect.gen(function* () {
      yield* Effect.succeed(1);
    });

    A quick fix is provided to automatically convert Effect.fn IIFEs to Effect.gen.

0.68.0

Minor Changes

  • #603 d747210 Thanks @mattiamanzati! - Added instanceOfSchema diagnostic that suggests using Schema.is instead of instanceof for Effect Schema types.

    Example:

    import { Schema } from "effect"
    
    const MySchema = Schema.Struct({ name: Schema.String })
    
    // Before - triggers diagnostic
    if (value instanceof MySchema) { ... }
    
    // After - using Schema.is
    if (Schema.is(MySchema)(value)) { ... }

    The diagnostic is disabled by default and can be enabled with instanceOfSchema:suggestion or instanceOfSchema:warning.

Patch Changes

0.67.0

Minor Changes

  • #599 4c9f5c7 Thanks @mattiamanzati! - Add quickfixes CLI command that shows diagnostics with available quick fixes and their proposed code changes.

    Example usage:

    # Check a specific file
    effect-language-service quickfixes --file ./src/index.ts
    
    # Check an entire project
    effect-language-service quickfixes --project ./tsconfig.json

    The command displays each diagnostic along with the available code fixes and a diff preview of the proposed changes, making it easy to see what automatic fixes are available before applying them.

Patch Changes

  • #601 c0a6da3 Thanks @mattiamanzati! - Reduce over-suggestion of effectFnOpportunity diagnostic for regular functions.

    The diagnostic now only suggests Effect.fn for regular functions (not using Effect.gen) when:

    • The function has a block body (not a concise arrow expression)
    • The function body has more than 5 statements

    Functions using Effect.gen are still always suggested regardless of body size.

0.66.1

Patch Changes

  • #597 3833a10 Thanks @mattiamanzati! - Improved effectFnOpportunity diagnostic message to mention that Effect.fn accepts piped transformations as additional arguments when pipe transformations are detected.

    When a function has .pipe() calls that would be absorbed by Effect.fn, the message now includes: "Effect.fn also accepts the piped transformations as additional arguments."

0.66.0

Minor Changes

  • #594 0b9b37c Thanks @mattiamanzati! - Add preferSchemaOverJson diagnostic that suggests using Effect Schema for JSON operations instead of JSON.parse/JSON.stringify inside Effect contexts (Effect.try, Effect.gen, Effect.fn).

    // Before - triggers diagnostic
    const program = Effect.try(() => JSON.parse('{"name":"John"}'));
    
    const program2 = Effect.gen(function* () {
      const parsed = JSON.parse('{"name":"John"}');
      return parsed;
    });
    
    // After - use Effect Schema
    import { Schema } from "effect";
    
    const Person = Schema.Struct({ name: Schema.String });
    
    const program = Schema.decode(Person)('{"name":"John"}');
    
    const program2 = Effect.gen(function* () {
      const parsed = yield* Schema.decode(Person)('{"name":"John"}');
      return parsed;
    });
  • #593 f4d888d Thanks @mattiamanzati! - Add schemaSyncInEffect diagnostic that warns when using Schema.decodeSync, Schema.decodeUnknownSync, Schema.encodeSync, or Schema.encodeUnknownSync inside Effect generators (Effect.gen, Effect.fn, Effect.fnUntraced), suggesting the use of Effect-based alternatives (Schema.decode, Schema.decodeUnknown, Schema.encode, Schema.encodeUnknown) for properly typed ParseError in the error channel.

    // Before - triggers diagnostic
    const program = Effect.gen(function* () {
      const person = Schema.decodeSync(Person)(input);
      return person;
    });
    
    // After - use Effect-based method
    const program = Effect.gen(function* () {
      const person = yield* Schema.decode(Person)(input);
      return person;
    });

    Also adds findEnclosingScopes helper to TypeParser for reusable scope detection logic.

Patch Changes

  • #595 f54ef88 Thanks @mattiamanzati! - Tone down effectFnOpportunity diagnostic to skip suggestions when function parameters are referenced inside pipe transformations. Converting such functions to Effect.fn would break the code since parameters would no longer be in scope for the pipe arguments.

    // This no longer triggers the diagnostic because `a` and `b` are used in the pipe
    export const shouldSkip = (a: number, b: string) => {
      return Effect.gen(function* () {
        yield* Effect.succeed(a);
        return b;
      }).pipe(Effect.withSpan("withParameters", { attributes: { a, b } }));
    };
  • #588 689059d Thanks @mattiamanzati! - The effectFnOpportunity diagnostic now also supports regular functions that return an Effect, not just those using Effect.gen.

  • #596 8f00287 Thanks @mattiamanzati! - Improved missedPipeableOpportunity diagnostic to check if callees are safe to use in pipes without losing this context.

    The diagnostic now stops accumulating transformations when it encounters an unsafe callee (like method calls on class instances) and wraps the result with any remaining outer transformations.

    Safe callees include:

    • Property access on modules/namespaces (e.g., Effect.map)
    • Standalone function identifiers
    • Call expressions (already evaluated)
    • Arrow functions and function expressions

    Example - before this change, the diagnostic would incorrectly suggest:

    // Input
    console.log(Effect.runPromise(Effect.ignore(Effect.log("Hello"))));
    
    // Would produce (incorrect - loses console.log wrapper)
    Effect.log("Hello").pipe(Effect.ignore, Effect.runPromise);

    Now it correctly produces:

    // Input
    console.log(Effect.runPromise(Effect.ignore(Effect.log("Hello"))));
    
    // Output (correct - preserves console.log wrapper)
    console.log(Effect.log("Hello").pipe(Effect.ignore, Effect.runPromise));

0.65.0

Minor Changes

  • #581 4569328 Thanks @mattiamanzati! - Add effectFnOpportunity diagnostic that suggests converting functions returning Effect.gen to Effect.fn for better tracing and concise syntax.

    The diagnostic triggers on:

    • Arrow functions returning Effect.gen(...)
    • Function expressions returning Effect.gen(...)
    • Function declarations returning Effect.gen(...)
    • Functions with Effect.gen(...).pipe(...) patterns

    It provides two code fixes:

    • Convert to Effect.fn (traced) - includes the function name as the span name
    • Convert to Effect.fnUntraced - without tracing

    The diagnostic skips:

    • Generator functions (can't be converted)
    • Named function expressions (typically used for recursion)
    • Functions with multiple call signatures (overloads)

    When the original function has a return type annotation, the converted function will use Effect.fn.Return<A, E, R> as the return type.

    Example:

    // Before
    export const myFunction = (a: number) =>
      Effect.gen(function* () {
        yield* Effect.succeed(1);
        return a;
      });
    
    // After (with Effect.fn)
    export const myFunction = Effect.fn("myFunction")(function* (a: number) {
      yield* Effect.succeed(1);
      return a;
    });
    
    // Before (with pipe)
    export const withPipe = () =>
      Effect.gen(function* () {
        return yield* Effect.succeed(1);
      }).pipe(Effect.withSpan("withPipe"));
    
    // After (with Effect.fn)
    export const withPipe = Effect.fn("withPipe")(function* () {
      return yield* Effect.succeed(1);
    }, Effect.withSpan("withPipe"));
  • #575 00aeed0 Thanks @mattiamanzati! - Add effectMapVoid diagnostic that suggests using Effect.asVoid instead of Effect.map(() => void 0), Effect.map(() => undefined), or Effect.map(() => {}).

    Also adds two new TypeParser utilities:

    • lazyExpression: matches zero-argument arrow functions or function expressions that return a single expression
    • emptyFunction: matches arrow functions or function expressions with an empty block body

    And adds isVoidExpression utility to TypeScriptUtils for detecting void 0 or undefined expressions.

    Example:

    // Before
    Effect.succeed(1).pipe(Effect.map(() => void 0));
    Effect.succeed(1).pipe(Effect.map(() => undefined));
    Effect.succeed(1).pipe(Effect.map(() => {}));
    
    // After (suggested fix)
    Effect.succeed(1).pipe(Effect.asVoid);
  • #582 94d4a6b Thanks @mattiamanzati! - Added layerinfo CLI command that provides detailed information about a specific exported layer.

    Features:

    • Shows layer type, location, and description
    • Lists services the layer provides and requires
    • Suggests optimal layer composition order using Layer.provide, Layer.provideMerge, and Layer.merge

    Example usage:

    effect-language-service layerinfo --file ./src/layers/app.ts --name AppLive

    Also added a tip to both overview and layerinfo commands about using Layer.mergeAll(...) to get suggested composition order.

  • #583 b0aa78f Thanks @mattiamanzati! - Add redundantSchemaTagIdentifier diagnostic that suggests removing redundant identifier arguments when they equal the tag value in Schema.TaggedClass, Schema.TaggedError, or Schema.TaggedRequest.

    Before:

    class MyError extends Schema.TaggedError<MyError>("MyError")("MyError", {
      message: Schema.String,
    }) {}

    After applying the fix:

    class MyError extends Schema.TaggedError<MyError>()("MyError", {
      message: Schema.String,
    }) {}

    Also updates the completions to not include the redundant identifier when autocompleting Schema.TaggedClass, Schema.TaggedError, and Schema.TaggedRequest.

  • #573 6715f91 Thanks @mattiamanzati! - Rename reportSuggestionsAsWarningsInTsc option to includeSuggestionsInTsc and change default to true.

    This option controls whether diagnostics with "suggestion" severity are included in TSC output when using the effect-language-service patch feature. When enabled, suggestions are reported as messages in TSC output, which is useful for LLM-based development tools to see all suggestions.

    Breaking change: The option has been renamed and the default behavior has changed:

    • Old: reportSuggestionsAsWarningsInTsc: false (suggestions not included by default)
    • New: includeSuggestionsInTsc: true (suggestions included by default)

    To restore the previous behavior, set "includeSuggestionsInTsc": false in your tsconfig.json plugin configuration.

  • #586 e225b5f Thanks @mattiamanzati! - Add markdown documentation support to setup command

    The setup command now automatically manages Effect Language Service documentation in AGENTS.md and CLAUDE.md files:

    • When installing: Adds or updates the Effect Language Service section with markers
    • When uninstalling: Removes the section if present
    • Case-insensitive file detection (supports both lowercase and uppercase filenames)
    • Skips symlinked files to avoid modifying linked content
    • Shows proper diff view for markdown file changes

    Example section added to markdown files:

    <!-- effect-language-service:start -->
    
    ## Effect Language Service
    
    The Effect Language Service comes in with a useful CLI that can help you with commands to get a better understanding your Effect Layers and Services, and to help you compose them correctly.
    
    <!-- effect-language-service:end -->

Patch Changes

  • #580 a45606b Thanks @mattiamanzati! - Add Effect.fn and Effect.fnUntraced support to the piping flows parser.

    The piping flows parser now recognizes pipe transformations passed as additional arguments to Effect.fn, Effect.fn("traced"), and Effect.fnUntraced. This enables diagnostics like catchAllToMapError, catchUnfailableEffect, and multipleEffectProvide to work with these patterns.

    Example:

    // This will now trigger the catchAllToMapError diagnostic
    const example = Effect.fn(
      function* () {
        return yield* Effect.fail("error");
      },
      Effect.catchAll((cause) => Effect.fail(new MyError(cause)))
    );
  • #587 7316859 Thanks @mattiamanzati! - Mark deprecated TypeScript Signature methods and migrate to property accessors

    Added @deprecated annotations to TypeScript Signature interface methods (getParameters, getTypeParameters, getDeclaration, getReturnType, getTypeParameterAtPosition) with guidance to use their modern property alternatives. Updated codebase usage of getParameters() to use .parameters property instead.

  • #584 ed12861 Thanks @mattiamanzati! - Fix TypeError in setup command when updating existing diagnosticSeverity configuration

    The setup command was throwing TypeError: Cannot read properties of undefined (reading 'text') when trying to update the diagnosticSeverity option of an existing @effect/language-service plugin configuration in tsconfig.json.

    This occurred because TypeScript's ChangeTracker formatter needed to compute indentation by traversing the AST tree, which failed when replacing a PropertyAssignment node inside a nested list context.

    The fix replaces just the initializer value (ObjectLiteralExpression) instead of the entire PropertyAssignment, avoiding the problematic list indentation calculation.

  • #585 7ebe5db Thanks @mattiamanzati! - Enhanced layerinfo CLI command with output type selection for layer composition.

    New Features:

    • Added --outputs option to select which output types to include in the suggested composition (e.g., --outputs 1,2,3)
    • Shows all available output types from the layer graph with indexed checkboxes
    • By default, only types that are in the layer's declared ROut are selected
    • Composition code now includes export const <name> = ... prefix for easy copy-paste

    Example output:

    Suggested Composition:
      Not sure you got your composition right? Just write all layers inside a Layer.mergeAll(...)
      then run this command again and use --outputs to select which outputs to include in composition.
      Example: --outputs 1,2,3
    
      [ ] 1. Cache
      [x] 2. UserRepository
    
      export const simplePipeIn = UserRepository.Default.pipe(
        Layer.provide(Cache.Default)
      )
    

    This allows users to see all available outputs from a layer composition and choose which ones to include in the suggested composition order.

  • #577 0ed50c3 Thanks @mattiamanzati! - Refactor catchAllToMapError diagnostic to use the piping flows parser for detecting Effect.catchAll calls.

    This change also:

    • Makes outType optional in ParsedPipingFlowSubject to handle cases where type information is unavailable
    • Sorts piping flows by position for consistent ordering
  • #578 cab6ce8 Thanks @mattiamanzati! - refactor: use piping flows parser in catchUnfailableEffect diagnostic

  • #579 2a82522 Thanks @mattiamanzati! - refactor: use piping flows parser in multipleEffectProvide diagnostic

  • #570 0db6e28 Thanks @mattiamanzati! - Refactor CLI overview command to extract symbol collection logic into reusable utility

    • Extract collectSourceFileExportedSymbols into src/cli/utils/ExportedSymbols.ts for reuse across CLI commands
    • Add --max-symbol-depth option to overview command (default: 3) to control how deep to traverse nested symbol properties
    • Add tests for the overview command with snapshot testing
  • #574 9d0695e Thanks @mattiamanzati! - Remove deprecated ts-patch documentation from README. The Effect LSP CLI Patch is now the only recommended approach for getting diagnostics at compile time.

  • #576 5017d75 Thanks @mattiamanzati! - Add piping flows parser for caching piping flow analysis per source file.

    This internal improvement introduces a pipingFlows function in TypeParser that analyzes and caches all piping flows (both pipe() calls and .pipe() method chains) in a source file. The parser:

    • Identifies piping flows including nested pipes and mixed call styles (e.g., Effect.map(effect, fn).pipe(...))
    • Tracks the subject, transformations, and intermediate types for each flow
    • Enables more efficient diagnostic implementations by reusing cached analysis

    The missedPipeableOpportunity diagnostic has been refactored to use this new parser, improving performance when analyzing files with multiple piping patterns.

0.64.1

Patch Changes

  • #568 477271d Thanks @mattiamanzati! - Fix auto-import with namespace import packages generating malformed code when the identifier is at the beginning of the file.

    When using namespaceImportPackages configuration and auto-completing an export like isAnyKeyword from effect/SchemaAST, the code was incorrectly generated as:

    SchemaAST.import * as SchemaAST from "effect/SchemaAST";

    Instead of the expected:

    import * as SchemaAST from "effect/SchemaAST";
    
    SchemaAST.isAnyKeyword;

    The fix ensures the import statement is added before the namespace prefix when both changes target position 0.

0.64.0

Minor Changes

  • #567 dcb3fe5 Thanks @mattiamanzati! - Added new diagnostic catchAllToMapError that suggests using Effect.mapError instead of Effect.catchAll + Effect.fail when the callback only wraps the error.

    Before:

    Effect.catchAll((cause) => Effect.fail(new MyError(cause)));

    After:

    Effect.mapError((cause) => new MyError(cause));

    The diagnostic includes a quick fix that automatically transforms the code.

  • #555 0424000 Thanks @mattiamanzati! - Add globalErrorInEffectCatch diagnostic to detect global Error types in catch callbacks

    This new diagnostic warns when catch callbacks in Effect.tryPromise, Effect.try, Effect.tryMap, or Effect.tryMapPromise return the global Error type instead of typed errors.

    Using the global Error type in Effect failures is not recommended as they can get merged together, making it harder to distinguish between different error cases. Instead, it's better to use tagged errors (like Data.TaggedError) or custom errors with discriminator properties to enable proper type checking and error handling.

    Example of code that triggers the diagnostic:

    Effect.tryPromise({
      try: () => fetch("http://example.com"),
      catch: () => new Error("Request failed"), // ⚠️ Warning: returns global Error type
    });

    Recommended approach:

    class FetchError extends Data.TaggedError("FetchError")<{
      cause: unknown;
    }> {}
    
    Effect.tryPromise({
      try: () => fetch("http://example.com"),
      catch: (e) => new FetchError({ cause: e }), // ✅ Uses typed error
    });

    This diagnostic also improves the clarity message for the leakingRequirements diagnostic by adding additional guidance on how services should be collected in the layer creation body.

  • #558 cc5feb1 Thanks @mattiamanzati! - Add layerMergeAllWithDependencies diagnostic to detect interdependencies in Layer.mergeAll calls

    This new diagnostic warns when Layer.mergeAll is called with layers that have interdependencies, where one layer provides a service that another layer in the same call requires.

    Layer.mergeAll creates layers in parallel, so dependencies between layers will not be satisfied. This can lead to runtime errors when trying to use the merged layer.

    Example of code that triggers the diagnostic:

    export class DbConnection extends Effect.Service<DbConnection>()(
      "DbConnection",
      {
        succeed: {},
      }
    ) {}
    export class FileSystem extends Effect.Service<FileSystem>()("FileSystem", {
      succeed: {},
    }) {}
    export class Cache extends Effect.Service<Cache>()("Cache", {
      effect: Effect.as(FileSystem, {}), // Cache requires FileSystem
    }) {}
    
    // ⚠️ Warning on FileSystem.Default
    const layers = Layer.mergeAll(
      DbConnection.Default,
      FileSystem.Default, // This provides FileSystem
      Cache.Default // This requires FileSystem
    );

    Recommended approach:

    // Provide FileSystem separately before merging
    const layers = Layer.mergeAll(DbConnection.Default, Cache.Default).pipe(
      Layer.provideMerge(FileSystem.Default)
    );

    The diagnostic correctly handles pass-through layers (layers that both provide and require the same type) and only reports on layers that actually provide dependencies needed by other layers in the same mergeAll call.

  • #557 83ce411 Thanks @mattiamanzati! - Add missingLayerContext diagnostic to detect missing service requirements in Layer definitions

    This new diagnostic provides better error readability when you're missing service requirements in your Layer type definitions. It works similarly to the existing missingEffectContext diagnostic but specifically checks the RIn (requirements input) parameter of Layer types.

    Example of code that triggers the diagnostic:

    import * as Effect from "effect/Effect";
    import * as Layer from "effect/Layer";
    
    class ServiceA extends Effect.Service<ServiceA>()("ServiceA", {
      succeed: { a: 1 },
    }) {}
    
    class ServiceB extends Effect.Service<ServiceB>()("ServiceB", {
      succeed: { a: 2 },
    }) {}
    
    declare const layerWithServices: Layer.Layer<ServiceA, never, ServiceB>;
    
    function testFn(layer: Layer.Layer<ServiceA>) {
      return layer;
    }
    
    // ⚠️ Error: Missing 'ServiceB' in the expected Layer context.
    testFn(layerWithServices);

    The diagnostic helps catch type mismatches early by clearly indicating which service requirements are missing when passing layers between functions or composing layers together.

  • #562 57d5af2 Thanks @mattiamanzati! - Add overview CLI command that provides an overview of Effect-related exports in a project.

    The command analyzes TypeScript files and reports all exported yieldable errors, services (Context.Tag, Effect.Tag, Effect.Service), and layers with their types, file locations, and JSDoc descriptions. A progress spinner shows real-time file processing status.

    Usage:

    effect-language-service overview --file path/to/file.ts
    effect-language-service overview --project tsconfig.json

    Example output:

    ✔ Processed 3 file(s)
    Overview for 3 file(s).
    
    Yieldable Errors (1)
      NotFoundError
        ./src/errors.ts:5:1
        NotFoundError
    
    Services (2)
      DbConnection
        ./src/services/db.ts:6:1
        Manages database connections
    
    Layers (1)
      AppLive
        ./src/layers/app.ts:39:14
        Layer<Cache | UserRepository, never, never>
    

Patch Changes

  • #561 c3b3bd3 Thanks @mattiamanzati! - Add descriptions to CLI commands using Command.withDescription for improved help output when using --help flag.

  • #565 2274aef Thanks @mattiamanzati! - Fix unnecessaryPipe diagnostic and refactor not working with namespace imports from effect/Function (e.g., Function.pipe() or Fn.pipe())

  • #560 75a480e Thanks @mattiamanzati! - Improve diagnostic message for unsupportedServiceAccessors when used with Effect.Tag

    When the unsupportedServiceAccessors diagnostic is triggered on an Effect.Tag class (which doesn't allow disabling accessors), the message now includes a helpful suggestion to use Context.Tag instead:

    export class MyService extends Effect.Tag("MyService")<
      MyService,
      {
        method: <A>(value: A) => Effect.Effect<A>;
      }
    >() {}
    // Diagnostic: Even if accessors are enabled, accessors for 'method' won't be available
    // because the signature have generic type parameters or multiple call signatures.
    // Effect.Tag does not allow to disable accessors, so you may want to use Context.Tag instead.
  • #559 4c1f809 Thanks @mattiamanzati! - Improve Layer Magic refactor ordering by considering both provided and required service counts

    The Layer Magic refactor now uses a combined ordering heuristic that considers both:

    1. The number of services a layer provides
    2. The number of services a layer requires

    This results in more optimal layer composition order, especially in complex dependency graphs where layers have varying numbers of dependencies.

  • #566 036c491 Thanks @mattiamanzati! - Simplify diagnostic messages for global Error type usage

    The diagnostic messages for globalErrorInEffectCatch and globalErrorInEffectFailure now use the more generic term "tagged errors" instead of "tagged errors (Data.TaggedError)" to provide cleaner, more concise guidance.

0.63.2

Patch Changes

  • #553 e64e3df Thanks @mattiamanzati! - fix: ensure correct path resolution in CLI setup

    • Use process.cwd() explicitly in path.resolve() for consistent behavior
    • Resolve the selected tsconfig path to an absolute path before validation
    • Simplify error handling by using direct yield* for TsConfigNotFoundError

0.63.1

Patch Changes

  • #551 9b3d807 Thanks @mattiamanzati! - fix: resolve TypeScript from project's working directory

    The CLI now attempts to resolve TypeScript from the current working directory first before falling back to the package's bundled version. This ensures the CLI uses the same TypeScript version as the project being analyzed.

0.63.0

Minor Changes

  • #548 ef8c2de Thanks @mattiamanzati! - Add globalErrorInEffectFailure diagnostic

    This diagnostic warns when Effect.fail is called with the global Error type. Using the global Error type in Effect failures is not recommended as they can get merged together, making it harder to distinguish between different error types.

    Instead, the diagnostic recommends using:

    • Tagged errors with Data.TaggedError
    • Custom error classes with a discriminator property (like _tag)

    Example:

    // This will trigger a warning
    Effect.fail(new Error("global error"));
    
    // These are recommended alternatives
    Effect.fail(new CustomError()); // where CustomError extends Data.TaggedError
    Effect.fail(new MyError()); // where MyError has a _tag property
  • #545 c590b5a Thanks @mattiamanzati! - Add effect-language-service setup CLI command

    This new command provides an interactive wizard to guide users through the complete installation and configuration of the Effect Language Service. The setup command:

    • Analyzes your repository structure (package.json, tsconfig files)
    • Guides you through adding the package to devDependencies
    • Configures the TypeScript plugin in your tsconfig.json
    • Allows customizing diagnostic severity levels
    • Optionally adds prepare script for automatic patching
    • Optionally configures VS Code settings for workspace TypeScript usage
    • Shows a review of all changes before applying them

    Example usage:

    effect-language-service setup

    The wizard will walk you through each step and show you exactly what changes will be made before applying them.

  • #550 4912ee4 Thanks @mattiamanzati! - Add support for @effect/sql's Model.Class in completions and diagnostics

    • Added effectSqlModelSelfInClasses completion: Auto-completes the Self type parameter when extending Model.Class from @effect/sql
    • Extended classSelfMismatch diagnostic: Now detects when the Self type parameter in Model.Class<Self> doesn't match the actual class name

    Example:

    import { Model } from "@effect/sql";
    import * as Schema from "effect/Schema";
    
    // Completion triggers after "Model." to generate the full class boilerplate
    export class User extends Model.Class<User>("User")({
      id: Schema.String,
    }) {}
    
    // Diagnostic warns when Self type parameter doesn't match class name
    export class User extends Model.Class<WrongName>("User")({
      //                                    ^^^^^^^^^ Self type should be "User"
      id: Schema.String,
    }) {}

Patch Changes

  • #547 9058a37 Thanks @mattiamanzati! - refactor: simplify unnecessaryFailYieldableError diagnostic implementation

    Changed the implementation to check if a type extends Cause.YieldableError on-demand rather than fetching all yieldable error types upfront.

  • #549 039f4b2 Thanks @mattiamanzati! - Add getTypeAtLocation utility to TypeCheckerUtils

    This refactoring adds a new getTypeAtLocation function to TypeCheckerUtils that safely retrieves types while filtering out JSX-specific nodes (JSX elements, opening/closing tags, and JSX attributes) that could cause issues when calling typeChecker.getTypeAtLocation.

    The utility is now used across multiple diagnostics and features, reducing code duplication and ensuring consistent handling of edge cases:

    • anyUnknownInErrorContext
    • catchUnfailableEffect
    • floatingEffect
    • globalErrorInEffectFailure
    • leakingRequirements
    • missedPipeableOpportunity
    • missingEffectServiceDependency
    • missingReturnYieldStar
    • multipleEffectProvide
    • nonObjectEffectServiceType
    • overriddenSchemaConstructor
    • returnEffectInGen
    • scopeInLayerEffect
    • strictBooleanExpressions
    • strictEffectProvide
    • unnecessaryFailYieldableError
    • And other features like quick info, goto definition, and refactors

0.62.5

Patch Changes

  • #543 0b13f3c Thanks @mattiamanzati! - Fix unwanted autocompletions inside import declarations

    Previously, Effect., Option., and Either.__ completions were incorrectly suggested inside import statements. This has been fixed by detecting when the completion is requested inside an import declaration and preventing these completions from appearing.

    Closes #541

0.62.4

Patch Changes

  • #539 4cc88d2 Thanks @mattiamanzati! - Improve layerMagic refactor to prioritize layers with more provided services

    The layerMagic refactor now uses a heuristic that prioritizes nodes with more provided services when generating layer composition code. This ensures that telemetry and tracing layers (which typically provide fewer services) are positioned as late as possible in the dependency graph, resulting in more intuitive and correct layer ordering.

    Example: When composing layers for services that depend on HttpClient with telemetry, the refactor now correctly places the telemetry layer (which provides fewer services) later in the composition chain.

0.62.3

Patch Changes

  • #537 e31c03b Thanks @mattiamanzati! - Fix counter increment timing in structural type to schema refactor to ensure proper naming of conflicting schemas (e.g., User_1 instead of User_0 for the first conflict)

0.62.2

Patch Changes

  • #535 361fc1e Thanks @mattiamanzati! - Fix duplicate schema names in "Refactor to Schema (Recursive Structural)" code generation.

    When the refactor encountered types with conflicting names, it was generating a unique suffix but not properly tracking the usage count, causing duplicate schema identifiers with different contents to be generated.

    This fix ensures that when a name conflict is detected and a unique suffix is added (e.g., Tax, Tax_1, Tax_2), the usage counter is properly incremented to prevent duplicate identifiers in the generated code.

    Fixes #534

0.62.1

Patch Changes

  • #532 8f189aa Thanks @mattiamanzati! - Fix handling of read-only arrays in "Refactor to Schema (Recursive Structural)" code generation.

    The refactor now correctly distinguishes between mutable arrays (Array<T>) and read-only arrays (ReadonlyArray<T> or readonly T[]):

    • Array<T> is now converted to Schema.mutable(Schema.Array(...)) to preserve mutability
    • ReadonlyArray<T> and readonly T[] are converted to Schema.Array(...) (read-only by default)

    This fixes compatibility issues with external libraries (like Stripe, BetterAuth) that expect mutable arrays in their API parameters.

    Fixes #531

0.62.0

Minor Changes

  • #528 7dc14cf Thanks @mattiamanzati! - Add typeToSchema codegen

    This adds a new // @effect-codegens typeToSchema codegen that automatically generates Effect Schema classes from TypeScript types. Given a type alias with object members representing schemas to generate (e.g., type ToGenerate = { UserSchema: User, TodoSchema: Todo }), the codegen will create the corresponding Schema class definitions.

    The generated schemas:

    • Automatically detect and reuse existing schema definitions in the file
    • Support both type aliases and interfaces
    • Include outdated detection to warn when the source type changes
    • Work with the outdatedEffectCodegen diagnostic to provide automatic fix actions

    Example usage:

    type User = {
      id: number;
      name: string;
    };
    
    // @effect-codegens typeToSchema
    export type ToGenerate = {
      UserSchema: User;
    };
    
    // Generated by the codegen:
    export class UserSchema extends Schema.Class<UserSchema>("UserSchema")({
      id: Schema.Number,
      name: Schema.String,
    }) {}

Patch Changes

  • #530 5ecdc62 Thanks @mattiamanzati! - Fix Refactor to Schema (Recursive Structural) to support exactOptionalPropertyTypes

    When exactOptionalPropertyTypes is enabled in tsconfig, optional properties with types like string | undefined are not assignable to types defined as prop?: string. This fix generates Schema.optionalWith(Schema.String, { exact: true }) instead of Schema.optional(Schema.Union(Schema.Undefined, Schema.String)) to maintain type compatibility with external libraries that don't always include undefined in their optional property types.

    Example:

    // With exactOptionalPropertyTypes enabled
    type User = {
      name?: string; // External library type (e.g., Stripe API)
    };
    
    // Generated schema now uses:
    Schema.optionalWith(Schema.String, { exact: true });
    
    // Instead of:
    Schema.optional(Schema.Union(Schema.Undefined, Schema.String));

    This ensures the generated schema maintains proper type compatibility with external libraries when using strict TypeScript configurations.

0.61.0

Minor Changes

  • #525 e2dbbad Thanks @mattiamanzati! - Add Structural Type to Schema refactor

    Adds a new "Structural Type to Schema" refactor that converts TypeScript interfaces and type aliases to Effect Schema classes. This refactor analyzes the structure of types and generates appropriate Schema definitions, with intelligent detection and reuse of existing schemas.

    Example:

    // Before
    export interface User {
      id: number;
      name: string;
    }
    
    // After (using the refactor)
    export class User extends Schema.Class<User>("User")({
      id: Schema.Number,
      name: Schema.String,
    }) {}

    The refactor supports:

    • All primitive types and common TypeScript constructs
    • Automatic reuse of existing Schema definitions for referenced types
    • Optional properties, unions, intersections, and nested structures
    • Both interface and type alias declarations

0.60.0

Minor Changes

  • #523 46ec3e1 Thanks @mattiamanzati! - Add configurable mermaid provider option

    Adds a new mermaidProvider configuration option that allows users to choose between different Mermaid diagram providers:

    • "mermaid.com" - Uses mermaidchart.com
    • "mermaid.live" - Uses mermaid.live (default)
    • Custom URL - Allows specifying a custom provider URL (e.g., "http://localhost:8080" for local mermaid-live-editor)

    This enhances flexibility for users who prefer different Mermaid visualization services or need to use self-hosted instances.

0.59.0

Minor Changes

  • #518 660549d Thanks @mattiamanzati! - Add new schemaStructWithTag diagnostic that suggests using Schema.TaggedStruct instead of Schema.Struct when a _tag field with Schema.Literal is present. This makes the tag optional in the constructor, improving the developer experience.

    Example:

    // Before (triggers diagnostic)
    export const User = Schema.Struct({
      _tag: Schema.Literal("User"),
      name: Schema.String,
      age: Schema.Number,
    });
    
    // After (applying quick fix)
    export const User = Schema.TaggedStruct("User", {
      name: Schema.String,
      age: Schema.Number,
    });

    The diagnostic includes a quick fix that automatically converts the Schema.Struct call to Schema.TaggedStruct, extracting the tag value and removing the _tag property from the fields.

Patch Changes

  • #521 61f28ba Thanks @mattiamanzati! - Fix auto-completion for directly imported Effect APIs. Completions now work when using direct imports like import { Service } from "effect/Effect" instead of only working with fully qualified names like Effect.Service.

    This fix applies to:

    • Effect.Service and Effect.Tag from effect/Effect
    • Schema.Class, Schema.TaggedError, Schema.TaggedClass, and Schema.TaggedRequest from effect/Schema
    • Data.TaggedError and Data.TaggedClass from effect/Data
    • Context.Tag from effect/Context

    Example:

    // Now works with direct imports
    import { Service } from "effect/Effect"
    export class MyService extends Service // ✓ Completion available
    
    // Still works with fully qualified names
    import * as Effect from "effect/Effect"
    export class MyService extends Effect.Service // ✓ Completion available

    Fixes #394

0.58.4

Patch Changes

  • #515 b77b7e5 Thanks @mattiamanzati! - Fix toggle type annotation and toggle return type annotation refactors to handle unnamed/unresolved types

    The refactors now use ts.NodeBuilderFlags.IgnoreErrors flag when generating type annotations, allowing them to work correctly with types that have errors or are unnamed (e.g., Schema.Struct({ ... }).make). This prevents the refactors from failing when the type contains unresolved references or complex type expressions.

  • #514 ddabde2 Thanks @mattiamanzati! - Fix symbol resolution for aliased module exports. The TypeParser now correctly handles cases where symbols are exported from a module with an alias, improving the accuracy of type analysis for Effect modules.

0.58.3

Patch Changes

  • #512 e3dc38e Thanks @mattiamanzati! - Fix type annotation context resolution in toggle refactors. When toggling type annotations or return type annotations, the refactors now correctly use the enclosing declaration node as context instead of the local node, which improves type resolution and prevents issues with type parameter scope.

0.58.2

Patch Changes

  • #510 9064174 Thanks @mattiamanzati! - Extend anyUnknownInErrorContext diagnostic to also check Layer types

    The anyUnknownInErrorContext diagnostic now checks both Effect and Layer types for any or unknown in their error and requirements channels. This helps catch more cases where type information is being lost in your Effect applications.

    Example:

    const effectUnknown = Effect.context<unknown>();
    const layerUnknown = Layer.effectDiscard(effectUnknown);
    // Now reports: This has unknown in the requirements channel which is not recommended.

    The diagnostic also now skips explicit Layer type annotations to avoid false positives on intentional type declarations.

0.58.1

Patch Changes

  • #508 1a4446c Thanks @mattiamanzati! - Fix anyUnknownInErrorContext diagnostic to exclude JSX elements from reporting false positives. The diagnostic will no longer incorrectly flag JSX tag names, self-closing elements, opening/closing elements, and attribute names.

    Example:

    // Before: Would incorrectly report diagnostic on <MyComponent />
    const element = <MyComponent />;
    
    // After: No diagnostic, JSX elements are properly excluded
    const element = <MyComponent />;

0.58.0

Minor Changes

  • #505 31cff49 Thanks @clayroach! - Enhance diagnostics CLI command with new options for CI/CD integration and tooling:

    • --format: Output format selection (json, pretty, text, github-actions)

      • json: Machine-readable JSON output with structured diagnostics and summary
      • pretty: Colored output with context (default, original behavior)
      • text: Plain text output without colors
      • github-actions: GitHub Actions workflow commands for inline PR annotations
    • --strict: Treat warnings as errors (affects exit code)

    • --severity: Filter diagnostics by severity level (comma-separated: error, warning, message)

    • Exit codes: Returns exit code 1 when errors are found (or warnings in strict mode)

    Example usage:

    # JSON output for CI/CD pipelines
    effect-language-service diagnostics --project tsconfig.json --format json
    
    # GitHub Actions with inline annotations
    effect-language-service diagnostics --project tsconfig.json --format github-actions
    
    # Strict mode for CI (fail on warnings)
    effect-language-service diagnostics --project tsconfig.json --strict
    
    # Only show errors
    effect-language-service diagnostics --project tsconfig.json --severity error

    Closes Effect-TS/effect #5180.

0.57.1

Patch Changes

  • #503 857e43e Thanks @mattiamanzati! - Add codefix to runEffectInsideEffect diagnostic that automatically transforms Effect.run* calls to use Runtime.run* when inside nested Effect contexts. The codefix will extract or reuse an existing Effect runtime and replace the direct Effect run call with the appropriate Runtime method.

    Example:

    // Before
    Effect.gen(function* () {
      websocket.onmessage = (event) => {
        Effect.runPromise(check);
      };
    });
    
    // After applying codefix
    Effect.gen(function* () {
      const effectRuntime = yield* Effect.runtime<never>();
    
      websocket.onmessage = (event) => {
        Runtime.runPromise(effectRuntime, check);
      };
    });

0.57.0

Minor Changes

  • #500 acc2d43 Thanks @mattiamanzati! - Add new annotate codegen that automatically adds type annotations to exported constants based on their initializer types. This codegen can be used by adding // @effect-codegens annotate comments above variable declarations.

    Example:

    // @effect-codegens annotate
    export const test = Effect.gen(function* () {
      if (Math.random() < 0.5) {
        return yield* Effect.fail("error");
      }
      return 1 as const;
    });
    // Becomes:
    // @effect-codegens annotate:5fce15f7af06d924
    export const test: Effect.Effect<1, string, never> = Effect.gen(function* () {
      if (Math.random() < 0.5) {
        return yield* Effect.fail("error");
      }
      return 1 as const;
    });

    The codegen automatically detects the type from the initializer and adds the appropriate type annotation, making code more explicit and type-safe.

  • #497 b188b74 Thanks @mattiamanzati! - Add new diagnostic unnecessaryFailYieldableError that warns when using yield* Effect.fail() with yieldable error types. The diagnostic suggests yielding the error directly instead of wrapping it with Effect.fail(), as yieldable errors (like Data.TaggedError and Schema.TaggedError) can be yielded directly in Effect generators.

    Example:

    // ❌ Unnecessary Effect.fail wrapper
    yield * Effect.fail(new DataTaggedError());
    
    // ✅ Direct yield of yieldable error
    yield * new DataTaggedError();

0.56.0

Minor Changes

  • #494 9b3edf0 Thanks @mattiamanzati! - Add codegen CLI command to automatically update Effect codegens

    This release introduces a new CLI command effect-language-service codegen that allows you to automatically update Effect codegens in your TypeScript files from the command line. The command scans files containing @effect-codegens directives and applies the necessary code transformations.

    Usage:

    • effect-language-service codegen --file <path> - Update a specific file
    • effect-language-service codegen --project <tsconfig.json> - Update all files in a project
    • effect-language-service codegen --verbose - Show detailed output during processing

    Example:

    # Update a single file
    effect-language-service codegen --file src/MyService.ts
    
    # Update entire project
    effect-language-service codegen --project tsconfig.json --verbose

    This is particularly useful for CI/CD pipelines or batch processing scenarios where you want to ensure all codegens are up-to-date without manual editor intervention.

0.55.5

Patch Changes

  • #492 f2d2748 Thanks @mattiamanzati! - Fixed duplicate edges in layer outline graph that could occur when multiple type assignments matched between layer nodes

0.55.4

Patch Changes

  • #490 7d2e6dc Thanks @mattiamanzati! - Optimize getTypeAtLocation usage to reduce unnecessary calls on non-expression nodes. This improves performance by ensuring type checking is only performed on expression nodes and adds additional null safety checks for symbol resolution.

0.55.3

Patch Changes

  • #488 53eedea Thanks @mattiamanzati! - Fixed @effect-diagnostics-next-line comment directive to properly work with diagnostics on property assignments within object literals. Previously, the directive would not suppress diagnostics for properties in the middle of an object literal.

  • #486 3830d48 Thanks @mattiamanzati! - Fixed quick info feature to properly display Effect type parameters when hovering over code. This resolves issues where the quick info would fail to show Success, Failure, and Requirements types in certain contexts.

  • #489 42ce900 Thanks @mattiamanzati! - Allow to override Schema constructor as long parameters are just redirected

0.55.2

Patch Changes

  • #484 7c18fa8 Thanks @mattiamanzati! - Fix edge cases in missedPipeableOpportunity diagnostic where it incorrectly flagged valid code patterns. The diagnostic now properly:
    • Excludes pipe function calls from chain detection
    • Ignores chains where the function returns a callable type (avoiding false positives for higher-order functions like Schedule.whileOutput)

0.55.1

Patch Changes

  • #482 9695bdf Thanks @mattiamanzati! - Fix missedPipeableOpportunity diagnostic to correctly detect nested function call chains

    The diagnostic now properly identifies when nested function calls can be converted to pipeable style. Previously, the chain detection logic incorrectly tracked parent-child relationships, causing false positives. This fix ensures that only valid pipeable chains are reported, such as toString(double(addOne(5))) which can be refactored to addOne(5).pipe(double, toString).

    Example:

    // Before: incorrectly flagged or missed
    identity(Schema.decodeUnknown(MyStruct)({ x: 42, y: 42 }));
    
    // After: correctly handles complex nested calls
    toString(double(addOne(5))); // ✓ Now correctly detected as pipeable

0.55.0

Minor Changes

  • #478 9a9d5f9 Thanks @mattiamanzati! - Add runEffectInsideEffect diagnostic to warn when using Effect.runSync, Effect.runPromise, Effect.runFork, or Effect.runCallback inside an Effect context (such as Effect.gen, Effect.fn, or Effect.fnUntraced).

    Running effects inside effects is generally not recommended as it breaks the composability of the Effect system. Instead, developers should extract the Runtime and use Runtime.runSync, Runtime.runPromise, etc., or restructure their code to avoid running effects inside effects.

    Example:

    // ❌ Will trigger diagnostic
    export const program = Effect.gen(function* () {
      const data = yield* Effect.succeed(42);
      const result = Effect.runSync(Effect.sync(() => data * 2)); // Not recommended
      return result;
    });
    
    // ✅ Proper approach - extract runtime
    export const program = Effect.gen(function* () {
      const data = yield* Effect.succeed(42);
      const runtime = yield* Effect.runtime();
      const result = Runtime.runSync(runtime)(Effect.sync(() => data * 2));
      return result;
    });
    
    // ✅ Better approach - compose effects
    export const program = Effect.gen(function* () {
      const data = yield* Effect.succeed(42);
      const result = yield* Effect.sync(() => data * 2);
      return result;
    });
  • #480 f1a0ece Thanks @mattiamanzati! - Add schemaUnionOfLiterals diagnostic to warn when using Schema.Union with multiple Schema.Literal calls that can be simplified to a single Schema.Literal call.

    This diagnostic helps improve code readability and maintainability by suggesting a more concise syntax for union of literals.

    Example:

    // ❌ Will trigger diagnostic
    export const Status = Schema.Union(Schema.Literal("A"), Schema.Literal("B"));
    
    // ✅ Simplified approach
    export const Status = Schema.Literal("A", "B");

Patch Changes

  • #481 160e018 Thanks @mattiamanzati! - Update Effect ecosystem dependencies to latest versions:

    • @effect/cli: 0.71.0 → 0.72.0
    • @effect/platform: 0.92.1 → 0.93.0
    • @effect/platform-node: 0.98.3 → 0.99.0
    • @effect/printer-ansi: 0.46.0 → 0.47.0
    • @effect/rpc: 0.71.0 → 0.72.0
    • effect: Updated to stable version 3.19.0

    Also updated development tooling dependencies:

    • vitest: 3.2.4 → 4.0.6
    • @vitest/coverage-v8: 3.2.4 → 4.0.6
    • TypeScript ESLint packages: 8.46.1 → 8.46.3
    • Various other minor dependency updates

0.54.0

Minor Changes

  • #476 9d5028c Thanks @mattiamanzati! - Add unknownInEffectCatch diagnostic to warn when catch callbacks in Effect.tryPromise, Effect.tryMap, or Effect.tryMapPromise return unknown or any types. This helps ensure proper error typing by encouraging developers to wrap unknown errors into Effect's Data.TaggedError or narrow down the type to the specific error being raised.

    Example:

    // ❌ Will trigger diagnostic
    const program = Effect.tryPromise({
      try: () => fetch("http://something"),
      catch: (e) => e, // returns unknown
    });
    
    // ✅ Proper typed error
    class MyError extends Data.TaggedError("MyError")<{ cause: unknown }> {}
    
    const program = Effect.tryPromise({
      try: () => fetch("http://something"),
      catch: (e) => new MyError({ cause: e }),
    });

Patch Changes

  • #475 9f2425e Thanks @mattiamanzati! - Fix TSC patching mode to properly filter diagnostics by module name. The reportSuggestionsAsWarningsInTsc option now only affects the TSC module and not the TypeScript module, preventing suggestions from being incorrectly reported in non-TSC contexts.

0.53.3

Patch Changes

  • #473 b29eca5 Thanks @mattiamanzati! - Fix memory leak in CLI diagnostics by properly disposing language services when they change between batches.

    The CLI diagnostics command now tracks the language service instance and disposes of it when a new instance is created, preventing memory accumulation during batch processing of large codebases.

  • #474 06b9ac1 Thanks @mattiamanzati! - Fix TSC patching mode to properly enable diagnosticsName option and simplify suggestion handling.

    When using the language service in TSC patching mode, the diagnosticsName option is now automatically enabled to ensure diagnostic rule names are included in the output. Additionally, the handling of suggestion-level diagnostics has been simplified - when reportSuggestionsAsWarningsInTsc is enabled, suggestions are now converted to Message category instead of Warning category with a prefix.

    This change ensures consistent diagnostic formatting across both IDE and CLI usage modes.

  • #471 be70748 Thanks @mattiamanzati! - Improve CLI diagnostics output formatting by displaying rule names in a more readable format.

    The CLI now displays diagnostic rule names using the format effect(ruleName): instead of TS<code>:, making it easier to identify which Effect diagnostic rule triggered the error. Additionally, the CLI now disables the diagnosticsName option internally to prevent duplicate rule name display in the message text.

    Example output:

    Before: TS90001: Floating Effect detected...
    After:  effect(floatingEffect): Floating Effect detected...
    

0.53.2

Patch Changes

  • #469 f27be56 Thanks @mattiamanzati! - Add reportSuggestionsAsWarningsInTsc configuration option to allow suggestions and messages to be reported as warnings in TypeScript compiler.

    When enabled, diagnostics with "suggestion" or "message" severity will be upgraded to "warning" severity with a "[suggestion]" prefix in the message text. This is useful for CI/CD pipelines where you want to enforce suggestion-level diagnostics as warnings in the TypeScript compiler output.

    Example configuration:

    {
      "compilerOptions": {
        "plugins": [
          {
            "name": "@effect/language-service",
            "reportSuggestionsAsWarningsInTsc": true
          }
        ]
      }
    }

0.53.1

Patch Changes

  • #467 c2f6e50 Thanks @mattiamanzati! - Fix layer graph display improvements: properly render newlines in mermaid diagrams using <br/> tags, and improve readability by displaying variable declaration names instead of full expressions when available.

    Example: Instead of showing the entire pipe(Database.Default, Layer.provideMerge(UserRepository.Default)) expression in the graph node, it now displays the cleaner variable name AppLive when the layer is assigned to a variable.

0.53.0

Minor Changes

  • #466 e76e9b9 Thanks @mattiamanzati! - Add support for following symbols in Layer Graph visualization

    The layer graph feature now supports following symbol references to provide deeper visualization of layer dependencies. This is controlled by the new layerGraphFollowDepth configuration option (default: 0).

    Example:

    // With layerGraphFollowDepth: 1
    export const myLayer = otherLayer.pipe(Layer.provide(DbConnection.Default));
    // Now visualizes the full dependency tree by following the 'otherLayer' reference

Patch Changes

0.52.1

Patch Changes

0.52.0

Minor Changes

  • #460 1ac81a0 Thanks @mattiamanzati! - Add new diagnostic catchUnfailableEffect to warn when using catch functions on effects that never fail

    This diagnostic detects when catch error handling functions are applied to effects that have a never error type (meaning they cannot fail). It supports all Effect catch variants:

    • Effect.catchAll
    • Effect.catch
    • Effect.catchIf
    • Effect.catchSome
    • Effect.catchTag
    • Effect.catchTags

    Example:

    // Will trigger diagnostic
    const example = Effect.succeed(42).pipe(
      Effect.catchAll(() => Effect.void) // <- Warns here
    );
    
    // Will not trigger diagnostic
    const example2 = Effect.fail("error").pipe(
      Effect.catchAll(() => Effect.succeed(42))
    );

    The diagnostic works in both pipeable style (Effect.succeed(x).pipe(Effect.catchAll(...))) and data-first style (pipe(Effect.succeed(x), Effect.catchAll(...))), analyzing the error type at each position in the pipe chain.

  • #458 372a9a7 Thanks @mattiamanzati! - Refactor TypeParser internals to use symbol-based navigation instead of type-based navigation

    This change improves the reliability and performance of the TypeParser by switching from type-based navigation to symbol-based navigation when identifying Effect, Schema, and other Effect ecosystem APIs. The new implementation:

    • Uses TypeScript's symbol resolution APIs to accurately identify imports and references
    • Supports package name resolution to verify that identifiers actually reference the correct packages
    • Implements proper alias resolution for imported symbols
    • Adds caching for source file package information lookups
    • Provides new helper methods like isNodeReferenceToEffectModuleApi and isNodeReferenceToEffectSchemaModuleApi

    This is an internal refactoring that doesn't change the public API or functionality, but provides a more robust foundation for the language service features.

0.51.1

Patch Changes

  • #456 ddc3da8 Thanks @mattiamanzati! - Bug fix for layer graph: properly display dependencies when they reference themselves

    The layer graph now correctly identifies and displays dependencies even when using type assignment compatibility (e.g., when a layer provides a base type and another layer requires a subtype).

0.51.0

Minor Changes

  • #452 fb0ae8b Thanks @mattiamanzati! - Add strictEffectProvide diagnostic to warn when using Effect.provide with Layer outside of application entry points

    This new diagnostic helps developers identify potential scope lifetime issues by detecting when Effect.provide is called with a Layer argument in locations that are not application entry points.

    Example:

    // Will trigger diagnostic
    export const program = Effect.void.pipe(Effect.provide(MyService.Default));

    Message:

    Effect.provide with a Layer should only be used at application entry points. If this is an entry point, you can safely disable this diagnostic. Otherwise, using Effect.provide may break scope lifetimes. Compose all layers at your entry point and provide them at once.

    Configuration:

    • Default severity: "off" (opt-in)
    • Diagnostic name: strictEffectProvide

    This diagnostic is disabled by default and can be enabled via tsconfig.json:

    {
      "compilerOptions": {
        "plugins": [
          {
            "name": "@effect/language-service",
            "diagnosticSeverity": {
              "strictEffectProvide": "warning"
            }
          }
        ]
      }
    }

Patch Changes

0.50.0

Minor Changes

  • #450 3994aaf Thanks @mattiamanzati! - Add new diagnostic to detect nested function calls that can be converted to pipeable style

    The new missedPipeableOpportunity diagnostic identifies nested function calls that would be more readable when converted to Effect's pipeable style. For example:

    // Detected pattern:
    toString(double(addOne(5)));
    
    // Can be converted to:
    addOne(5).pipe(double, toString);

    This diagnostic helps maintain consistent code style and improves readability by suggesting the more idiomatic pipeable approach when multiple functions are chained together.

0.49.0

Minor Changes

Patch Changes

  • #449 ff11b7d Thanks @mattiamanzati! - Update effect package version to 97ff1dc. This version improves handling of special characters in layer graph mermaid diagrams by properly escaping HTML entities (parentheses, braces, quotes) to ensure correct rendering.

0.48.0

Minor Changes

  • #441 ed1db9e Thanks @mattiamanzati! - Add default-hashed pattern for deterministic keys

    A new default-hashed pattern option is now available for service and error key patterns. This pattern works like the default pattern but hashes the resulting string, which is useful when you want deterministic keys but are concerned about potentially exposing service names in builds.

    Example configuration:

    {
      "keyPatterns": [
        { "target": "service", "pattern": "default-hashed" },
        { "target": "error", "pattern": "default-hashed" }
      ]
    }

Patch Changes

  • #442 44f4304 Thanks @mattiamanzati! - Tone down try/catch message to ignore try/finally blocks

  • #439 b73c231 Thanks @mattiamanzati! - Fix regression in type unification for union types and prevent infinite recursion in layerMagic refactor

    • Fixed toggleTypeAnnotation refactor to properly unify boolean types instead of expanding them to true | false
    • Fixed infinite recursion issue in layerMagic refactor's adjustedNode function when processing variable and property declarations

0.47.3

Patch Changes

  • #437 e583192 Thanks @mattiamanzati! - In toggle return type refactors, skip type parameters if they are the same as the function default in some cases.

0.47.2

Patch Changes

0.47.1

Patch Changes

  • #431 acbbc55 Thanks @mattiamanzati! - Fix nested project references relative paths in CLI diagnostics command

    The CLI diagnostics command now correctly resolves paths for nested project references by:

    • Using absolute paths when parsing tsconfig files
    • Correctly resolving the base directory for relative paths in project references
    • Processing files in batches to improve memory usage and prevent leaks

0.47.0

Minor Changes

  • #429 351d7fb Thanks @mattiamanzati! - Add new diagnostics CLI command to check Effect-specific diagnostics for files or projects

    The new effect-language-service diagnostics command provides a way to get Effect-specific diagnostics through the CLI without patching your TypeScript installation. It supports:

    • --file option to get diagnostics for a specific file
    • --project option with a tsconfig file to check an entire project

    The command outputs diagnostics in the same format as the TypeScript compiler, showing errors, warnings, and messages with their locations and descriptions.

0.46.0

Minor Changes

  • #424 4bbfdb0 Thanks @mattiamanzati! - Add support to mark a service as "leakable" via JSDoc tag. Services marked with @effect-leakable-service will be excluded from the leaking requirements diagnostic, allowing requirements that are expected to be provided per method invocation (e.g. HttpServerRequest).

    Example:

    /**
     * @effect-leakable-service
     */
    export class FileSystem extends Context.Tag("FileSystem")<
      FileSystem,
      {
        writeFile: (content: string) => Effect.Effect<void>;
      }
    >() {}
  • #428 ebaa8e8 Thanks @mattiamanzati! - Add diagnostic to warn when @effect-diagnostics-next-line comments have no effect. This helps identify unused suppression comments that don't actually suppress any diagnostics, improving code cleanliness.

    The new missingDiagnosticNextLine option controls the severity of this diagnostic (default: "warning"). Set to "off" to disable.

    Example:

    // This comment will trigger a warning because it doesn't suppress any diagnostic
    // @effect-diagnostics-next-line effect/floatingEffect:off
    const x = 1;
    
    // This comment is correctly suppressing a diagnostic
    // @effect-diagnostics-next-line effect/floatingEffect:off
    Effect.succeed(1);

Patch Changes

  • #426 22717bd Thanks @mattiamanzati! - Improve Layer Magic refactor with enhanced dependency sorting and cycle detection

    The Layer Magic refactor now includes:

    • Better handling of complex layer composition scenarios
    • Support for detecting missing layer implementations with helpful error messages

0.45.1

Patch Changes

  • #423 70d8734 Thanks @mattiamanzati! - Add code fix to rewrite Schema class constructor overrides as static 'new' methods

    When detecting constructor overrides in Schema classes, the diagnostic now provides a new code fix option that automatically rewrites the constructor as a static 'new' method. This preserves the custom initialization logic while maintaining Schema's decoding behavior.

    Example:

    // Before (with constructor override)
    class MyClass extends Schema.Class<MyClass>("MyClass")({ a: Schema.Number }) {
      b: number;
      constructor() {
        super({ a: 42 });
        this.b = 56;
      }
    }
    
    // After (using static 'new' method)
    class MyClass extends Schema.Class<MyClass>("MyClass")({ a: Schema.Number }) {
      b: number;
      public static new() {
        const _this = new this({ a: 42 });
        _this.b = 56;
        return _this;
      }
    }
  • #421 8c455ed Thanks @mattiamanzati! - Update dependencies to their latest versions including Effect 3.18.4, TypeScript 5.9.3, and various ESLint and build tooling packages

0.45.0

Minor Changes

  • #419 7cd7216 Thanks @mattiamanzati! - Add support for custom APIs in deterministicKeys diagnostic using the @effect-identifier JSDoc tag.

    You can now enforce deterministic keys in custom APIs that follow an extends MyApi("identifier") pattern by:

    • Adding extendedKeyDetection: true to plugin options to enable detection
    • Marking the identifier parameter with /** @effect-identifier */ JSDoc tag

    Example:

    export function Repository(/** @effect-identifier */ identifier: string) {
      return Context.Tag("Repository/" + identifier);
    }
    
    export class UserRepo extends Repository("user-repo")<
      UserRepo,
      {
        /** ... */
      }
    >() {}

0.44.1

Patch Changes

0.44.0

Minor Changes

  • #415 42c66a1 Thanks @mattiamanzati! - Add diagnosticsName option to include rule names in diagnostic messages. When enabled (default: true), diagnostic messages will display the rule name at the end, e.g., "Effect must be yielded or assigned to a variable. effect(floatingEffect)"

0.43.2

Patch Changes

0.43.1

Patch Changes

0.43.0

Minor Changes

  • #407 6590590 Thanks @mattiamanzati! - Add deterministicKeys diagnostic to enforce consistent key patterns for Services and Errors

    This new diagnostic helps maintain consistent and unique keys for Effect Services and Tagged Errors by validating them against configurable patterns. The diagnostic is disabled by default and can be enabled via the deterministicKeys diagnosticSeverity setting.

    Two patterns are supported:

    • default: Constructs keys from package name + file path + class identifier (e.g., @effect/package/FileName/ClassIdentifier)
    • package-identifier: Uses package name + identifier for flat project structures

    Example configuration:

    {
      "diagnosticSeverity": {
        "deterministicKeys": "error"
      },
      "keyPatterns": [
        {
          "target": "service",
          "pattern": "default",
          "skipLeadingPath": ["src/"]
        }
      ]
    }

    The diagnostic also provides auto-fix code actions to update keys to match the configured patterns.

Patch Changes

  • #405 f43b3ab Thanks @mattiamanzati! - Fix wrapWithEffectGen refactor not working on class heritage clauses

    The wrapWithEffectGen refactor now correctly skips expressions in heritage clauses (e.g., extends clauses in class declarations) to avoid wrapping them inappropriately.

0.42.0

Minor Changes

  • #403 dc3f7e9 Thanks @mattiamanzati! - Add quickinfoMaximumLength option to control the maximum length of types displayed in quickinfo hover. This helps improve performance when dealing with very long types by allowing TypeScript to truncate them to a specified budget. Defaults to -1 (no truncation), but can be set to any positive number (e.g., 1000) to limit type display length.

0.41.1

Patch Changes

  • #401 394fa8d Thanks @mattiamanzati! - Add Effect.Tag completion for classes extending Effect

    When typing Effect. in a class that extends Effect, the completion now also suggests Effect.Tag alongside the existing Effect.Service completion. This provides an additional way to define tagged services using the Effect.Tag pattern.

  • #398 ae323d7 Thanks @mattiamanzati! - Refactor internal TypeScript API wrappers to TypeScriptApi module for better code organization

  • #400 6537461 Thanks @mattiamanzati! - Reuse program package json info cache if available

0.41.0

Minor Changes

  • #396 744de40 Thanks @mattiamanzati! - Add new diagnostic to warn when Effect.Service is used with a primitive type instead of an object type. This diagnostic helps prevent common mistakes where developers try to use primitive values (strings, numbers, etc.) as service types, which is not supported by Effect.Service. The diagnostic suggests wrapping the value in an object or manually using Context.Tag or Effect.Tag for primitive types.

0.40.1

Patch Changes

0.40.0

Minor Changes

  • #384 62b9829 Thanks @mattiamanzati! - Add new diagnostic: effectGenUsesAdapter - warns when using Effect.gen with the generator adapter pattern (function*(_)) instead of using pipe()

    The generator adapter pattern function*(_) is an old pattern. Users should use pipe() for composing effects or Effect.gen(function*()) without the adapter for generator-based code.

    Example that will trigger the warning:

    const example = Effect.gen(function* (_) {
      const result = yield* _(Effect.succeed(42));
      return result;
    });

Patch Changes

0.39.0

Minor Changes

0.38.4

Patch Changes

  • #378 2f9bc51 Thanks @mattiamanzati! - Add support for Effect.Tag in writeTagClassAccessors refactor

    The writeTagClassAccessors refactor now supports Effect.Tag classes in addition to Effect.Service and Context.Tag. This allows users to generate accessor methods for services created with Effect.Tag, maintaining consistency across all tag-based service patterns.

0.38.3

Patch Changes

  • #375 74696fd Thanks @mattiamanzati! - Fix resolveModulePattern to use fallback mechanism for package scope resolution when primary method is unavailable

0.38.2

Patch Changes

  • #374 9d66c1e Thanks @mattiamanzati! - Fix Mermaid graph generation for layers with generic types

    Properly escape angle brackets (< and >) in Mermaid diagrams to prevent rendering issues when displaying layer names containing generic type parameters.

  • #370 0e25fbc Thanks @mattiamanzati! - Layer Magic refactor now shows previously provided layers as a comment in the generated type annotation.

    When using the Layer Magic "Prepare for reuse" refactor, layers that were already provided at the location are now shown as a trailing comment (e.g., /* Foo | Bar */) next to the newly introduced layer types. This helps developers understand which layers were already available and which ones are being newly introduced.

  • #372 172363c Thanks @mattiamanzati! - Add general support for Effect.Tag in various diagnostics/refactors

0.38.1

Patch Changes

0.38.0

Minor Changes

  • #365 3b418c5 Thanks @mattiamanzati! - Add Layer Magic refactor for automatic layer composition and building

    This refactor allows you to automatically compose and build layers based on service dependencies. It helps simplify complex layer constructions by:

    • Analyzing service dependencies
    • Automatically composing layers in the correct order
    • Building final layer structures with proper dependency resolution

    Example: When working with services that have dependencies, the refactor can transform your layer setup code into a properly composed layer structure that respects all service requirements.

Patch Changes

0.37.0

Minor Changes

Patch Changes

  • #356 8c906e1 Thanks @mattiamanzati! - Add helper for renames, so that triggering a rename will include the identifier of a class as well

  • #360 331051d Thanks @mattiamanzati! - Some minor perf improvements

  • #358 03cfa73 Thanks @mattiamanzati! - Refactor TypeChecker utilities to improve code organization by moving utility functions from TypeCheckerApi.ts to TypeCheckerUtils.ts

  • #364 358f323 Thanks @mattiamanzati! - Replace direct .text property access with TypeScript API helper ts.idText() for getting identifier text from nodes. This is a more robust approach that properly handles escaped identifiers and follows TypeScript's recommended practices.

0.36.0

Minor Changes

Patch Changes

  • #353 790d4d0 Thanks @mattiamanzati! - Fix CLI and LSP improvements:

    • Remove deprecated check command from CLI
    • Fix unpatch command to default to both typescript and tsc modules when no modules specified
    • Add concatDiagnostics utility to prevent duplicate diagnostics in LSP
  • #351 be5d851 Thanks @mattiamanzati! - Fix TypeScript module reference in patch utility to use correct module name when patching TypeScript directly

  • #349 46a1ef2 Thanks @mattiamanzati! - Introduce ts-patch less mode

0.35.2

Patch Changes

  • #346 5a37be2 Thanks @mattiamanzati! - Fix auto-import barrel-to-barrel mapping for top-level named re-exports

    When topLevelNamedReexports is set to "follow", the auto-import provider now correctly maps barrel exports to their barrel modules, ensuring proper import suggestions for re-exported functions like pipe from effect/Function.

0.35.1

Patch Changes

  • #345 92ee0ff Thanks @mattiamanzati! - Fix async/await to Effect.gen.tryPromise and Effect.fn.tryPromise refactors to use Data.TaggedError for error handling instead of inline objects

  • #343 0570ccf Thanks @mattiamanzati! - Fix async/await to Effect.fn refactor to use correct function name

    Previously, the refactor would incorrectly use the function's own name instead of Effect.fn when transforming async functions. This patch fixes the issue to properly generate Effect.fn("functionName") in the refactored code.

0.35.0

Minor Changes

  • #339 ef70757 Thanks @mattiamanzati! - Add new refactors to transform async/await functions to Effect.fn

    • Transform an async function definition into an Effect by using Effect.fn
    • Transform an async function definition into an Effect by using Effect.fn with tagged errors for each promise call

    These refactors complement the existing Effect.gen refactors by providing an alternative transformation using Effect.fn.

Patch Changes

0.34.0

Minor Changes

  • #335 81a090a Thanks @mattiamanzati! - Add new diagnostic to warn when schema classes override the default constructor behavior

    The new diagnostic helps catch cases where schema classes define custom constructors that might break the expected schema behavior. Example:

    import { Schema } from "effect";
    
    class MySchema extends Schema.Class<MySchema>("MySchema")({
      value: Schema.String,
    }) {
      // This will trigger a warning
      constructor(props: { value: string }) {
        super(props);
      }
    }

    The diagnostic provides quickfixes to either:

    • Remove the constructor
    • Suppress the warning for the current line
    • Suppress the warning for the entire file

Patch Changes

  • #337 d72b1b4 Thanks @mattiamanzati! - Improve effectGenToFn refactor to preserve function names

    The effectGenToFn refactor now extracts and preserves the original function name when converting from Effect.gen to Effect.fn. For example:

    // Before refactor
    export const programWithPipes = (fa: number, fb: number) =>
      Eff.gen(
        function* () {
          const a = yield* Eff.succeed(fa);
          const b = yield* Eff.succeed(fb);
          return a + b;
        },
        Eff.map((a) => a + 1)
      );
    
    // After refactor (now preserves "programWithPipes" name)
    export const programWithPipes = Eff.fn("programWithPipes")(
      function* (fa: number, fb: number) {
        const a = yield* Eff.succeed(fa);
        const b = yield* Eff.succeed(fb);
        return a + b;
      },
      Eff.map((a) => a + 1)
    );

0.33.2

Patch Changes

  • #331 d862c23 Thanks @mattiamanzati! - Fix diagnostics not running for all source files in transform

    Previously, diagnostics were only running on the current file being transformed instead of all root files in the TypeScript program. This could cause some diagnostics to be missed during compilation.

    Also updated README with important notes about ts-patch limitations:

    • Effect diagnostics in watch mode with noEmit enabled are not supported
    • Incremental builds may require a full rebuild after enabling ts-patch to invalidate the previous diagnostics cache

0.33.1

Patch Changes

  • #328 e25a3f9 Thanks @mattiamanzati! - feat: add inlay hints for Effect.gen-like middleware functions

    Improved inlay hints for Effect.gen-like middleware functions to reduce visual clutter by omitting redundant type annotations that TypeScript already provides.

0.33.0

Minor Changes

  • #327 52de365 Thanks @mattiamanzati! - Add support for inlay hints in Effect.gen-like middleware functions

    This feature provides TypeScript inlay hints for generator functions used with Effect.gen, Effect.fn.gen, and Effect.fn.untraced.gen. When enabled, it shows the inferred return type directly in the editor, making it easier to understand the types without hovering over the function.

    Example:

    const myEffect = Effect.gen(function* () /* : Effect<number> */ {
      yield* Effect.succeed(42);
    });
  • #325 cbea35a Thanks @mattiamanzati! - Add quickinfoEffectParameters configuration option to control when Effect type parameters are displayed in quickinfo

    This new option allows users to configure when Effect type parameters are shown in hover information:

    • "always": Always show type parameters
    • "never": Never show type parameters
    • "whenTruncated" (default): Only show when TypeScript truncates the type display

    Example configuration:

    {
      "effectLanguageService": {
        "quickinfoEffectParameters": "whenTruncated"
      }
    }

0.32.0

Minor Changes

  • #323 b584cde Thanks @mattiamanzati! - Added support for topLevelNamedReexports configuration option to control how top-level named re-exports are handled when using namespaceImportPackages.

    • "ignore" (default): Named re-exports like import { pipe } from "effect" are left as-is
    • "follow": Named re-exports are rewritten to their original module, e.g., import { pipe } from "effect/Function"

    This allows users to have more control over their import style preferences when using namespace imports.

Patch Changes

  • #321 022956a Thanks @mattiamanzati! - Improve diagnostic message for missingReturnYieldStar to better explain why return yield* is recommended for Effects that never succeed

  • #324 8271284 Thanks @mattiamanzati! - Improve floating effect diagnostic message to specify the actual type being flagged. When detecting floating Stream or other Effect subtypes, the error message now shows "Effect-able Stream<...>" instead of just "Effect", making it clearer what type needs to be handled.

0.31.2

Patch Changes

  • #318 9928704 Thanks @mattiamanzati! - Improve missing Effect service dependency diagnostic

    • Enhanced TypeParser to better handle service dependencies detection
    • Fixed ValidService5 example in test files to properly demonstrate valid service usage
    • Updated test snapshots to reflect the corrected behavior

0.31.1

Patch Changes

0.31.0

Minor Changes

  • #312 5d4f5c6 Thanks @mattiamanzati! - Add missingEffectServiceDependency diagnostic

    This diagnostic warns when an Effect.Service declaration has missing service dependencies. It checks if all services used within the service's effect are properly declared in the dependencies array.

    Example:

    // This will show a warning because SampleService1 is used but not declared in dependencies
    export class InvalidService extends Effect.Service<InvalidService>()(
      "InvalidService",
      {
        effect: Effect.gen(function* () {
          const sampleService1 = yield* SampleService1;
          return {
            constant: Effect.succeed(sampleService1.value),
          };
        }),
        // Missing: dependencies: [SampleService1.Default]
      }
    ) {}

0.30.0

Minor Changes

  • #311 f2dc3c4 Thanks @mattiamanzati! - Add unsupportedServiceAccessors diagnostic that warns when using Effect.Service with accessors: true but methods have generics or multiple signatures

  • #309 949d5eb Thanks @mattiamanzati! - Add classSelfMismatch diagnostic rule

    This new diagnostic rule checks that the Self type parameter in Effect.Service, Context.Tag, and Schema classes matches the actual class name.

    Example:

    // ❌ Error: Self type parameter should be 'MyService'
    class MyService extends Effect.Service<WrongName>()("MyService", {
      succeed: { value: 1 },
    }) {}
    
    // ✅ Correct
    class MyService extends Effect.Service<MyService>()("MyService", {
      succeed: { value: 1 },
    }) {}

    The diagnostic includes a quick fix to automatically correct the mismatch.

0.29.0

Minor Changes

  • #306 7f3facc Thanks @mattiamanzati! - Extract TypeScript utilities into a dedicated TypeScriptUtils module

    This refactoring improves code organization by consolidating TypeScript-related utilities into a separate TypeScriptUtils module. The changes include:

    • Created new src/core/TypeScriptUtils.ts module containing all TypeScript utility functions
    • Removed the old src/core/AST.ts file which contained scattered utilities
    • Updated all imports across the codebase to use the new module structure
    • Improved type safety and consistency in TypeScript API interactions
    • Enhanced modularity by using the Nano dependency injection pattern

    This change maintains backward compatibility while providing better separation of concerns and easier maintenance of TypeScript-related functionality.

  • #308 e649978 Thanks @mattiamanzati! - Add codegen functionality including:

    • New completion provider for Effect codegens via comments
    • New diagnostic for outdated Effect codegen with quickfixes
    • Improved tag class accessors refactor with better formatting
    • Enhanced TypeScript utilities and type parsing capabilities

0.28.3

Patch Changes

  • #303 e603a89 Thanks @mattiamanzati! - Refactor AutoImport provider and add sortText support

  • #304 5885afe Thanks @mattiamanzati! - Add middleware for auto-import quickfixes

    • Extracted auto-import logic into a reusable AutoImport core module
    • Refactored existing middleware auto-import completion to use the new shared AutoImport provider
    • This enables consistent auto-import behavior across both completions and quickfixes
  • #301 d6b36f8 Thanks @mattiamanzati! - Update message for multiple Effect.provide diagnostic

0.28.2

Patch Changes

0.28.1

Patch Changes

0.28.0

Minor Changes

Patch Changes

0.27.2

Patch Changes

0.27.1

Patch Changes

0.27.0

Minor Changes

0.26.0

Minor Changes

0.25.1

Patch Changes

0.25.0

Minor Changes

Patch Changes

0.24.2

Patch Changes

0.24.1

Patch Changes

0.24.0

Minor Changes

Patch Changes

  • #257 d875f85 Thanks @mattiamanzati! - Add quickfixes to missingEffectError to implement catchAll or catchTags based on the missing errors context

0.23.5

Patch Changes

0.23.4

Patch Changes

  • #251 19dcecf Thanks @mattiamanzati! - Allow wildcard * at end of ImportPackages settings to match all packages starting with a prefix

0.23.3

Patch Changes

  • #247 b7abbdf Thanks @mattiamanzati! - Add exclusion rules for barrel style so pipe will be imported from "effect" instead of "effect/Function"

0.23.2

Patch Changes

0.23.1

Patch Changes

0.23.0

Minor Changes

0.22.3

Patch Changes

0.22.2

Patch Changes

0.22.1

Patch Changes

0.22.0

Minor Changes

Patch Changes

0.21.8

Patch Changes

0.21.7

Patch Changes

0.21.6

Patch Changes

0.21.5

Patch Changes

0.21.4

Patch Changes

0.21.3

Patch Changes

0.21.2

Patch Changes

0.21.1

Patch Changes

0.21.0

Minor Changes

Patch Changes

0.20.1

Patch Changes

0.20.0

Minor Changes

Patch Changes

0.19.0

Minor Changes

0.18.1

Patch Changes

  • #179 a170bfc Thanks @mattiamanzati! - Handle unnecessary Effect.gen even when yielded expression is not returned

    export const shouldRaiseForSingle = Effect.gen(function* () {
      yield* Effect.succeed(42);
    });
    // ^- this will become Effect.asVoid(Effect.succeed(42))
    
    export const shouldRaiseForSingleReturnVoid = Effect.gen(function* () {
      yield* Effect.void;
    });
    // ^- this will become Effect.void

0.18.0

Minor Changes

Patch Changes

0.17.1

Patch Changes

0.17.0

Minor Changes

0.16.7

Patch Changes

0.16.6

Patch Changes

0.16.5

Patch Changes

0.16.4

Patch Changes

0.16.3

Patch Changes

0.16.2

Patch Changes

0.16.1

Patch Changes

0.16.0

Minor Changes

0.15.1

Patch Changes

0.15.0

Minor Changes

0.14.0

Minor Changes

0.13.0

Minor Changes

Patch Changes

0.12.2

Patch Changes

0.12.1

Patch Changes

0.12.0

Minor Changes

0.11.0

Minor Changes

0.10.2

Patch Changes

0.10.1

Patch Changes

0.10.0

Minor Changes

0.9.2

Patch Changes

  • #109 c325568 Thanks @mattiamanzati! - Add support for completions for Data.TaggedClass and Data.TaggedError

  • #106 63cc227 Thanks @wmaurer! - Fixed a bug where certain refactors were not available when the cursor was position at the start of a node

0.9.1

Patch Changes

0.9.0

Minor Changes

0.8.1

Patch Changes

0.8.0

Minor Changes

Patch Changes

0.7.1

Patch Changes

0.7.0

Minor Changes

  • #88 c3944ce Thanks @wmaurer! - Add refactor remove-unnecessary-effect-gen. This removes unnecessary Effect.gen calls by simplifying generator functions that only wrap a single yield* statement returning an Effect. This refactor replaces the Effect.gen wrapper with the inner Effect directly, making the code more concise and readable.

0.6.2

Patch Changes

0.6.1

Patch Changes

0.6.0

Minor Changes

Patch Changes

0.5.1

Patch Changes

  • #73 3c9c1ba Thanks @mattiamanzati! - Avoid to bail-out type generation when imports are missing, show instead partial signature

0.5.0

Minor Changes

  • #71 8d309ab Thanks @mattiamanzati! - Detect unnecessary usages of Effect.gen

  • #68 79ce0b1 Thanks @mattiamanzati! - Adds support for quickinfo for effect

    They can be disabled by the LSP option "quickinfo": false.

    Once you hover a truncated type, you'll see additional information about the Effect type arguments like Success, Failure and Requirements.

Patch Changes

0.4.0

Minor Changes

Patch Changes

0.3.2

Patch Changes

0.3.1

Patch Changes

0.3.0

Minor Changes

  • #54 19e5a77 Thanks @mattiamanzati! - - Update internal version of effect from 2.x beta to 3.12.5

    • Remove adapter from gen refactors
  • #56 5b2b27c Thanks @mattiamanzati! - Add support for Effect diagnostics

    With this release of the language service plugin, we aim to improve the overall Effect experience by providing additional diagnostics that tries to fix misleading or hard to read TypeScript errors.

    All of the diagnostics provided by the language service are available only in editor-mode, that means that they won't show up when using tsc.

    Diagnostics are enabled by default, but you can opt-out of them by changing the language service configuration and provide diagnostics: false.

    {
      "plugins": [
        {
          "name": "@effect/language-service",
          "diagnostics": false
        }
      ]
    }

    Please report any false positive or missing diagnostic you encounter over the Github repository.

    Missing Errors and Services in Effects

    Additionally to the standard TypeScript error that may be cryptic at first:

    Argument of type 'Effect<number, never, ServiceB | ServiceA | ServiceC>' is not assignable to parameter of type 'Effect<number, never, ServiceB | ServiceA>' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the types of the target's properties.
      Type 'ServiceB | ServiceA | ServiceC' is not assignable to type 'ServiceB | ServiceA'.
        Type 'ServiceC' is not assignable to type 'ServiceB | ServiceA'.
          Type 'ServiceC' is not assignable to type 'ServiceA'.
            Types of property 'a' are incompatible.
              Type '3' is not assignable to type '1'.ts(2379)
    

    you'll now receive an additional error:

    Missing 'ServiceC' in the expected Effect context.
    

    Floating Effect

    In some situation you may not receive any compile error at all, but that's because you may have forgot to yield your effects inside gen!

    Floating Effects that are not assigned to a variable will be reported into the Effect diagnostics.

    Effect.runPromise(
      Effect.gen(function* () {
        Effect.sync(() => console.log("Hello!"));
        // ^- Effect must be yielded or assigned to a variable.
      })
    );

    Used yield instead of yield*

    Similarly, yield instead of yield* won't result in a type error by itself, but is not the intended usage.

    This yield will be reported in the effect diagnostics.

    Effect.runPromise(
      Effect.gen(function* () {
        yield Effect.sync(() => console.log("Hello!"));
        // ^- When yielding Effects inside Effect.gen, you should use yield* instead of yield.
      })
    );

0.2.0

Minor Changes

0.1.0

Minor Changes

  • #48 9bb0011 Thanks @wmaurer! - Improve Effect imports to work with current effect npm package

  • #48 9bb0011 Thanks @wmaurer! - Modernise build setup. Fix asyncWaitToGen problem for TS5. Refactor asyncWaitToGen to work with current Effect API. Add config option preferredEffectGenAdapterName.

0.0.21

Patch Changes

0.0.20

Patch Changes

0.0.19

Patch Changes

0.0.18

Patch Changes

0.0.17

Patch Changes

0.0.16

Patch Changes

0.0.15

Patch Changes

0.0.14

Patch Changes

0.0.13

Patch Changes

0.0.12

Patch Changes

0.0.11

Patch Changes

0.0.10

Patch Changes

0.0.9

Patch Changes

0.0.8

Patch Changes

0.0.7

Patch Changes

0.0.6

Patch Changes

0.0.5

Patch Changes

0.0.4

Patch Changes

0.0.3

Patch Changes

0.0.2

Patch Changes

0.0.1

Patch Changes

  • #2 8915f80 Thanks @mattiamanzati! - Fixed type annotation removal in both toggle return type and toggle type annotation