{"version":3,"sources":["../src/rules-entry.ts","../src/register-node-ts-morph.ts","../src/ts-morph-loader.ts","../src/analyze.ts","../src/types.ts","../src/static-analyzer.ts","../src/analysis-utils.ts","../src/type-extractor.ts","../src/analysis-patterns.ts","../src/path-utils.ts","../src/alias-resolution.ts","../src/program-discovery.ts","../src/core-analysis.ts","../src/effect-analysis.ts","../src/callback-summary.ts","../src/layer-initializer-resolution.ts","../src/service-type-heuristics.ts","../src/analysis-context.ts","../src/stream-channel-sink-analyzers.ts","../src/analysis-classifiers.ts","../src/retry-timeout-analyzers.ts","../src/concurrency-fiber-analyzers.ts","../src/parallel-race-analyzers.ts","../src/error-handler-analyzer.ts","../src/resource-analyzer.ts","../src/control-flow-analyzers.ts","../src/strict-diagnostics.ts","../src/layer-graph.ts","../src/effect-linter.ts","../src/lint-rules-extra.ts","../src/source-linter-docs.ts","../src/source-linter.ts","../src/lint-session.ts","../src/rule-registry.ts","../src/tsgo-diagnostics.ts","../src/ir.ts","../src/fidelity-findings.ts","../src/diagram-fidelity.ts","../src/error-channel.ts","../src/service-health.ts","../src/performance-antipatterns.ts"],"sourcesContent":["/** Diagnostics and lint interface for Effect v4. */\n\nexport { analyze } from './analyze';\nexport * from './strict-diagnostics';\nexport * from './effect-linter';\nexport * from './source-linter';\nexport * from './lint-session';\nexport * from './rule-registry';\nexport * from './diagram-fidelity';\nexport * from './error-channel';\nexport * from './service-health';\nexport * from './performance-antipatterns';\n","import { createRequire } from 'node:module';\nimport { setTsMorphLoader } from './ts-morph-loader';\n\n/** Current module location in both ESM and bundled CommonJS builds. */\nexport const nodeModuleLocation =\n  typeof __filename === 'string' ? __filename : import.meta.url;\n\nsetTsMorphLoader(() => {\n  const require = createRequire(nodeModuleLocation);\n  return require('ts-morph') as typeof import('ts-morph');\n});\n","/**\n * Runtime-configurable ts-morph loader.\n *\n * Node uses a lazy builtin-module fallback so browser bundles do not pull in\n * `node:module` at build time. Browser consumers must explicitly provide a\n * ts-morph-compatible module before calling source analysis APIs.\n */\n\nimport type { Project, SourceFile } from 'ts-morph';\n\ntype TsMorphModule = typeof import('ts-morph');\ntype TsMorphLoader = () => TsMorphModule;\n\nlet tsMorphModule: TsMorphModule | null = null;\nlet tsMorphLoader: TsMorphLoader | null = null;\nconst projectCache = new Map<string, Project>();\n\ninterface BuiltinAwareProcess {\n  readonly getBuiltinModule?: (id: string) => unknown;\n}\n\nconst getBuiltinModule = (id: string): unknown => {\n  const maybeProcess = (globalThis as { process?: BuiltinAwareProcess }).process;\n  return maybeProcess?.getBuiltinModule?.(id);\n};\n\nconst loadNodeTsMorph = (): TsMorphModule | null => {\n  const moduleBuiltin =\n    getBuiltinModule('node:module') ?? getBuiltinModule('module');\n  const createRequire =\n    moduleBuiltin &&\n    typeof moduleBuiltin === 'object' &&\n    'createRequire' in moduleBuiltin\n      ? (moduleBuiltin.createRequire as (url: string) => NodeJS.Require)\n      : undefined;\n\n  if (!createRequire) {\n    return null;\n  }\n\n  try {\n    const require = createRequire(import.meta.url);\n    return require('ts-morph') as TsMorphModule;\n  } catch {\n    return null;\n  }\n};\n\nexport const setTsMorphModule = (module: TsMorphModule): void => {\n  tsMorphModule = module;\n};\n\nexport const setTsMorphLoader = (loader: TsMorphLoader): void => {\n  tsMorphLoader = loader;\n  tsMorphModule = null;\n};\n\nexport const resetTsMorphRuntime = (): void => {\n  tsMorphModule = null;\n  tsMorphLoader = null;\n  projectCache.clear();\n};\n\nexport const loadTsMorph = (): TsMorphModule => {\n  if (tsMorphModule) {\n    return tsMorphModule;\n  }\n\n  const configuredModule =\n    tsMorphLoader?.() ?? loadNodeTsMorph();\n\n  if (!configuredModule) {\n    throw new Error(\n      'ts-morph is not configured. In Node, install ts-morph as a dependency. In browser builds, call setTsMorphModule() or setTsMorphLoader() before analysis.',\n    );\n  }\n\n  tsMorphModule = configuredModule;\n  return configuredModule;\n};\n\nexport const createProject = (tsConfigPath?: string): Project => {\n  const cacheKey = tsConfigPath ?? '__default__';\n  const cached = projectCache.get(cacheKey);\n  if (cached) {\n    return cached;\n  }\n\n  const { Project } = loadTsMorph();\n  const options: { tsConfigFilePath?: string } = {};\n  if (tsConfigPath) {\n    options.tsConfigFilePath = tsConfigPath;\n  }\n  const project = new Project(options);\n  projectCache.set(cacheKey, project);\n  return project;\n};\n\nexport const clearProjectCache = (): void => {\n  projectCache.clear();\n};\n\nexport const createProjectFromSource = (\n  code: string,\n  filePath = 'temp.ts',\n): SourceFile => {\n  const { Project } = loadTsMorph();\n  const project = new Project({\n    useInMemoryFileSystem: true,\n    compilerOptions: {\n      strict: true,\n      esModuleInterop: true,\n    },\n  });\n  return project.createSourceFile(filePath, code);\n};\n","/**\n * Fluent Builder API for Static Effect Analysis\n *\n * Provides an ergonomic API for analyzing Effect files with explicit intent.\n * Built entirely with Effect for composability.\n *\n * @known-hub Library API entry point — imported by all consumers\n *\n * @example\n * ```typescript\n * import { Effect } from \"effect\";\n * import { analyze } from \"effect-analyzer/analysis\";\n *\n * // Single program file\n * const ir = await Effect.runPromise(analyze(\"./program.ts\").single);\n *\n * // Multi-program file\n * const programs = await Effect.runPromise(analyze(\"./programs.ts\").all);\n *\n * // Get specific program by name\n * const program = await Effect.runPromise(analyze(\"./programs.ts\").named(\"myProgram\"));\n *\n * // From source string\n * const ir = await Effect.runPromise(analyze.source(code).single);\n * ```\n */\n\nimport './register-node-ts-morph';\nimport { Effect, Option } from 'effect';\nimport { AnalysisError } from './types';\nimport type { StaticEffectIR, AnalyzerOptions } from './types';\nimport {\n  analyzeEffectFile,\n  analyzeEffectSource,\n  resetIdCounter,\n} from './static-analyzer';\n\n/**\n * Result object from analyze() with fluent methods to retrieve programs.\n */\nexport interface AnalyzeResult {\n  /**\n   * Get single program. Fails if file has 0 or >1 programs.\n   */\n  readonly single: Effect.Effect<StaticEffectIR, AnalysisError>;\n\n  /**\n   * Get single program or None if not exactly one.\n   */\n  readonly singleOption: Effect.Effect<\n    Option.Option<StaticEffectIR>\n  >;\n\n  /**\n   * Get all programs as array.\n   */\n  readonly all: Effect.Effect<\n    readonly StaticEffectIR[],\n    AnalysisError\n  >;\n\n  /**\n   * Get program by name. Fails if not found.\n   */\n  readonly named: (\n    name: string,\n  ) => Effect.Effect<StaticEffectIR, AnalysisError>;\n\n  /**\n   * Get first program. Fails if empty.\n   */\n  readonly first: Effect.Effect<StaticEffectIR, AnalysisError>;\n\n  /**\n   * Get first program or None if empty.\n   */\n  readonly firstOption: Effect.Effect<\n    Option.Option<StaticEffectIR>\n  >;\n}\n\nconst createResult = (\n  programs: readonly StaticEffectIR[],\n): AnalyzeResult => ({\n  single: Effect.gen(function* () {\n      if (programs.length === 1) {\n        const program = programs[0];\n        if (program) {\n          return program;\n        }\n      }\n      return yield* Effect.fail(\n        new AnalysisError(\n          'NOT_SINGLE_PROGRAM',\n          `Expected exactly 1 program, found ${String(programs.length)}: ` +\n            `${programs.map((p) => p.root.programName).join(', ')}. ` +\n            'Use .named(name) to pick one, or .all for every program.',\n        ),\n      );\n    }),\n\n  singleOption: Effect.gen(function* () {\n      if (programs.length === 1) {\n        const program = programs[0];\n        if (program) {\n          return Option.some(program);\n        }\n      }\n      return Option.none<StaticEffectIR>();\n    }),\n\n  all: Effect.succeed(programs),\n\n  named: (name: string) =>\n    Effect.gen(function* () {\n      const found = programs.find((p) => p.root.programName === name);\n      if (!found) {\n        const available = programs.map((p) => p.root.programName).join(', ');\n        return yield* Effect.fail(\n          new AnalysisError(\n            'PROGRAM_NOT_FOUND',\n            `Program \"${name}\" not found. Available: ${available || '(none)'}`,\n          ),\n        );\n      }\n      return found;\n    }),\n\n  first: Effect.gen(function* () {\n      const program = programs[0];\n      if (program) {\n        return program;\n      }\n      return yield* Effect.fail(\n        new AnalysisError('NO_PROGRAMS', 'No programs found'),\n      );\n    }),\n\n  firstOption: Effect.gen(function* () {\n      const program = programs[0];\n      if (program) {\n        return Option.some(program);\n      }\n      return Option.none<StaticEffectIR>();\n    }),\n});\n\n/**\n * Analyze an Effect file and return a fluent result object.\n *\n * @param filePath - Path to the TypeScript file containing the Effect program(s)\n * @param options - Analysis options\n * @returns Fluent result object with methods to retrieve programs\n *\n * @example\n * ```typescript\n * // Single program file\n * const ir = await Effect.runPromise(analyze(\"./program.ts\").single);\n *\n * // Multiple programs - get all as array\n * const programs = await Effect.runPromise(analyze(\"./programs.ts\").all);\n *\n * // Get specific program by name\n * const program = await Effect.runPromise(analyze(\"./programs.ts\").named(\"myProgram\"));\n * ```\n */\nexport const analyze = (\n  filePath: string,\n  options?: AnalyzerOptions,\n): AnalyzeResult => {\n  // Reset ID counter for deterministic results\n  resetIdCounter();\n\n  // Lazily evaluate the analysis\n  const programsEffect = analyzeEffectFile(filePath, options);\n\n  return {\n    single: Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).single;\n      }),\n\n    singleOption: Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).singleOption;\n      }).pipe(Effect.orDie),\n\n    all: programsEffect,\n\n    named: (name: string) =>\n      Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).named(name);\n      }),\n\n    first: Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).first;\n      }),\n\n    firstOption: Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).firstOption;\n      }).pipe(Effect.orDie),\n  };\n};\n\n/**\n * Analyze Effect source code directly (for testing or dynamic analysis).\n *\n * @param code - TypeScript source code containing the Effect program(s)\n * @param options - Analysis options\n * @returns Fluent result object with methods to retrieve programs\n *\n * @example\n * ```typescript\n * const source = `\n *   const program = Effect.gen(function* () {\n *     yield* Effect.log(\"Hello\");\n *     return 42;\n *   });\n * `;\n *\n * const ir = await Effect.runPromise(analyze.source(source).single);\n * ```\n */\nanalyze.source = (code: string, options?: AnalyzerOptions): AnalyzeResult => {\n  resetIdCounter();\n\n  const programsEffect = analyzeEffectSource(code, 'temp.ts', options);\n\n  return {\n    single: Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).single;\n      }),\n\n    singleOption: Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).singleOption;\n      }).pipe(Effect.orDie),\n\n    all: programsEffect,\n\n    named: (name: string) =>\n      Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).named(name);\n      }),\n\n    first: Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).first;\n      }),\n\n    firstOption: Effect.gen(function* () {\n        const programs = yield* programsEffect;\n        return yield* createResult(programs).firstOption;\n      }).pipe(Effect.orDie),\n  };\n};\n","/**\n * Static Effect Analysis - Type Definitions\n *\n * These types represent Effect code structure extracted through static analysis\n * (AST walking) rather than runtime execution.\n *\n * @known-hub Central IR type definitions imported by every analyzer\n */\n\nimport { Effect, Option } from 'effect';\n\n// =============================================================================\n// Static Node Types\n// =============================================================================\n\n/**\n * Source code location for tracing back to original code.\n */\nexport interface SourceLocation {\n  /** Absolute file path */\n  readonly filePath: string;\n  /** Line number (1-indexed) */\n  readonly line: number;\n  /** Column number (0-indexed) */\n  readonly column: number;\n  /** End line number */\n  readonly endLine?: number | undefined;\n  /** End column number */\n  readonly endColumn?: number | undefined;\n  /** Character offset from start of file (0-indexed) */\n  readonly offset?: number | undefined;\n  /** Character end offset from start of file (0-indexed) */\n  readonly endOffset?: number | undefined;\n}\n\n/**\n * Semantic role classification for display and styling.\n */\nexport type SemanticRole =\n  | 'constructor'\n  | 'service-call'\n  | 'environment'\n  | 'side-effect'\n  | 'transform'\n  | 'error-handler'\n  | 'concurrency'\n  | 'resource'\n  | 'control-flow'\n  | 'scheduling'\n  | 'stream'\n  | 'layer'\n  | 'fiber'\n  | 'unknown';\n\n/**\n * Structured JSDoc tag data extracted from comments.\n */\nexport interface JSDocTags {\n  readonly params: readonly { readonly name: string; readonly description?: string }[];\n  readonly returns?: string | undefined;\n  readonly throws: readonly string[];\n  readonly example?: string | undefined;\n}\n\n/**\n * Detail level for Mermaid diagram labels.\n */\nexport type MermaidDetailLevel = 'compact' | 'standard' | 'verbose';\n\n/**\n * Base properties shared by all static analysis nodes.\n */\nexport interface StaticBaseNode {\n  /** Unique identifier for this node */\n  readonly id: string;\n  /** Human-readable name */\n  readonly name?: string | undefined;\n  /** Source location */\n  readonly location?: SourceLocation | undefined;\n  /** Pre-computed human-readable display label (e.g. \"user <- UserRepo.getById\") */\n  readonly displayName?: string | undefined;\n  /** Semantic role classification for styling and filtering */\n  readonly semanticRole?: SemanticRole | undefined;\n  /** Span name from Effect.withSpan annotation */\n  readonly spanName?: string | undefined;\n  /** Runtime nesting order for multiple Effect.withSpan transformations. */\n  readonly spanNames?: readonly string[] | undefined;\n  /** True when a span name is computed and cannot be joined statically. */\n  readonly spanNameDynamic?: boolean | undefined;\n}\n\n/**\n * A single Effect operation (yield* or direct call).\n */\nexport interface StaticEffectNode extends StaticBaseNode {\n  readonly type: 'effect';\n  /** The Effect being created (e.g., \"Effect.succeed\", \"Effect.sync\") */\n  readonly callee: string;\n  /** Description of what this effect does */\n  readonly description?: string | undefined;\n  /** JSDoc description extracted from comments above the effect */\n  readonly jsdocDescription?: string | undefined;\n  /** Structured JSDoc tags extracted from comments */\n  readonly jsdocTags?: JSDocTags | undefined;\n  /** Error type if statically determinable */\n  readonly errorType?: string | undefined;\n  /** Full type signature (A, E, R) - requires type extraction */\n  readonly typeSignature?: EffectTypeSignature | undefined;\n  /** Services required by this specific effect */\n  readonly requiredServices?: ServiceRequirement[] | undefined;\n  /** If this effect is a method call on a typed service object */\n  readonly serviceCall?: {\n    /** Resolved type name of the service object (e.g. 'UserRepo') */\n    readonly serviceType: string;\n    /** Method name being called (e.g. 'getById') */\n    readonly methodName: string;\n    /** Variable/expression name used at call site (e.g. 'repo') */\n    readonly objectName: string;\n  } | undefined;\n  /** Resolved service method when call is e.g. yield* db.query() and db is bound to a service tag */\n  readonly serviceMethod?: { readonly serviceId: string; readonly methodName: string } | undefined;\n  /** Service wrapper callback pattern like `fileClient.use((client) => ...)` */\n  readonly usePattern?: {\n    readonly wrapperName: string;\n    readonly callbackKind: 'promise' | 'effect' | 'unknown';\n  } | undefined;\n  /** Inner effects from Effect.sync/promise/async callback body (one level only) */\n  readonly callbackBody?: readonly StaticFlowNode[] | undefined;\n  /** Callback-style constructors: resume/canceller patterns for Effect.callback/asyncEffect/callback. */\n  readonly asyncCallback?: {\n    readonly resumeParamName: string;\n    readonly resumeCallCount: number;\n    readonly returnsCanceller: boolean;\n  } | undefined;\n  /** Effect.provide only: whether context is provided via Layer, Context, or Runtime. */\n  readonly provideKind?: 'layer' | 'context' | 'runtime' | undefined;\n  /** Constructor subtype classification */\n  readonly constructorKind?: 'sync' | 'promise' | 'async' | 'callback' | 'never' | 'void' | 'fromNullable' | 'fn' | 'fnUntraced' | undefined;\n  /** FiberRef built-in name (e.g. currentLogLevel, currentConcurrency) */\n  readonly fiberRefName?: string | undefined;\n  /** Effect.fn traced name */\n  readonly tracedName?: string | undefined;\n}\n\n/**\n * Generator-based effect block (Effect.gen).\n */\nexport interface StaticGeneratorNode extends StaticBaseNode {\n  readonly type: 'generator';\n  /** Variables yielded in the generator */\n  readonly yields: {\n    readonly variableName?: string | undefined;\n    readonly effect: StaticFlowNode;\n  }[];\n  /** Final return value */\n  readonly returnNode?: StaticFlowNode | undefined;\n  /** JSDoc description extracted from comments above the generator function */\n  readonly jsdocDescription?: string | undefined;\n  /** Structured JSDoc tags extracted from comments */\n  readonly jsdocTags?: JSDocTags | undefined;\n}\n\n/**\n * Pipe composition chain (effect.pipe(...)).\n */\nexport interface StaticPipeNode extends StaticBaseNode {\n  readonly type: 'pipe';\n  /** The initial effect */\n  readonly initial: StaticFlowNode;\n  /** Pipe transformations in order */\n  readonly transformations: readonly StaticFlowNode[];\n  /** Type flow through the pipe chain (A, E, R at each step) */\n  readonly typeFlow?: readonly EffectTypeSignature[] | undefined;\n}\n\n/**\n * Concurrency mode for Effect.all / Effect.allWith.\n */\nexport type ConcurrencyMode = 'sequential' | 'bounded' | 'unbounded' | number;\n\n/**\n * Parallel execution (Effect.all, Effect.allPar).\n */\nexport interface StaticParallelNode extends StaticBaseNode {\n  readonly type: 'parallel';\n  /** Child effects running in parallel */\n  readonly children: readonly StaticFlowNode[];\n  /** Mode: sequential (all) or parallel (allPar) */\n  readonly mode: 'sequential' | 'parallel';\n  /** The callee (e.g., \"Effect.all\", \"Effect.allPar\") */\n  readonly callee: string;\n  /** Resolved concurrency: from options or inferred from mode (GAP 18) */\n  readonly concurrency?: ConcurrencyMode | undefined;\n  /** Request batching enabled (Effect.all with { batching: true }) */\n  readonly batching?: boolean | undefined;\n  /** Results discarded (Effect.all with { discard: true }) */\n  readonly discard?: boolean | undefined;\n  /** Labels for each parallel branch (from child displayNames) */\n  readonly branchLabels?: readonly string[] | undefined;\n}\n\n/**\n * Race execution (Effect.race, Effect.raceAll).\n */\nexport interface StaticRaceNode extends StaticBaseNode {\n  readonly type: 'race';\n  /** Child effects racing */\n  readonly children: readonly StaticFlowNode[];\n  /** The callee */\n  readonly callee: string;\n  /** Labels for each race competitor */\n  readonly raceLabels?: readonly string[] | undefined;\n}\n\n/**\n * Error handling (catch, catchTag, orElse, etc.).\n */\nexport interface StaticErrorHandlerNode extends StaticBaseNode {\n  readonly type: 'error-handler';\n  /** Type of handler: catch, catchTag, orElse, etc. */\n  readonly handlerType:\n    | 'catch'\n    | 'catchTag'\n    | 'catchCause'\n    | 'catchIf'\n    | 'catchSome'\n    | 'catchSomeCause'\n    | 'catchSomeDefect'\n    | 'catchDefect'\n    | 'catchTags'\n    // Effect 4 catch APIs\n    | 'catchReason'\n    | 'catchReasons'\n    | 'catchFilter'\n    | 'catchCauseIf'\n    | 'catchCauseFilter'\n    | 'catchNoSuchElement'\n    | 'catchEager'\n    | 'orElse'\n    | 'orElseFail'\n    | 'orElseSucceed'\n    | 'orDie'\n    | 'orDieWith'\n    | 'flip'\n    | 'mapError'\n    | 'mapErrorCause'\n    | 'mapBoth'\n    | 'sandbox'\n    | 'unsandbox'\n    | 'parallelErrors'\n    | 'filterOrDie'\n    | 'filterOrDieMessage'\n    | 'filterOrElse'\n    | 'filterOrFail'\n    | 'match'\n    | 'matchCause'\n    | 'matchEffect'\n    | 'matchCauseEffect'\n    | 'firstSuccessOf'\n    | 'ignore'\n    | 'ignoreLogged'\n    | 'eventually';\n  /** The effect being handled */\n  readonly source: StaticFlowNode;\n  /** The handler (recovery) effect */\n  readonly handler?: StaticFlowNode | undefined;\n  /** For catchTag, the error tag being caught */\n  readonly errorTag?: string | undefined;\n  /** For catchTags (object form), the error tags being caught */\n  readonly errorTags?: readonly string[] | undefined;\n  /** Edge label for the error path (e.g. \"on DatabaseError\") */\n  readonly errorEdgeLabel?: string | undefined;\n}\n\n/**\n * Schedule composition info (GAP 8).\n */\nexport interface ScheduleInfo {\n  readonly baseStrategy:\n    | 'fixed'\n    | 'exponential'\n    | 'fibonacci'\n    | 'spaced'\n    | 'linear'\n    | 'cron'\n    | 'windowed'\n    | 'duration'\n    | 'elapsed'\n    | 'delays'\n    | 'once'\n    | 'stop'\n    | 'count'\n    | 'custom';\n  readonly maxRetries?: number | 'unlimited' | undefined;\n  readonly initialDelay?: string | undefined;\n  readonly maxDelay?: string | undefined;\n  readonly jittered: boolean;\n  readonly conditions: readonly string[];\n  readonly estimatedMaxDuration?: string | undefined;\n}\n\n/**\n * Retry/Schedule operation.\n */\nexport interface StaticRetryNode extends StaticBaseNode {\n  readonly type: 'retry';\n  /** The effect being retried */\n  readonly source: StaticFlowNode;\n  /** Schedule policy if statically determinable (expression text) */\n  readonly schedule?: string | undefined;\n  /** Parsed schedule when present (GAP 8 dedicated Schedule IR) */\n  readonly scheduleNode?: StaticFlowNode | undefined;\n  /** Whether it's a retryOrElse */\n  readonly hasFallback: boolean;\n  /** Decomposed schedule (GAP 8) */\n  readonly scheduleInfo?: ScheduleInfo | undefined;\n  /** Edge label for the retry path (e.g. \"retry: exponential(100ms)\") */\n  readonly retryEdgeLabel?: string | undefined;\n}\n\n/**\n * Timeout operation.\n */\nexport interface StaticTimeoutNode extends StaticBaseNode {\n  readonly type: 'timeout';\n  /** The effect being timed out */\n  readonly source: StaticFlowNode;\n  /** Timeout duration if statically determinable */\n  readonly duration?: string | undefined;\n  /** Whether there's a fallback */\n  readonly hasFallback: boolean;\n}\n\n/**\n * Resource acquisition (acquireRelease).\n */\nexport interface StaticResourceNode extends StaticBaseNode {\n  readonly type: 'resource';\n  /** Acquisition effect */\n  readonly acquire: StaticFlowNode;\n  /** Release effect */\n  readonly release: StaticFlowNode;\n  /** Use effect */\n  readonly use?: StaticFlowNode | undefined;\n}\n\n/**\n * Conditional execution (Effect.if, when, unless).\n */\nexport interface StaticConditionalNode extends StaticBaseNode {\n  readonly type: 'conditional';\n  /** The condition as source string */\n  readonly condition: string;\n  /** Type of conditional */\n  readonly conditionalType:\n    | 'if'\n    | 'when'\n    | 'unless'\n    | 'whenEffect'\n    | 'whenFiberRef'\n    | 'whenRef'\n    | 'unlessEffect'\n    | 'option'\n    | 'either'\n    | 'exit'\n    | 'liftPredicate';\n  /** Branch when condition is true */\n  readonly onTrue: StaticFlowNode;\n  /** Branch when condition is false (if present) */\n  readonly onFalse?: StaticFlowNode | undefined;\n  /** Semantic label for the condition (e.g. \"isAdmin\") */\n  readonly conditionLabel?: string | undefined;\n  /** Label for the true branch edge */\n  readonly trueEdgeLabel?: string | undefined;\n  /** Label for the false branch edge */\n  readonly falseEdgeLabel?: string | undefined;\n}\n\n/**\n * Decision node for raw `if`, ternaries, short-circuits, and `Step.decide`.\n */\nexport interface StaticDecisionNode extends StaticBaseNode {\n  readonly type: 'decision';\n  /** Unique decision identifier */\n  readonly decisionId: string;\n  /** Human-readable label for the decision */\n  readonly label: string;\n  /** Condition expression source text */\n  readonly condition: string;\n  /** Origin of the decision construct */\n  readonly source: 'effect-flow' | 'raw-if' | 'raw-ternary' | 'raw-short-circuit';\n  /** Branch when condition is true */\n  readonly onTrue: readonly StaticFlowNode[];\n  /** Branch when condition is false (if present) */\n  readonly onFalse?: readonly StaticFlowNode[] | undefined;\n}\n\n/**\n * A single case arm in a switch node.\n */\nexport interface StaticSwitchCase {\n  /** Labels for this case (e.g. string/number literals) */\n  readonly labels: readonly string[];\n  /** Whether this is the default case */\n  readonly isDefault: boolean;\n  /** Body nodes for this case */\n  readonly body: readonly StaticFlowNode[];\n}\n\n/**\n * Switch node for raw `switch` statements and `Step.branch`.\n */\nexport interface StaticSwitchNode extends StaticBaseNode {\n  readonly type: 'switch';\n  /** Optional switch identifier */\n  readonly switchId?: string | undefined;\n  /** Expression being switched on */\n  readonly expression: string;\n  /** Case arms */\n  readonly cases: readonly StaticSwitchCase[];\n  /** Origin of the switch construct */\n  readonly source: 'effect-flow' | 'raw-js';\n  /** Whether a default case is present */\n  readonly hasDefault: boolean;\n  /** Whether any case falls through to the next */\n  readonly hasFallthrough: boolean;\n}\n\n/**\n * Try/catch/finally node for raw exception handling.\n */\nexport interface StaticTryCatchNode extends StaticBaseNode {\n  readonly type: 'try-catch';\n  /** Body of the try block */\n  readonly tryBody: readonly StaticFlowNode[];\n  /** Catch clause variable name */\n  readonly catchVariable?: string | undefined;\n  /** Body of the catch block */\n  readonly catchBody?: readonly StaticFlowNode[] | undefined;\n  /** Body of the finally block */\n  readonly finallyBody?: readonly StaticFlowNode[] | undefined;\n  /** Whether the try body contains a terminal statement (return/throw) */\n  readonly hasTerminalInTry: boolean;\n}\n\n/**\n * Terminal node for `return`, `throw`, `break`, and `continue` statements.\n */\nexport interface StaticTerminalNode extends StaticBaseNode {\n  readonly type: 'terminal';\n  /** Kind of terminal statement */\n  readonly terminalKind: 'return' | 'throw' | 'break' | 'continue';\n  /** Label for labeled break/continue */\n  readonly label?: string | undefined;\n  /** Value expression (e.g. the returned/thrown value) */\n  readonly value?: readonly StaticFlowNode[] | undefined;\n}\n\n/**\n * Opaque node for unsupported or unanalyzable constructs.\n */\nexport interface StaticOpaqueNode extends StaticBaseNode {\n  readonly type: 'opaque';\n  /** Reason why this construct could not be analyzed */\n  readonly reason: string;\n  /** Original source text of the construct */\n  readonly sourceText: string;\n}\n\n/**\n * Cause module operation — construction or inspection of Effect Cause values.\n */\nexport interface StaticCauseNode extends StaticBaseNode {\n  readonly type: 'cause';\n  /** The specific Cause operation */\n  readonly causeOp:\n    | 'fail'\n    | 'die'\n    | 'interrupt'\n    | 'parallel'\n    | 'sequential'\n    | 'empty'\n    | 'failures'\n    | 'defects'\n    | 'interruptors'\n    | 'squash'\n    | 'squashWith'\n    | 'pretty'\n    | 'flatten'\n    | 'isDie'\n    | 'isFailure'\n    | 'isInterrupted'\n    | 'isEmpty'\n    | 'map'\n    | 'filter'\n    | 'other';\n  /** Whether this is a constructor (fail/die/interrupt/parallel/sequential/empty) */\n  readonly isConstructor: boolean;\n  /** For parallel/sequential: child cause nodes (GAP Cause structural traversal). */\n  readonly children?: readonly StaticFlowNode[] | undefined;\n  /** Cause kind classification */\n  readonly causeKind?: 'fail' | 'die' | 'interrupt' | 'mixed' | undefined;\n}\n\n/**\n * Exit module operation — construction or inspection of Effect Exit values.\n */\nexport interface StaticExitNode extends StaticBaseNode {\n  readonly type: 'exit';\n  /** The specific Exit operation */\n  readonly exitOp:\n    | 'succeed'\n    | 'fail'\n    | 'die'\n    | 'interrupt'\n    | 'void'\n    | 'unit'\n    | 'match'\n    | 'isSuccess'\n    | 'isFailure'\n    | 'isInterrupted'\n    | 'when'\n    | 'whenEffect'\n    | 'exists'\n    | 'contains'\n    | 'flatten'\n    | 'map'\n    | 'mapBoth'\n    | 'mapError'\n    | 'flatMap'\n    | 'zipWith'\n    | 'tap'\n    | 'tapBoth'\n    | 'tapError'\n    | 'other';\n  /** Whether this is a constructor (succeed/fail/die/interrupt/void/unit) */\n  readonly isConstructor: boolean;\n}\n\n/**\n * Schedule module operation — construction or composition of Schedule values (GAP 8 dedicated IR).\n */\nexport interface StaticScheduleNode extends StaticBaseNode {\n  readonly type: 'schedule';\n  /** The specific Schedule operation */\n  readonly scheduleOp:\n    | 'exponential'\n    | 'fibonacci'\n    | 'spaced'\n    | 'fixed'\n    | 'linear'\n    | 'cron'\n    | 'windowed'\n    | 'duration'\n    | 'elapsed'\n    | 'delays'\n    | 'once'\n    | 'stop'\n    | 'count'\n    | 'forever'\n    | 'jittered'\n    | 'andThen'\n    | 'intersect'\n    | 'union'\n    | 'compose'\n    | 'zipWith'\n    | 'addDelay'\n    | 'modifyDelay'\n    | 'check'\n    | 'resetAfter'\n    | 'resetWhen'\n    | 'ensure'\n    | 'driver'\n    | 'mapInput'\n    | 'other';\n  /** Decomposed schedule (when parseable from expression text) */\n  readonly scheduleInfo?: ScheduleInfo | undefined;\n}\n\n/**\n * Match module operation (Match.type / Match.when / Match.exhaustive etc.).\n */\nexport interface StaticMatchNode extends StaticBaseNode {\n  readonly type: 'match';\n  /** The specific Match operation */\n  readonly matchOp:\n    | 'type'\n    | 'tag'\n    | 'value'\n    | 'when'\n    | 'whenOr'\n    | 'whenAnd'\n    | 'not'\n    | 'is'\n    | 'exhaustive'\n    | 'orElse'\n    | 'option'\n    | 'either'\n    | 'discriminator'\n    | 'discriminatorsExhaustive'\n    | 'tags'\n    | 'tagsExhaustive'\n    | 'withReturnType'\n    | 'run'\n    | 'other';\n  /** Tag names matched (for Match.tag, Match.when with tag literals, Match.tags) */\n  readonly matchedTags?: readonly string[] | undefined;\n  /** Whether this match arm makes the overall match exhaustive */\n  readonly isExhaustive: boolean;\n}\n\n/**\n * Transformation step in a pipe chain (map, flatMap, andThen, tap, zip, as, etc.).\n * These preserve the Effect channel but transform A, E, or R.\n */\nexport interface StaticTransformNode extends StaticBaseNode {\n  readonly type: 'transform';\n  /** Specific transformation operation */\n  readonly transformType:\n    | 'map'\n    | 'flatMap'\n    | 'andThen'\n    | 'tap'\n    | 'tapBoth'\n    | 'tapError'\n    | 'tapErrorTag'\n    | 'tapErrorCause'\n    | 'tapDefect'\n    | 'zipLeft'\n    | 'zipRight'\n    | 'zipWith'\n    | 'zip'\n    | 'as'\n    | 'asVoid'\n    | 'asSome'\n    | 'asSomeError'\n    | 'flatten'\n    | 'ap'\n    | 'negate'\n    | 'merge'\n    | 'other';\n  /**\n   * Whether this is an effectful transformation\n   * (e.g. flatMap/andThen produce a new Effect, map does not).\n   */\n  readonly isEffectful: boolean;\n  /** The source/input effect (if extractable from args, undefined for curried forms). */\n  readonly source?: StaticFlowNode | undefined;\n  /** The transformation function text (if simple enough to extract). */\n  readonly fn?: string | undefined;\n  /** Input type signature (before transform) */\n  readonly inputType?: EffectTypeSignature | undefined;\n  /** Output type signature (after transform) */\n  readonly outputType?: EffectTypeSignature | undefined;\n}\n\n/**\n * Loop structure (forEach, loop).\n */\nexport interface StaticLoopNode extends StaticBaseNode {\n  readonly type: 'loop';\n  /** Type of loop / collection operation */\n  readonly loopType:\n    | 'forEach'\n    | 'filter'\n    | 'filterMap'\n    | 'partition'\n    | 'reduce'\n    | 'validate'\n    | 'replicate'\n    | 'dropUntil'\n    | 'dropWhile'\n    | 'takeUntil'\n    | 'takeWhile'\n    | 'every'\n    | 'exists'\n    | 'findFirst'\n    | 'head'\n    | 'mergeAll'\n    | 'loop'\n    | 'for'\n    | 'forOf'\n    | 'forIn'\n    | 'while'\n    | 'doWhile';\n  /** The iteration source */\n  readonly iterSource?: string | undefined;\n  /** Body of the loop */\n  readonly body: StaticFlowNode;\n  /** Callback/reducer body summary for higher-order collection APIs */\n  readonly callbackBody?: readonly StaticFlowNode[] | undefined;\n  /** Whether the loop contains an early exit (break/return) */\n  readonly hasEarlyExit?: boolean | undefined;\n  /** Yield expressions in the loop header (e.g. for-of with yield* in initializer) */\n  readonly headerYields?: readonly StaticFlowNode[] | undefined;\n  /** Iteration variable name (for for-of/for-in loops) */\n  readonly iterVariable?: string | undefined;\n}\n\n/**\n * Layer lifecycle (GAP 2).\n */\nexport type LayerLifecycle = 'default' | 'fresh' | 'scoped' | 'memoized';\n\n/**\n * Layer/service provision.\n */\nexport interface StaticLayerNode extends StaticBaseNode {\n  readonly type: 'layer';\n  /** Layer operations */\n  readonly operations: readonly StaticFlowNode[];\n  /** Whether this is a merged layer */\n  readonly isMerged: boolean;\n  /** Service tags this layer provides (GAP 2) */\n  readonly provides?: readonly string[] | undefined;\n  /** Service tags this layer requires (GAP 2) */\n  readonly requires?: readonly string[] | undefined;\n  /** Lifecycle (GAP 2) */\n  readonly lifecycle?: LayerLifecycle | undefined;\n  /** True when this layer is or contains Layer.MemoMap (GAP dedicated memo-map analysis). */\n  readonly isMemoMap?: boolean | undefined;\n}\n\n/**\n * Stream operator in a pipeline (GAP 5).\n */\nexport interface StreamOperatorInfo {\n  readonly operation: string;\n  readonly isEffectful: boolean;\n  /** Callback/transformation body summary for higher-order stream operators */\n  readonly callbackBody?: readonly StaticFlowNode[] | undefined;\n  readonly estimatedCardinality?: 'same' | 'fewer' | 'more' | 'unknown' | undefined;\n  readonly category?:\n    | 'constructor'\n    | 'transform'\n    | 'filter'\n    | 'windowing'\n    | 'merge'\n    | 'broadcasting'\n    | 'halting'\n    | 'text'\n    | 'backpressure'\n    | 'error'\n    | 'resource'\n    | 'context'\n    | 'sink'\n    | 'conversion'\n    | 'channel'\n    | 'other'\n    | undefined;\n  /** Windowing: size for grouped/groupedWithin/sliding (GAP 2 windowing detail). */\n  readonly windowSize?: number | undefined;\n  /** Windowing: stride/step for sliding (GAP 2 windowing detail). */\n  readonly stride?: number | undefined;\n}\n\n/**\n * Stream pipeline (GAP 5).\n */\nexport interface StaticStreamNode extends StaticBaseNode {\n  readonly type: 'stream';\n  readonly source: StaticFlowNode;\n  readonly pipeline: readonly StreamOperatorInfo[];\n  readonly sink?: string | undefined;\n  readonly backpressureStrategy?: 'buffer' | 'drop' | 'sliding' | undefined;\n  /** Classified constructor type when this is a Stream.from* / Stream.make / etc. */\n  readonly constructorType?:\n    | 'fromIterable'\n    | 'fromArray'\n    | 'fromQueue'\n    | 'fromPubSub'\n    | 'fromEffect'\n    | 'fromAsyncIterable'\n    | 'fromReadableStream'\n    | 'fromEventListener'\n    | 'fromSchedule'\n    | 'range'\n    | 'tick'\n    | 'iterate'\n    | 'unfold'\n    | 'make'\n    | 'empty'\n    | 'never'\n    | 'succeed'\n    | 'fail'\n    | 'fromMailbox'\n    | 'fromSubscriptionRef'\n    | 'other'\n    | undefined;\n}\n\n/**\n * Concurrency primitive (Queue, PubSub, Deferred, Semaphore, Mailbox, Latch, FiberSet, FiberMap, FiberHandle, RateLimiter, SubscriptionRef) - GAP 6.\n */\nexport interface StaticConcurrencyPrimitiveNode extends StaticBaseNode {\n  readonly type: 'concurrency-primitive';\n  readonly primitive:\n    | 'queue'\n    | 'pubsub'\n    | 'deferred'\n    | 'semaphore'\n    | 'mailbox'\n    | 'latch'\n    | 'fiberHandle'\n    | 'fiberSet'\n    | 'fiberMap'\n    | 'rateLimiter'\n    | 'cache'\n    | 'scopedCache'\n    | 'rcRef'\n    | 'rcMap'\n    | 'reloadable'\n    | 'subscriptionRef';\n  readonly operation:\n    | 'create'\n    | 'offer'\n    | 'take'\n    | 'takeAll'\n    | 'publish'\n    | 'subscribe'\n    | 'await'\n    | 'succeed'\n    | 'fail'\n    | 'withPermit'\n    | 'run'\n    | 'open'\n    | 'close'\n    | 'release'\n    | 'available'\n    | 'get'\n    | 'set'\n    | 'invalidate'\n    | 'contains'\n    | 'update'\n    | 'reload'\n    | 'end'\n    | 'toStream'\n    | 'changes';\n  readonly strategy?: 'bounded' | 'unbounded' | 'sliding' | 'dropping' | undefined;\n  readonly capacity?: number | undefined;\n  /** For Semaphore take(n) / release(n): permit count when first arg is numeric literal (GAP 13). */\n  readonly permitCount?: number | undefined;\n  readonly source?: StaticFlowNode | undefined;\n  /** Lifecycle options (e.g. FiberHandle.run { onlyIfMissing: true }) */\n  readonly lifecycleOptions?: Record<string, unknown> | undefined;\n}\n\n/**\n * Fiber operation (fork, join, interrupt) - GAP 1.\n */\nexport interface StaticFiberNode extends StaticBaseNode {\n  readonly type: 'fiber';\n  readonly operation:\n    | 'fork'\n    | 'forkScoped'\n    | 'forkDaemon'\n    | 'forkAll'\n    | 'forkIn'\n    | 'forkWithErrorHandler'\n    | 'join'\n    | 'await'\n    | 'interrupt'\n    | 'interruptFork'\n    | 'poll'\n    | 'status'\n    | 'all'\n    | 'awaitAll'\n    | 'children'\n    | 'dump'\n    | 'scoped'\n    | 'inheritAll'\n    | 'map'\n    | 'mapEffect'\n    | 'mapFiber'\n    | 'roots'\n    | 'getCurrentFiber';\n  readonly fiberSource?: StaticFlowNode | undefined;\n  readonly joinPoint?: string | undefined;\n  readonly isScoped: boolean;\n  readonly isDaemon: boolean;\n  /** Scope context: 'safe' when fiber is inside Effect.scoped or after Scope.make */\n  readonly scopeContext?: string | undefined;\n}\n\n/**\n * Interruption region (interruptible/uninterruptible/mask/onInterrupt).\n */\nexport interface StaticInterruptionNode extends StaticBaseNode {\n  readonly type: 'interruption';\n  /** The interruption operation */\n  readonly interruptionType:\n    | 'interrupt'\n    | 'interruptWith'\n    | 'interruptible'\n    | 'uninterruptible'\n    | 'interruptibleMask'\n    | 'uninterruptibleMask'\n    | 'onInterrupt'\n    | 'disconnect'\n    | 'allowInterrupt';\n  /** The wrapped effect (for interruptible/uninterruptible/mask) */\n  readonly source?: StaticFlowNode | undefined;\n  /** The interrupt handler (for onInterrupt) */\n  readonly handler?: StaticFlowNode | undefined;\n}\n\n/**\n * Unknown or unanalyzable code block.\n */\nexport interface StaticUnknownNode extends StaticBaseNode {\n  readonly type: 'unknown';\n  /** Reason why this couldn't be analyzed */\n  readonly reason: string;\n  /** The source code that couldn't be analyzed */\n  readonly sourceCode?: string | undefined;\n}\n\n/** Channel operator or constructor (improve.md §8). */\nexport interface ChannelOperatorInfo {\n  readonly operation: string;\n  readonly category?: 'constructor' | 'transform' | 'pipe' | 'other' | undefined;\n}\n\n/**\n * Channel pipeline node (improve.md §8 dedicated Channel analysis).\n */\nexport interface StaticChannelNode extends StaticBaseNode {\n  readonly type: 'channel';\n  readonly source?: StaticFlowNode | undefined;\n  readonly pipeline: readonly ChannelOperatorInfo[];\n}\n\n/** Sink operator (improve.md §8). */\nexport interface SinkOperatorInfo {\n  readonly operation: string;\n  readonly category?: 'constructor' | 'transform' | 'other' | undefined;\n}\n\n/**\n * Sink pipeline node (improve.md §8 dedicated Sink analysis).\n */\nexport interface StaticSinkNode extends StaticBaseNode {\n  readonly type: 'sink';\n  readonly source?: StaticFlowNode | undefined;\n  readonly pipeline: readonly SinkOperatorInfo[];\n}\n\n/**\n * Union of all static flow node types.\n */\nexport type StaticFlowNode =\n  | StaticEffectNode\n  | StaticGeneratorNode\n  | StaticPipeNode\n  | StaticParallelNode\n  | StaticRaceNode\n  | StaticErrorHandlerNode\n  | StaticRetryNode\n  | StaticTimeoutNode\n  | StaticResourceNode\n  | StaticConditionalNode\n  | StaticLoopNode\n  | StaticCauseNode\n  | StaticExitNode\n  | StaticScheduleNode\n  | StaticMatchNode\n  | StaticTransformNode\n  | StaticLayerNode\n  | StaticStreamNode\n  | StaticChannelNode\n  | StaticSinkNode\n  | StaticConcurrencyPrimitiveNode\n  | StaticFiberNode\n  | StaticInterruptionNode\n  | StaticDecisionNode\n  | StaticSwitchNode\n  | StaticTryCatchNode\n  | StaticTerminalNode\n  | StaticOpaqueNode\n  | StaticUnknownNode;\n\n// =============================================================================\n// Static Effect IR\n// =============================================================================\n\n/**\n * Root node representing the analyzed effect program.\n */\nexport interface StaticEffectProgram extends StaticBaseNode {\n  readonly type: 'program';\n  /** Name of the program (from file name or variable) */\n  readonly programName: string;\n  /** Entry point: gen, direct, pipe, run, workflow-execute, or class */\n  readonly source: 'generator' | 'direct' | 'pipe' | 'run' | 'workflow-execute' | 'class' | 'classProperty' | 'classMethod' | 'functionDeclaration';\n  /** Discovery confidence based on alias/path resolution vs heuristics */\n  readonly discoveryConfidence?: 'high' | 'medium' | 'low';\n  /** Best-effort reason used to classify this as an Effect program */\n  readonly discoveryReason?: string | undefined;\n  /** The root effect nodes */\n  readonly children: readonly StaticFlowNode[];\n  /** Dependencies (services required) */\n  readonly dependencies: readonly DependencyInfo[];\n  /** Error types */\n  readonly errorTypes: readonly string[];\n  /** Full type signature of the program (A, E, R) */\n  readonly typeSignature?: EffectTypeSignature | undefined;\n  /** All service requirements across the program */\n  readonly requiredServices?: ServiceRequirement[] | undefined;\n  /** Description */\n  readonly description?: string | undefined;\n  /** JSDoc description extracted from comments above the program */\n  readonly jsdocDescription?: string | undefined;\n  /** Structured JSDoc tags extracted from comments */\n  readonly jsdocTags?: JSDocTags | undefined;\n}\n\n/**\n * Information about a dependency/service.\n */\nexport interface DependencyInfo {\n  readonly name: string;\n  readonly typeSignature?: string | undefined;\n  readonly isLayer: boolean;\n}\n\n/**\n * Effect Type Signature - A, E, R parameters\n */\nexport interface EffectTypeSignature {\n  /** Success type (A) */\n  readonly successType: string;\n  /** Error type (E) */\n  readonly errorType: string;\n  /** Requirements/Context type (R) */\n  readonly requirementsType: string;\n  /** Whether the type was successfully extracted */\n  readonly isInferred: boolean;\n  /** Confidence level of the type extraction */\n  readonly typeConfidence: 'declared' | 'inferred' | 'unknown';\n  /** Raw type string from TypeScript */\n  readonly rawTypeString?: string;\n}\n\n/** Stream type args — Stream<A, E, R> (21.3 type extraction) */\nexport interface StreamTypeSignature {\n  readonly successType: string;\n  readonly errorType: string;\n  readonly requirementsType: string;\n  readonly rawTypeString?: string;\n}\n\n/** Layer type args — Layer<ROut, E, RIn> (provides, error, requires) (21.3 type extraction) */\nexport interface LayerTypeSignature {\n  readonly providedType: string;\n  readonly errorType: string;\n  readonly requiredType: string;\n  readonly rawTypeString?: string;\n}\n\n/** Schedule type args — Schedule<Out, In, R> (21.3 type extraction) */\nexport interface ScheduleTypeSignature {\n  readonly outputType: string;\n  readonly inputType: string;\n  readonly requirementsType: string;\n  readonly rawTypeString?: string;\n}\n\n/** Cause type args — Cause<E> (21.3 type extraction) */\nexport interface CauseTypeSignature {\n  readonly errorType: string;\n  readonly rawTypeString?: string;\n}\n\n/**\n * Service requirement extracted from Context type\n */\nexport interface ServiceRequirement {\n  /** Service identifier (tag key) */\n  readonly serviceId: string;\n  /** Service type name */\n  readonly serviceType: string;\n  /** Where this requirement originates */\n  readonly requiredAt: SourceLocation;\n}\n\n// =============================================================================\n// Schema Analysis Types\n// =============================================================================\n\n/**\n * Schema validation path - represents a field that can fail validation\n */\nexport interface SchemaValidationPath {\n  /** Field path (e.g., \"user.email\" or \"items[0].name\") */\n  readonly path: string;\n  /** Schema type at this path */\n  readonly schemaType: string;\n  /** Validation constraints (e.g., minLength, pattern) */\n  readonly constraints: readonly SchemaConstraint[];\n  /** Whether this field is optional */\n  readonly isOptional: boolean;\n  /** Location in source code */\n  readonly location?: SourceLocation | undefined;\n}\n\n/**\n * Schema validation constraint\n */\nexport interface SchemaConstraint {\n  /** Constraint type (e.g., \"minLength\", \"pattern\", \"range\") */\n  readonly type: string;\n  /** Constraint value */\n  readonly value: string | number | boolean;\n  /** Human-readable description */\n  readonly description: string;\n}\n\n/**\n * Schema decode/encode operation analysis\n */\nexport interface SchemaOperation {\n  /** Operation type */\n  readonly operation: 'decode' | 'encode' | 'decodeUnknown' | 'encodeUnknown';\n  /** Schema being used */\n  readonly schemaName: string;\n  /** Source type (encoded) */\n  readonly sourceType: string;\n  /** Target type (decoded) */\n  readonly targetType: string;\n  /** Validation paths that can fail */\n  readonly validationPaths: readonly SchemaValidationPath[];\n  /** Whether error handling is present */\n  readonly hasErrorHandling: boolean;\n  /** Location in source code */\n  readonly location?: SourceLocation | undefined;\n}\n\n/**\n * Schema composition information\n */\nexport interface SchemaComposition {\n  /** Schema name */\n  readonly schemaName: string;\n  /** Composition type */\n  readonly compositionType:\n    | 'struct'\n    | 'union'\n    | 'array'\n    | 'record'\n    | 'tuple'\n    | 'class'\n    | 'recursive'\n    | 'optional'\n    | 'nullable'\n    | 'transform'\n    | 'filter'\n    | 'brand'\n    | 'literal'\n    | 'enum'\n    | 'refinement'\n    | 'datetime'\n    | 'effect-type'\n    | 'serializable';\n  /** Child schemas */\n  readonly children: readonly string[];\n  /** Validation paths */\n  readonly validationPaths: readonly SchemaValidationPath[];\n}\n\n/**\n * Complete Schema analysis result\n */\nexport interface SchemaAnalysis {\n  /** All Schema.decode/encode operations found */\n  readonly operations: readonly SchemaOperation[];\n  /** Schema compositions detected */\n  readonly compositions: readonly SchemaComposition[];\n  /** Missing error handlers for Schema operations */\n  readonly unhandledOperations: readonly SchemaOperation[];\n}\n\n/**\n * Complete static Effect IR.\n */\nexport interface StaticEffectIR {\n  readonly root: StaticEffectProgram;\n  readonly metadata: StaticAnalysisMetadata;\n  readonly references: ReadonlyMap<string, StaticEffectIR>;\n}\n\n/**\n * Service interface shape extracted from Context.Tag / Effect.Service class (GAP service interface tracking).\n */\nexport interface ServiceDefinition {\n  /** Tag/service identifier (class name or tag string). */\n  readonly tagId: string;\n  /** Method names from the service interface type. */\n  readonly methods: readonly string[];\n  /** Property names (non-callable members) from the service interface type. */\n  readonly properties: readonly string[];\n  /** Whether class implements [Equal.symbol] */\n  readonly hasCustomEquality?: boolean | undefined;\n  /** Whether class implements [Hash.symbol] */\n  readonly hasCustomHash?: boolean | undefined;\n}\n\n/**\n * Metadata about the static analysis.\n */\nexport interface StaticAnalysisMetadata {\n  readonly analyzedAt: number;\n  readonly filePath: string;\n  readonly tsVersion?: string | undefined;\n  readonly warnings: readonly AnalysisWarning[];\n  readonly stats: AnalysisStats;\n  /** Service interface shapes (methods/properties) from Context.Tag/Effect.Service in this file. */\n  readonly serviceDefinitions?: readonly ServiceDefinition[] | undefined;\n}\n\n/**\n * Warning generated during analysis.\n */\nexport interface AnalysisWarning {\n  readonly code: string;\n  readonly message: string;\n  readonly location?: SourceLocation | undefined;\n}\n\n/**\n * Statistics about the analysis.\n */\nexport interface AnalysisStats {\n  totalEffects: number;\n  parallelCount: number;\n  raceCount: number;\n  errorHandlerCount: number;\n  retryCount: number;\n  timeoutCount: number;\n  resourceCount: number;\n  loopCount: number;\n  conditionalCount: number;\n  layerCount: number;\n  interruptionCount: number;\n  unknownCount: number;\n  decisionCount: number;\n  switchCount: number;\n  tryCatchCount: number;\n  terminalCount: number;\n  opaqueCount: number;\n}\n\n// =============================================================================\n// Diagram Quality Types\n// =============================================================================\n\nexport type DiagramReadabilityBand = 'good' | 'ok' | 'noisy';\n\nexport interface DiagramQualityMetrics {\n  readonly stepCountDetailed: number;\n  readonly stepCountSummary: number;\n  readonly collapsedGroupsSummary: number;\n  readonly logRatio: number;\n  readonly sideEffectRatio: number;\n  readonly anonymousNodeCount: number;\n  readonly anonymousRatio: number;\n  readonly unknownNodeCount: number;\n  readonly serviceCallCount: number;\n  readonly namedServiceCallRatio: number;\n  readonly pipeChainCount: number;\n  readonly maxPipeChainLength: number;\n}\n\nexport interface DiagramQuality {\n  readonly score: number;\n  readonly band: DiagramReadabilityBand;\n  readonly metrics: DiagramQualityMetrics;\n  readonly reasons: readonly string[];\n  readonly tips: readonly string[];\n}\n\nexport interface DiagramTopOffenderEntry {\n  readonly filePath: string;\n  readonly metricValue: number;\n  readonly tip: string;\n}\n\nexport interface DiagramTopOffendersReport {\n  readonly largestPrograms: readonly DiagramTopOffenderEntry[];\n  readonly mostAnonymousNodes: readonly DiagramTopOffenderEntry[];\n  readonly mostUnknownNodes: readonly DiagramTopOffenderEntry[];\n  readonly highestLogRatio: readonly DiagramTopOffenderEntry[];\n}\n\nexport interface DiagramQualityWithFile {\n  readonly filePath: string;\n  readonly quality: DiagramQuality;\n}\n\n/**\n * Options for the static analyzer.\n */\nexport interface AnalyzerOptions {\n  readonly tsConfigPath?: string | undefined;\n  readonly resolveReferences?: boolean | undefined;\n  readonly maxReferenceDepth?: number | undefined;\n  readonly includeLocations?: boolean | undefined;\n  readonly assumeImported?: boolean | undefined;\n  /** Enable effect-workflow patterns (Workflow.make / Workflow.run). Use the \"effect-workflow\" entrypoint for this. */\n  readonly enableEffectWorkflow?: boolean | undefined;\n  /** Optional path to known Effect internals root; local/relative imports under this path are treated as Effect-like (improve.md §1). */\n  readonly knownEffectInternalsRoot?: string | undefined;\n  /** Optional minimum confidence threshold for discovered programs. */\n  readonly minDiscoveryConfidence?: 'low' | 'medium' | 'high' | undefined;\n  /** When true, only keep discovered programs whose roots are exported (or top-level run statements). */\n  readonly onlyExportedPrograms?: boolean | undefined;\n  /** Enable effect-flow analysis for raw control-flow constructs (if/switch/try-catch/loops). */\n  readonly enableEffectFlow?: boolean | undefined;\n}\n\n// =============================================================================\n// Effect-based Analysis Result\n// =============================================================================\n\n/**\n * Result of static analysis - wrapped in Effect for composability.\n */\nexport type AnalysisResult = Effect.Effect<StaticEffectIR, AnalysisError>;\n\n/**\n * Errors that can occur during analysis.\n */\nexport class AnalysisError extends Error {\n  readonly code: string;\n  readonly location?: SourceLocation | undefined;\n\n  constructor(\n    code: string,\n    message: string,\n    location?: SourceLocation  ,\n  ) {\n    super(message);\n    this.code = code;\n    this.location = location;\n    this.name = 'AnalysisError';\n  }\n}\n\n// =============================================================================\n// Path Analysis Types\n// =============================================================================\n\n/**\n * A single execution path through the effect program.\n */\nexport interface EffectPath {\n  readonly id: string;\n  readonly description: string;\n  readonly steps: readonly PathStepRef[];\n  readonly conditions: readonly PathCondition[];\n  readonly hasLoops: boolean;\n  readonly hasUnresolvedRefs: boolean;\n}\n\n/**\n * Reference to a step in a path.\n */\nexport interface PathStepRef {\n  readonly nodeId: string;\n  readonly name?: string | undefined;\n  readonly repeated: boolean;\n}\n\n/**\n * A condition for a path.\n */\nexport interface PathCondition {\n  readonly expression: string;\n  readonly mustBe: boolean;\n  readonly location?: SourceLocation | undefined;\n}\n\n// =============================================================================\n// Complexity Types\n// =============================================================================\n\n/**\n * Complexity metrics for an effect program.\n */\nexport interface ComplexityMetrics {\n  readonly cyclomaticComplexity: number;\n  readonly pathCount: number | 'unbounded';\n  readonly maxDepth: number;\n  readonly maxParallelBreadth: number;\n  readonly decisionPoints: number;\n  readonly cognitiveComplexity: number;\n}\n\n/**\n * Complexity thresholds.\n */\nexport interface ComplexityThresholds {\n  readonly cyclomaticWarning: number;\n  readonly cyclomaticError: number;\n  readonly pathCountWarning: number;\n  readonly maxDepthWarning: number;\n}\n\n// =============================================================================\n// Test Matrix Types\n// =============================================================================\n\n/**\n * Test coverage matrix.\n */\nexport interface TestMatrix {\n  readonly paths: readonly TestPath[];\n  readonly conditions: readonly TestCondition[];\n  readonly summary: TestMatrixSummary;\n}\n\n/**\n * A path in the test matrix.\n */\nexport interface TestPath {\n  readonly id: string;\n  readonly suggestedTestName: string;\n  readonly description: string;\n  readonly setupConditions: readonly string[];\n  readonly expectedSteps: readonly string[];\n  readonly priority: 'high' | 'medium' | 'low';\n}\n\n/**\n * A condition affecting tests.\n */\nexport interface TestCondition {\n  readonly expression: string;\n  readonly affectedPathsWhenTrue: readonly string[];\n  readonly affectedPathsWhenFalse: readonly string[];\n}\n\n/**\n * Test matrix summary.\n */\nexport interface TestMatrixSummary {\n  readonly totalPaths: number;\n  readonly highPriorityPaths: number;\n  readonly totalConditions: number;\n  readonly minTestsForCoverage: number;\n}\n\n// =============================================================================\n// Type Guards (using Effect Option)\n// =============================================================================\n\nexport const isStaticEffectNode = (\n  node: StaticFlowNode,\n): node is StaticEffectNode => node.type === 'effect';\n\nexport const isStaticGeneratorNode = (\n  node: StaticFlowNode,\n): node is StaticGeneratorNode => node.type === 'generator';\n\nexport const isStaticPipeNode = (\n  node: StaticFlowNode,\n): node is StaticPipeNode => node.type === 'pipe';\n\nexport const isStaticParallelNode = (\n  node: StaticFlowNode,\n): node is StaticParallelNode => node.type === 'parallel';\n\nexport const isStaticRaceNode = (\n  node: StaticFlowNode,\n): node is StaticRaceNode => node.type === 'race';\n\nexport const isStaticErrorHandlerNode = (\n  node: StaticFlowNode,\n): node is StaticErrorHandlerNode => node.type === 'error-handler';\n\nexport const isStaticRetryNode = (\n  node: StaticFlowNode,\n): node is StaticRetryNode => node.type === 'retry';\n\nexport const isStaticTimeoutNode = (\n  node: StaticFlowNode,\n): node is StaticTimeoutNode => node.type === 'timeout';\n\nexport const isStaticResourceNode = (\n  node: StaticFlowNode,\n): node is StaticResourceNode => node.type === 'resource';\n\nexport const isStaticConditionalNode = (\n  node: StaticFlowNode,\n): node is StaticConditionalNode => node.type === 'conditional';\n\nexport const isStaticLoopNode = (\n  node: StaticFlowNode,\n): node is StaticLoopNode => node.type === 'loop';\n\nexport const isStaticLayerNode = (\n  node: StaticFlowNode,\n): node is StaticLayerNode => node.type === 'layer';\n\nexport const isStaticCauseNode = (\n  node: StaticFlowNode,\n): node is StaticCauseNode => node.type === 'cause';\n\nexport const isStaticExitNode = (\n  node: StaticFlowNode,\n): node is StaticExitNode => node.type === 'exit';\n\nexport const isStaticScheduleNode = (\n  node: StaticFlowNode,\n): node is StaticScheduleNode => node.type === 'schedule';\n\nexport const isStaticMatchNode = (\n  node: StaticFlowNode,\n): node is StaticMatchNode => node.type === 'match';\n\nexport const isStaticTransformNode = (\n  node: StaticFlowNode,\n): node is StaticTransformNode => node.type === 'transform';\n\nexport const isStaticStreamNode = (\n  node: StaticFlowNode,\n): node is StaticStreamNode => node.type === 'stream';\n\nexport const isStaticChannelNode = (\n  node: StaticFlowNode,\n): node is StaticChannelNode => node.type === 'channel';\n\nexport const isStaticSinkNode = (\n  node: StaticFlowNode,\n): node is StaticSinkNode => node.type === 'sink';\n\n/**\n * Collect all `StreamOperatorInfo` entries from a stream node, traversing\n * nested `source` links (for curried pipe-style chains not yet flattened).\n */\nexport const collectStreamPipeline = (node: StaticStreamNode): readonly StreamOperatorInfo[] => {\n  const ops: StreamOperatorInfo[] = [];\n  const seen = new Set<string>();\n  let current: StaticFlowNode = node;\n  while (current.type === 'stream') {\n    const s: StaticStreamNode = current;\n    if (seen.has(s.id)) break;\n    seen.add(s.id);\n    // pipeline is already flattened if data-last; just collect\n    ops.unshift(...s.pipeline);\n    current = s.source;\n  }\n  return ops;\n};\n\nexport const isStaticConcurrencyPrimitiveNode = (\n  node: StaticFlowNode,\n): node is StaticConcurrencyPrimitiveNode => node.type === 'concurrency-primitive';\n\nexport const isStaticFiberNode = (\n  node: StaticFlowNode,\n): node is StaticFiberNode => node.type === 'fiber';\n\nexport const isStaticInterruptionNode = (\n  node: StaticFlowNode,\n): node is StaticInterruptionNode => node.type === 'interruption';\n\nexport const isStaticUnknownNode = (\n  node: StaticFlowNode,\n): node is StaticUnknownNode => node.type === 'unknown';\n\nexport const isStaticDecisionNode = (node: StaticFlowNode): node is StaticDecisionNode => node.type === 'decision';\nexport const isStaticSwitchNode = (node: StaticFlowNode): node is StaticSwitchNode => node.type === 'switch';\nexport const isStaticTryCatchNode = (node: StaticFlowNode): node is StaticTryCatchNode => node.type === 'try-catch';\nexport const isStaticTerminalNode = (node: StaticFlowNode): node is StaticTerminalNode => node.type === 'terminal';\nexport const isStaticOpaqueNode = (node: StaticFlowNode): node is StaticOpaqueNode => node.type === 'opaque';\n\n// =============================================================================\n// Output Types\n// =============================================================================\n\n/**\n * Options for JSON output rendering.\n */\nexport interface JSONRenderOptions {\n  readonly pretty: boolean;\n  readonly includeMetadata: boolean;\n  readonly compact: boolean;\n}\n\n/**\n * Style definitions for Mermaid diagram output.\n */\nexport interface MermaidStyles {\n  readonly effect: string;\n  readonly generator: string;\n  readonly pipe: string;\n  readonly parallel: string;\n  readonly race: string;\n  readonly errorHandler: string;\n  readonly retry: string;\n  readonly timeout: string;\n  readonly resource: string;\n  readonly conditional: string;\n  readonly loop: string;\n  readonly layer: string;\n  readonly stream?: string | undefined;\n  readonly concurrencyPrimitive?: string | undefined;\n  readonly fiber?: string | undefined;\n  readonly unknown: string;\n  /** Start node style */\n  readonly start?: string | undefined;\n  /** End node style */\n  readonly end?: string | undefined;\n  /** Decision node style */\n  readonly decision?: string | undefined;\n  /** Switch node style */\n  readonly switch?: string | undefined;\n  /** Try/catch node style */\n  readonly tryCatch?: string | undefined;\n  /** Terminal node style */\n  readonly terminal?: string | undefined;\n  /** Opaque node style */\n  readonly opaque?: string | undefined;\n  /** Cause node style */\n  readonly cause?: string | undefined;\n  /** Exit node style */\n  readonly exit?: string | undefined;\n  /** Schedule node style */\n  readonly schedule?: string | undefined;\n  /** Match node style */\n  readonly match?: string | undefined;\n  /** Transform node style */\n  readonly transform?: string | undefined;\n  /** Channel node style */\n  readonly channel?: string | undefined;\n  /** Sink node style */\n  readonly sink?: string | undefined;\n  /** Interruption node style */\n  readonly interruption?: string | undefined;\n}\n\n/**\n * Options for Mermaid diagram output.\n */\nexport interface MermaidOptions {\n  readonly direction: 'TB' | 'LR' | 'BT' | 'RL';\n  readonly includeIds: boolean;\n  readonly includeDescriptions: boolean;\n  readonly styles: MermaidStyles;\n  readonly compact: boolean;\n  readonly title?: string | undefined;\n  /** Include type signatures (A, E, R) on effect nodes */\n  readonly includeTypeSignatures?: boolean | undefined;\n  /** Wrap parallel/race blocks in subgraphs */\n  readonly useSubgraphs?: boolean | undefined;\n  /** Show condition labels on edges (e.g. true/false for conditionals) */\n  readonly showConditions?: boolean | undefined;\n  /** Level of detail in node labels: compact (callee only), standard (+ variable names), verbose (+ types + roles) */\n  readonly detail?: MermaidDetailLevel | undefined;\n  /** Overlay data-flow variable annotations on edges and warning classes on nodes */\n  readonly dataFlowOverlay?: boolean | undefined;\n  /** Overlay error-flow annotations (error types, unhandled errors) on nodes */\n  readonly errorFlowOverlay?: boolean | undefined;\n}\n\n/**\n * Get children of a node as an Option.\n * Accepts StaticFlowNode or StaticEffectProgram (root) so that walking from ir.root works.\n */\nexport const getStaticChildren = (\n  node: StaticFlowNode | StaticEffectProgram,\n): Option.Option<readonly StaticFlowNode[]> => {\n  switch (node.type) {\n    case 'program':\n      return Option.some(node.children);\n    case 'generator':\n      return Option.some(node.yields.map((y) => y.effect));\n    case 'pipe':\n      return Option.some([node.initial, ...node.transformations]);\n    case 'parallel':\n    case 'race':\n      return Option.some([...node.children]);\n    case 'error-handler':\n      return Option.some(\n        node.handler ? [node.source, node.handler] : [node.source],\n      );\n    case 'retry': {\n      const retryNode = node;\n      const list = ([retryNode.source, retryNode.scheduleNode] as (StaticFlowNode | undefined)[]).filter(\n        (n): n is StaticFlowNode => n !== undefined,\n      );\n      return list.length > 0 ? Option.some(list) : Option.none();\n    }\n    case 'timeout': {\n      const src = node.source as StaticFlowNode | undefined;\n      return src ? Option.some([src]) : Option.none();\n    }\n    case 'resource':\n      return Option.some(\n        node.use\n          ? [node.acquire, node.release, node.use]\n          : [node.acquire, node.release],\n      );\n    case 'conditional':\n      return Option.some(\n        node.onFalse ? [node.onTrue, node.onFalse] : [node.onTrue],\n      );\n    case 'loop':\n      return Option.some([node.body]);\n    case 'cause':\n      return node.children && node.children.length > 0\n        ? Option.some(node.children)\n        : Option.none();\n    case 'exit':\n    case 'schedule':\n    case 'match':\n      return Option.none();\n    case 'transform':\n      return node.source ? Option.some([node.source]) : Option.none();\n    case 'layer':\n      return Option.some([...node.operations]);\n    case 'stream':\n      return Option.some([node.source]);\n    case 'channel':\n      return node.source ? Option.some([node.source]) : Option.none();\n    case 'sink':\n      return node.source ? Option.some([node.source]) : Option.none();\n    case 'concurrency-primitive':\n      return node.source ? Option.some([node.source]) : Option.none();\n    case 'fiber':\n      return node.fiberSource ? Option.some([node.fiberSource]) : Option.none();\n    case 'interruption': {\n      const children: StaticFlowNode[] = [];\n      if (node.source) children.push(node.source);\n      if (node.handler) children.push(node.handler);\n      return children.length > 0 ? Option.some(children) : Option.none();\n    }\n    case 'effect':\n      return node.callbackBody && node.callbackBody.length > 0\n        ? Option.some([...node.callbackBody])\n        : Option.none();\n    case 'decision':\n      return Option.some([...node.onTrue, ...(node.onFalse ?? [])]);\n    case 'switch':\n      return Option.some(node.cases.flatMap(c => [...c.body]));\n    case 'try-catch':\n      return Option.some([...node.tryBody, ...(node.catchBody ?? []), ...(node.finallyBody ?? [])]);\n    case 'terminal':\n      return node.value ? Option.some([...node.value]) : Option.none();\n    case 'opaque':\n      return Option.none();\n    default:\n      return Option.none();\n  }\n};\n\n// =============================================================================\n// Service Artifact Types (whole-codebase service mapping)\n// =============================================================================\n\n/**\n * A layer implementation that provides a service.\n */\nexport interface LayerImplementation {\n  /** Name of the layer variable (e.g. 'UserRepoLive') */\n  readonly name: string;\n  /** File where the layer is defined */\n  readonly filePath: string;\n  /** Source location of the layer definition */\n  readonly location: SourceLocation;\n  /** Layer kind */\n  readonly kind: 'effect' | 'succeed' | 'sync' | 'scoped' | 'other';\n  /** Services required by this layer implementation */\n  readonly requires: readonly string[];\n  /** IR of the layer's implementation body (if analyzable) */\n  readonly bodyIR?: StaticEffectIR | undefined;\n}\n\n/**\n * A reference to a program that consumes a service.\n */\nexport interface ServiceConsumerRef {\n  /** Program name that uses this service */\n  readonly programName: string;\n  /** File containing the program */\n  readonly filePath: string;\n  /** Location of the yield* call */\n  readonly location?: SourceLocation | undefined;\n}\n\n/**\n * First-class artifact for an Effect service, deduplicated at the project level.\n */\nexport interface ServiceArtifact {\n  /** Unique service identifier (tag string, e.g. 'UserRepo') */\n  readonly serviceId: string;\n  /** Class name (may differ from serviceId if tag string differs) */\n  readonly className: string;\n  /** File where the service tag class is defined */\n  readonly definitionFilePath: string;\n  /** Source location of the class declaration */\n  readonly definitionLocation: SourceLocation;\n  /** Interface shape (methods, properties) */\n  readonly definition: ServiceDefinition;\n  /** Full type text of the service interface */\n  readonly interfaceTypeText?: string | undefined;\n  /** Layer implementations that provide this service */\n  readonly layerImplementations: readonly LayerImplementation[];\n  /** Programs that consume (yield*) this service */\n  readonly consumers: readonly ServiceConsumerRef[];\n  /** Services this service's layers depend on (transitive requirements) */\n  readonly dependencies: readonly string[];\n}\n\n/**\n * Project-level deduplicated service map.\n */\nexport interface ProjectServiceMap {\n  /** Map from serviceId to its artifact */\n  readonly services: ReadonlyMap<string, ServiceArtifact>;\n  /** Services referenced but with no tag definition found */\n  readonly unresolvedServices: readonly string[];\n  /** Topological order of services (leaves first) */\n  readonly topologicalOrder: readonly string[];\n}\n\n// =============================================================================\n// Showcase Types\n// =============================================================================\n\nexport interface ShowcaseStepDetail {\n  readonly stepId: string;\n  readonly name: string;\n  readonly callee: string;\n  // Output type\n  readonly outputType: string;\n  readonly outputTypeKind: 'declared' | 'inferred' | 'unknown';\n  readonly outputTypeDisplay: string;\n  readonly outputTypeText: string;\n  // Error type\n  readonly errorTypeDisplay: string;\n  readonly errors: readonly string[];\n  // Dependency\n  readonly depSource?: string | undefined;\n  // Step kind\n  readonly stepKind?: string | undefined;\n  // Retry/timeout/resource/loop context (optional)\n  readonly retry?: { readonly attempts: number | 'unlimited'; readonly backoff: string } | undefined;\n  readonly timeout?: { readonly ms: string } | undefined;\n  readonly kind?: 'resource' | undefined;\n  readonly acquire?: string | undefined;\n  readonly use?: string | undefined;\n  readonly release?: string | undefined;\n  readonly repeats?: 'loop' | undefined;\n  readonly loopType?: string | undefined;\n  readonly iterationSource?: string | undefined;\n}\n\nexport interface ShowcaseEntry {\n  readonly title: string;\n  readonly code: string;\n  readonly mermaid: string;\n  readonly stepDetails: readonly ShowcaseStepDetail[];\n}\n","/**\n * Static Effect Analyzer\n *\n * Uses ts-morph to walk the TypeScript AST and extract Effect structure\n * without executing the code. Built entirely with Effect for composability.\n *\n * Public API: analyzeEffectFile, analyzeEffectSource, resetIdCounter.\n * Implementation is split across analysis-utils, analysis-patterns, alias-resolution,\n * program-discovery, effect-analysis, and core-analysis.\n */\n\nimport { Effect } from 'effect';\nimport {\n  loadTsMorph,\n  createProject,\n  createProjectFromSource,\n} from './ts-morph-loader';\nimport { AnalysisError } from './types';\nimport type { StaticEffectIR, AnalyzerOptions } from './types';\nimport { DEFAULT_OPTIONS, isJsOrJsxPath } from './analysis-utils';\nimport { findEffectPrograms } from './program-discovery';\nimport { analyzeProgram } from './core-analysis';\n\nexport { resetIdCounter } from './analysis-utils';\n\nexport const analyzeEffectFile = (\n  filePath: string,\n  options?: AnalyzerOptions,\n): Effect.Effect<readonly StaticEffectIR[], AnalysisError> =>\n  Effect.gen(function* () {\n    const opts = { ...DEFAULT_OPTIONS, ...options };\n    const { ts, Project } = loadTsMorph();\n\n    const project = yield* Effect.try({\n      try: () => {\n        if (isJsOrJsxPath(filePath)) {\n          return new Project({\n            skipAddingFilesFromTsConfig: true,\n            compilerOptions: { allowJs: true },\n          });\n        }\n        return createProject(opts.tsConfigPath);\n      },\n      catch: (error) =>\n        new AnalysisError(\n          'PROJECT_CREATION_FAILED',\n          `Failed to create project: ${String(error)}`,\n        ),\n    });\n\n    const existingFile = project.getSourceFile(filePath);\n    if (existingFile) {\n      project.removeSourceFile(existingFile);\n    }\n\n    const sourceFile = yield* Effect.try({\n      try: () => project.addSourceFileAtPath(filePath),\n      catch: (error) =>\n        new AnalysisError(\n          'FILE_NOT_FOUND',\n          `Failed to load file ${filePath}: ${String(error)}`,\n        ),\n    });\n\n    const programs = findEffectPrograms(sourceFile, opts);\n\n    if (programs.length === 0) {\n      return yield* Effect.fail(\n        new AnalysisError(\n          'NO_EFFECTS_FOUND',\n          `No Effect programs found in ${filePath}`,\n        ),\n      );\n    }\n\n    return yield* Effect.forEach(\n      programs,\n      (program) =>\n        analyzeProgram(program, sourceFile, filePath, opts, ts.version),\n      { concurrency: 'unbounded' },\n    );\n  });\n\nexport const analyzeEffectSource = (\n  code: string,\n  filePath = 'temp.ts',\n  options?: AnalyzerOptions,\n): Effect.Effect<readonly StaticEffectIR[], AnalysisError> =>\n  Effect.gen(function* () {\n    const opts = { ...DEFAULT_OPTIONS, ...options };\n    const { ts } = loadTsMorph();\n\n    const sourceFile = yield* Effect.try({\n      try: () => createProjectFromSource(code, filePath),\n      catch: (error) =>\n        new AnalysisError(\n          'SOURCE_PARSE_FAILED',\n          `Failed to parse source: ${String(error)}`,\n        ),\n    });\n\n    const programs = findEffectPrograms(sourceFile, opts);\n\n    if (programs.length === 0) {\n      return yield* Effect.fail(\n        new AnalysisError(\n          'NO_EFFECTS_FOUND',\n          `No Effect programs found in source`,\n        ),\n      );\n    }\n\n    return yield* Effect.forEach(\n      programs,\n      (program) =>\n        analyzeProgram(program, sourceFile, filePath, opts, ts.version),\n      { concurrency: 'unbounded' },\n    );\n  });\n","/**\n * Shared utilities for static Effect analysis: options, ID generation,\n * location/JSDoc extraction, dependency/error aggregation, program naming.\n */\n\nimport type {\n  Node,\n  VariableDeclaration,\n  PropertyAssignment,\n  CallExpression,\n  FunctionDeclaration,\n  ClassDeclaration,\n  PropertyDeclaration,\n  MethodDeclaration,\n  GetAccessorDeclaration,\n} from 'ts-morph';\nimport { Option } from 'effect';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  AnalysisStats,\n  AnalyzerOptions,\n  DependencyInfo,\n  JSDocTags,\n  SemanticRole,\n  SourceLocation,\n  StaticFlowNode,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { splitTopLevelUnion } from './type-extractor';\nimport { KNOWN_EFFECT_NAMESPACES, BUILT_IN_TYPE_NAMES } from './analysis-patterns';\n\nconst EFFECT_RUNTIME_PRIMITIVE_NAMES = new Set([\n  'Ref',\n  'SynchronizedRef',\n  'FiberRef',\n  'TxRef',\n  'TRef',\n  'Queue',\n  'TQueue',\n  'TxQueue',\n  'PubSub',\n  'TPubSub',\n  'Deferred',\n  'TDeferred',\n  'Semaphore',\n  'TSemaphore',\n  'SubscriptionRef',\n  'Mailbox',\n]);\n\nconst isRuntimePrimitiveDependency = (name: string): boolean => {\n  const firstSegment = name.split('.')[0] ?? name;\n  return EFFECT_RUNTIME_PRIMITIVE_NAMES.has(firstSegment);\n};\n\nconst CANONICAL_EFFECT_SERVICE_NAMES = new Map<string, string>([\n  ['FileSystem', 'FileSystem.FileSystem'],\n  ['Path', 'Path.Path'],\n  ['Terminal', 'Terminal.Terminal'],\n  ['Clock', 'Clock.Clock'],\n  ['Random', 'Random.Random'],\n  ['Console', 'Console.Console'],\n  ['Scope', 'Scope.Scope'],\n]);\n\nexport const canonicalizeServiceDisplayName = (name: string): string =>\n  CANONICAL_EFFECT_SERVICE_NAMES.get(name) ?? name;\n\n// =============================================================================\n// Default Options\n// =============================================================================\n\nexport const DEFAULT_OPTIONS: Required<AnalyzerOptions> = {\n  tsConfigPath: './tsconfig.json',\n  resolveReferences: true,\n  maxReferenceDepth: 5,\n  includeLocations: true,\n  assumeImported: false,\n  enableEffectWorkflow: false,\n  knownEffectInternalsRoot: undefined,\n  minDiscoveryConfidence: 'low',\n  onlyExportedPrograms: false,\n  enableEffectFlow: false,\n};\n\n// =============================================================================\n// ID Generation\n// =============================================================================\n\nlet idCounter = 0;\n\nexport const resetIdCounter = (): void => {\n  idCounter = 0;\n};\n\nexport const generateId = (): string => `effect-${++idCounter}`;\n\n// =============================================================================\n// Node text cache (reduce repeated getText() on large nodes - improve.md §7)\n// =============================================================================\n\nconst nodeTextCache = new WeakMap<Node, string>();\n\nexport function getNodeText(node: Node): string {\n  let text = nodeTextCache.get(node);\n  if (text === undefined) {\n    text = node.getText();\n    nodeTextCache.set(node, text);\n  }\n  return text;\n}\n\n// =============================================================================\n// Program-level aggregation (dependencies, error types)\n// =============================================================================\n\nexport function collectErrorTypes(nodes: readonly StaticFlowNode[]): string[] {\n  const set = new Set<string>();\n  const visit = (list: readonly StaticFlowNode[]) => {\n    for (const node of list) {\n      if (node.type === 'effect') {\n        const err = node.typeSignature?.errorType?.trim();\n        if (err && err !== 'never') {\n          for (const part of splitTopLevelUnion(err)) {\n            set.add(part);\n          }\n        }\n      }\n      const children = Option.getOrElse(getStaticChildren(node), () => []);\n      if (children.length > 0) visit(children);\n    }\n  };\n  visit(nodes);\n  return Array.from(set).sort();\n}\n\nexport function collectDependencies(nodes: readonly StaticFlowNode[]): DependencyInfo[] {\n  const byName = new Map<string, DependencyInfo>();\n  const visit = (list: readonly StaticFlowNode[]) => {\n    for (const node of list) {\n      if (node.type === 'effect') {\n        const reqs = (node).requiredServices;\n        if (reqs) {\n          for (const r of reqs) {\n            if (isRuntimePrimitiveDependency(r.serviceId)) continue;\n            const displayName = canonicalizeServiceDisplayName(r.serviceId);\n            if (!byName.has(displayName)) {\n              byName.set(displayName, {\n                name: displayName,\n                typeSignature: r.serviceType,\n                isLayer: false,\n              });\n            }\n          }\n        }\n\n        // Also collect from environment/service yields (yield* ServiceTag pattern)\n        // Include both 'environment' role and service-like callees (e.g., FileSystem.FileSystem, Config.string)\n        if ((node.semanticRole === 'environment' || node.semanticRole === 'side-effect') && node.callee) {\n          const callee = node.callee;\n          // Heuristic: service tags typically start with uppercase or are dotted identifiers like FileSystem.FileSystem\n          // Skip known Effect/JS namespaces and built-in types\n          const firstSegment = callee.split('.')[0] ?? callee;\n          const looksLikeService = /^[A-Z]/.test(callee)\n            && !KNOWN_EFFECT_NAMESPACES.has(firstSegment)\n            && !BUILT_IN_TYPE_NAMES.has(firstSegment);\n          if (isRuntimePrimitiveDependency(callee)) continue;\n          const displayName = canonicalizeServiceDisplayName(callee);\n          if (looksLikeService && !byName.has(displayName)) {\n            byName.set(displayName, {\n              name: displayName,\n              typeSignature: node.typeSignature?.requirementsType,\n              isLayer: false,\n            });\n          }\n        }\n      }\n      const children = Option.getOrElse(getStaticChildren(node), () => []);\n      if (children.length > 0) visit(children);\n    }\n  };\n  visit(nodes);\n  return Array.from(byName.values());\n}\n\n// =============================================================================\n// Source Location Extraction\n// =============================================================================\n\nexport const extractLocation = (\n  node: Node,\n  filePath: string,\n  includeLocations: boolean,\n): SourceLocation | undefined => {\n  if (!includeLocations) {\n    return undefined;\n  }\n\n  const sourceFile = node.getSourceFile();\n  const pos = node.getStart();\n  const { line, column } = sourceFile.getLineAndColumnAtPos(pos);\n  const endPos = node.getEnd();\n  const end = sourceFile.getLineAndColumnAtPos(endPos);\n\n  return {\n    filePath,\n    line,\n    column,\n    endLine: end.line,\n    endColumn: end.column,\n    offset: pos,\n    endOffset: endPos,\n  };\n};\n\n// =============================================================================\n// JSDoc Extraction\n// =============================================================================\n\n/**\n * Extract JSDoc description from a node.\n * Uses ts-morph's getJsDocs() method with fallback to leading comment ranges.\n * Extracts only the description text (before first @tag).\n */\nexport const extractJSDocDescription = (node: Node): string | undefined => {\n  // Try to get JSDoc from the node directly using ts-morph\n  const jsDocs = (\n    node as unknown as {\n      getJsDocs?: () => {\n        getText: () => string;\n        getComment?: () => string | { text: string }[];\n      }[];\n    }\n  ).getJsDocs?.();\n\n  if (jsDocs && jsDocs.length > 0) {\n    const firstJsDoc = jsDocs[0];\n    if (!firstJsDoc) return undefined;\n    const comment = firstJsDoc.getComment?.();\n\n    if (comment) {\n      // Handle both string and array comment formats\n      let description: string;\n      if (typeof comment === 'string') {\n        description = comment;\n      } else if (Array.isArray(comment)) {\n        description = comment.map((c) => c.text).join('\\n');\n      } else {\n        return undefined;\n      }\n\n      // Extract only the description (before first @tag)\n      const tagIndex = description.search(/\\n\\s*@/);\n      if (tagIndex !== -1) {\n        description = description.substring(0, tagIndex);\n      }\n\n      return description.trim() || undefined;\n    }\n\n    // Fallback to parsing the raw JSDoc text\n    const rawText = firstJsDoc.getText();\n    const descriptionMatch = /\\/\\*\\*\\s*\\n?\\s*\\*\\s*([^@]*?)(?=\\n\\s*\\*\\s*@|\\*\\/)/.exec(rawText);\n    if (descriptionMatch?.[1]) {\n      return (\n        descriptionMatch[1].replace(/\\n\\s*\\*\\s*/g, ' ').trim() || undefined\n      );\n    }\n  }\n\n  // Fallback: use leading comment ranges\n  const leadingComments = node.getLeadingCommentRanges();\n  if (leadingComments.length > 0) {\n    const lastComment = leadingComments[leadingComments.length - 1];\n    if (!lastComment) return undefined;\n\n    const commentText = lastComment.getText();\n\n    // Check if it's a JSDoc comment\n    if (commentText.startsWith('/**')) {\n      // Remove /** and */ and * prefixes\n      const cleaned = commentText\n        .replace(/^\\/\\*\\*\\s*/, '')\n        .replace(/\\s*\\*\\/\\s*$/, '')\n        .replace(/^\\s*\\*\\s?/gm, '')\n        .trim();\n\n      // Extract only the description (before first @tag)\n      const tagIndex = cleaned.search(/\\n@/);\n      if (tagIndex !== -1) {\n        return cleaned.substring(0, tagIndex).trim() || undefined;\n      }\n\n      return cleaned || undefined;\n    }\n  }\n\n  return undefined;\n};\n\n/**\n * Extract structured JSDoc tags (@param, @returns, @throws, @example) from a node.\n * Returns undefined if no structured tags are present.\n */\nexport const extractJSDocTags = (node: Node): JSDocTags | undefined => {\n  const tryGetJsDocText = (n: Node): string | undefined => {\n    const jsDocs = (\n      n as unknown as {\n        getJsDocs?: () => { getText: () => string }[];\n      }\n    ).getJsDocs?.();\n    if (jsDocs && jsDocs.length > 0) {\n      return jsDocs[0]!.getText();\n    }\n    // Fallback: leading comment ranges\n    const leadingComments = n.getLeadingCommentRanges();\n    if (leadingComments.length > 0) {\n      const lastComment = leadingComments[leadingComments.length - 1];\n      if (lastComment) {\n        const commentText = lastComment.getText();\n        if (commentText.startsWith('/**')) return commentText;\n      }\n    }\n    return undefined;\n  };\n\n  // Try the node itself first\n  let text = tryGetJsDocText(node);\n\n  // Walk up to find JSDoc on parent statement (same logic as getJSDocFromParentVariable)\n  if (!text) {\n    const { SyntaxKind } = loadTsMorph();\n    let current = node.getParent();\n    // Walk through CallExpression → ArrowFunction → VariableDeclaration → VariableDeclarationList → VariableStatement\n    while (current && !text) {\n      const kind = current.getKind();\n      if (kind === SyntaxKind.VariableStatement) {\n        text = tryGetJsDocText(current);\n        break;\n      }\n      if (kind === SyntaxKind.VariableDeclarationList) {\n        const grandparent = current.getParent();\n        if (grandparent) {\n          text = tryGetJsDocText(grandparent);\n        }\n        break;\n      }\n      // Keep walking up through CallExpression, ArrowFunction, VariableDeclaration\n      if (\n        kind === SyntaxKind.CallExpression ||\n        kind === SyntaxKind.ArrowFunction ||\n        kind === SyntaxKind.VariableDeclaration ||\n        kind === SyntaxKind.ParenthesizedExpression\n      ) {\n        current = current.getParent();\n      } else {\n        break;\n      }\n    }\n  }\n\n  if (!text) return undefined;\n  return parseJSDocTags(text);\n};\n\nfunction parseJSDocTags(rawText: string): JSDocTags | undefined {\n  const cleaned = rawText\n    .replace(/^\\/\\*\\*/, '')\n    .replace(/\\*\\/$/, '')\n    .split('\\n')\n    .map(line => line.replace(/^\\s*\\*\\s?/, ''))\n    .join('\\n');\n\n  const params: { name: string; description?: string }[] = [];\n  let returns: string | undefined;\n  const throws: string[] = [];\n  let example: string | undefined;\n\n  const tagPattern = /@(param|returns?|throws?|exception|example)\\s*(.*)/gi;\n  let match: RegExpExecArray | null;\n\n  while ((match = tagPattern.exec(cleaned)) !== null) {\n    const tag = match[1]!.toLowerCase();\n    const rest = match[2]!.trim();\n\n    if (tag === 'param') {\n      const paramMatch =\n        /^(?:\\{[^}]*\\}\\s*)?(\\[?\\w+(?:=[^\\]]*)?]?)\\s*(?:-\\s*(.*))?$/.exec(rest);\n      if (paramMatch) {\n        const name = paramMatch[1]!.replace(/^\\[|\\]$/g, '').replace(/=.*/, '');\n        const description = paramMatch[2]?.trim();\n        params.push(description ? { name, description } : { name });\n      }\n    } else if (tag === 'returns' || tag === 'return') {\n      returns = rest.replace(/^\\{[^}]*\\}\\s*/, '').trim() || undefined;\n    } else if (tag === 'throws' || tag === 'throw' || tag === 'exception') {\n      const value = rest.replace(/^\\{[^}]*\\}\\s*/, '').trim();\n      if (value) throws.push(value);\n    } else if (tag === 'example') {\n      // @example may span multiple lines until next @tag or end of comment\n      const exampleStart = match.index + match[0].length;\n      const nextTagMatch = /\\n\\s*@\\w/.exec(cleaned.slice(exampleStart));\n      if (nextTagMatch) {\n        const block = cleaned.slice(match.index + match[0].length - rest.length, exampleStart + nextTagMatch.index);\n        example = block.trim() || undefined;\n      } else {\n        const block = cleaned.slice(match.index + match[0].length - rest.length);\n        example = block.trim() || undefined;\n      }\n    }\n  }\n\n  if (params.length === 0 && !returns && throws.length === 0 && !example) {\n    return undefined;\n  }\n\n  return { params, returns, throws, example };\n}\n\n/**\n * Get JSDoc description from the parent variable declaration of a node.\n * Used to extract program-level JSDoc from the variable above an Effect program.\n */\nexport const getJSDocFromParentVariable = (node: Node): string | undefined => {\n  const parent = node.getParent();\n  const { SyntaxKind } = loadTsMorph();\n\n  if (parent) {\n    const parentKind = parent.getKind();\n\n    if (parentKind === SyntaxKind.VariableDeclaration) {\n      return extractJSDocDescription(parent);\n    }\n\n    // Check for arrow function assignment\n    if (parentKind === SyntaxKind.ArrowFunction) {\n      const grandparent = parent.getParent();\n      if (grandparent?.getKind() === SyntaxKind.VariableDeclaration) {\n        return extractJSDocDescription(grandparent);\n      }\n    }\n  }\n\n  return undefined;\n};\n\n// =============================================================================\n// Path / file helpers\n// =============================================================================\n\n/** Gap 6: .js/.jsx need allowJs and a minimal project so tsconfig does not exclude them. */\nexport function isJsOrJsxPath(path: string): boolean {\n  return path.endsWith('.js') || path.endsWith('.jsx');\n}\n\n// =============================================================================\n// EffectProgram type (used by program-discovery and core-analysis)\n// =============================================================================\n\nexport interface EffectProgram {\n  readonly name: string;\n  readonly discoveryConfidence?: 'high' | 'medium' | 'low';\n  readonly discoveryReason?: string;\n  readonly node: CallExpression | FunctionDeclaration | VariableDeclaration | ClassDeclaration\n    | PropertyDeclaration | MethodDeclaration | GetAccessorDeclaration;\n  readonly type: 'generator' | 'direct' | 'pipe' | 'run' | 'workflow-execute' | 'class' | 'classProperty' | 'classMethod' | 'functionDeclaration';\n}\n\n// =============================================================================\n// Program / yield name extraction\n// =============================================================================\n\nexport const extractYieldVariableName = (yieldNode: Node): string | undefined => {\n  const parent = yieldNode.getParent();\n  const { SyntaxKind } = loadTsMorph();\n\n  if (parent?.getKind() === SyntaxKind.VariableDeclaration) {\n    return (parent as VariableDeclaration).getName();\n  }\n\n  return undefined;\n};\n\nexport const extractProgramName = (node: Node): string | undefined => {\n  const { SyntaxKind } = loadTsMorph();\n  const getEnclosingVariableName = (start: Node): string | undefined => {\n    let current: Node | undefined = start;\n    while (current !== undefined) {\n      if (current.getKind() === SyntaxKind.VariableDeclaration) {\n        return (current as VariableDeclaration).getName();\n      }\n      current = current.getParent();\n    }\n    return undefined;\n  };\n\n  // Try to find the variable name this is assigned to\n  const parent = node.getParent();\n  if (parent) {\n    const parentKind = parent.getKind();\n\n    if (parentKind === SyntaxKind.VariableDeclaration) {\n      return (parent as VariableDeclaration).getName();\n    }\n\n    if (parentKind === SyntaxKind.AwaitExpression) {\n      const grandparent = parent.getParent();\n      if (grandparent?.getKind() === SyntaxKind.VariableDeclaration) {\n        return (grandparent as VariableDeclaration).getName();\n      }\n    }\n\n    if (parentKind === SyntaxKind.PropertyAssignment) {\n      const property = parent as PropertyAssignment;\n      const propertyName = property.getName();\n      const containerName = getEnclosingVariableName(parent);\n      return containerName ? `${containerName}.${propertyName}` : propertyName;\n    }\n\n    // Check for arrow function assignment\n    if (parentKind === SyntaxKind.ArrowFunction) {\n      const grandparent = parent.getParent();\n      if (grandparent?.getKind() === SyntaxKind.VariableDeclaration) {\n        return (grandparent as VariableDeclaration).getName();\n      }\n      if (grandparent?.getKind() === SyntaxKind.PropertyAssignment) {\n        const property = grandparent as PropertyAssignment;\n        const propertyName = property.getName();\n        const containerName = getEnclosingVariableName(grandparent);\n        return containerName ? `${containerName}.${propertyName}` : propertyName;\n      }\n    }\n  }\n\n  // Walk further up through DIRECT wrappers (CallExpression, ArrowFunction, FunctionExpression)\n  // Stop at function boundaries we're not an argument of\n  let ancestor: Node | undefined = node;\n  for (let depth = 0; ancestor && depth < 6; depth++) {\n    ancestor = ancestor.getParent();\n    if (!ancestor) break;\n\n    const kind = ancestor.getKind();\n\n    // Found a named container — use it\n    if (kind === SyntaxKind.VariableDeclaration) {\n      return (ancestor as VariableDeclaration).getName();\n    }\n\n    if (kind === SyntaxKind.PropertyAssignment) {\n      const property = ancestor as PropertyAssignment;\n      const propertyName = property.getName();\n      const containerName = getEnclosingVariableName(ancestor);\n      return containerName ? `${containerName}.${propertyName}` : propertyName;\n    }\n\n    // Stop walking up at Block/SourceFile — we've left the expression context\n    if (kind === SyntaxKind.Block || kind === SyntaxKind.SourceFile) break;\n  }\n\n  return undefined;\n};\n\n/**\n * Walk up the AST from a node to find an enclosing Effect.fn(\"name\") call.\n * Returns the name string if found, e.g., for Effect.gen inside Effect.fn(\"getUser\").\n */\nexport const extractEnclosingEffectFnName = (node: Node): string | undefined => {\n  const { SyntaxKind } = loadTsMorph();\n  let current: Node | undefined = node.getParent();\n  for (let depth = 0; current && depth < 10; depth++) {\n    if (current.getKind() === SyntaxKind.CallExpression) {\n      const callExpr = current as CallExpression;\n      const exprText = callExpr.getExpression().getText();\n      if (exprText === 'Effect.fn' || exprText.endsWith('.fn')) {\n        const args = callExpr.getArguments();\n        if (args.length > 0) {\n          const firstArg = args[0]!.getText();\n          // Extract string literal: \"name\" or 'name'\n          const match = /^[\"'](.+)[\"']$/.exec(firstArg);\n          if (match?.[1]) return match[1];\n        }\n      }\n    }\n    current = current.getParent();\n  }\n  return undefined;\n};\n\n// =============================================================================\n// Stats Helper\n// =============================================================================\n\nexport const createEmptyStats = (): AnalysisStats => ({\n  totalEffects: 0,\n  parallelCount: 0,\n  raceCount: 0,\n  errorHandlerCount: 0,\n  retryCount: 0,\n  timeoutCount: 0,\n  resourceCount: 0,\n  loopCount: 0,\n  conditionalCount: 0,\n  layerCount: 0,\n  interruptionCount: 0,\n  unknownCount: 0,\n  decisionCount: 0,\n  switchCount: 0,\n  tryCatchCount: 0,\n  terminalCount: 0,\n  opaqueCount: 0,\n});\n\n// =============================================================================\n// Display Name & Semantic Role Computation\n// =============================================================================\n\n/** Default max length for user-visible labels (diagrams, explain, IR display names). */\nexport const DEFAULT_LABEL_MAX = 60;\n\n/**\n * Truncate a string to `max` characters, appending an ellipsis if truncated.\n * Use for any user-facing label in output renderers.\n */\nexport function truncateDisplayText(s: string, max: number = DEFAULT_LABEL_MAX): string {\n  return s.length <= max ? s : `${s.slice(0, max)}…`;\n}\n\nconst truncate = truncateDisplayText;\n\n/**\n * Escape a label for a Mermaid node. Labels come from source text that may wrap\n * across lines, so whitespace runs collapse to a single space.\n */\nexport function escapeMermaidLabel(text: string): string {\n  return text\n    .replace(/\\s+/g, ' ')\n    .replace(/\"/g, '#quot;')\n    .replace(/</g, '#lt;')\n    .replace(/>/g, '#gt;')\n    .replace(/\\(/g, '#lpar;')\n    .replace(/\\)/g, '#rpar;');\n}\n\n/**\n * Extract a clean function name from a callee expression.\n *\n * For known Effect namespaces (Effect, Schema, Layer, etc.), strips the prefix:\n *   \"Effect.tryPromise\" → \"tryPromise\"\n *   \"Schema.decodeUnknown(UserSchema)\" → \"decodeUnknown\"\n *\n * For user/service objects, keeps the receiver for context:\n *   \"deps.convertCurrency\" → \"deps.convertCurrency\"\n *   \"config.getOrDefault\" → \"config.getOrDefault\"\n */\nexport function extractFunctionName(callee: string): string {\n  // Remove anything after opening paren (arguments)\n  const withoutArgs = callee.replace(/\\(.*$/, '');\n  const parts = withoutArgs.split('.');\n  if (parts.length <= 1) return withoutArgs;\n  // Strip known Effect namespace prefixes (Effect.X → X, Schema.X → X)\n  const receiver = parts[0] ?? '';\n  if (KNOWN_EFFECT_NAMESPACES.has(receiver) || BUILT_IN_TYPE_NAMES.has(receiver)) {\n    return parts[parts.length - 1] ?? withoutArgs;\n  }\n  // Keep receiver for user objects (deps.foo, config.bar)\n  return withoutArgs;\n}\n\n/**\n * Compute a human-readable display label for a StaticFlowNode.\n *\n * @param node - The node to label.\n * @param variableName - Optional variable name the result is assigned to (e.g. from a yield).\n */\nexport function computeDisplayName(node: StaticFlowNode, variableName?: string): string {\n  switch (node.type) {\n    case 'effect': {\n      const fnName = extractFunctionName(node.callee);\n      if (node.usePattern) {\n        const wrapper = node.serviceCall?.serviceType ?? node.usePattern.wrapperName;\n        return truncate(`${wrapper}.use`, 60);\n      }\n      if (variableName) {\n        return truncate(`${variableName} <- ${fnName}`, 60);\n      }\n      if (node.name) {\n        return truncate(`${node.name} <- ${fnName}`, 60);\n      }\n      return truncate(fnName, 60);\n    }\n\n    case 'generator':\n      return `Generator (${node.yields.length} yields)`;\n\n    case 'pipe':\n      return `Pipe (${node.transformations.length} steps)`;\n\n    case 'parallel':\n      return `${node.callee} (${node.children.length})`;\n\n    case 'race':\n      return `${node.callee} (${node.children.length} racing)`;\n\n    case 'error-handler':\n      return node.name ? `${node.name}: ${node.handlerType}` : node.handlerType;\n\n    case 'retry':\n      return node.schedule ? `retry: ${node.schedule}` : 'retry';\n\n    case 'timeout':\n      return node.duration ? `timeout: ${node.duration}` : 'timeout';\n\n    case 'resource':\n      return 'Resource';\n\n    case 'conditional':\n      return truncate(node.condition, 30);\n\n    case 'loop':\n      return node.iterSource ? truncate(`${node.loopType}(${node.iterSource})`, 60) : node.loopType;\n\n    case 'layer':\n      return node.isMerged ? 'Layer (merged)' : 'Layer';\n\n    case 'stream': {\n      const ops = node.pipeline.map((op) => op.operation);\n      const parts: string[] = ['Stream', ...ops];\n      if (node.sink) parts.push(node.sink);\n      return truncate(parts.join(' → '), 60);\n    }\n\n    case 'concurrency-primitive':\n      return `${node.primitive}.${node.operation}`;\n\n    case 'fiber': {\n      const op = node.operation;\n      if (node.isDaemon) return `${op} (daemon)`;\n      if (node.isScoped) return `${op} (scoped)`;\n      return op;\n    }\n\n    case 'transform':\n      return node.transformType;\n\n    case 'match':\n      return `Match.${node.matchOp}`;\n\n    case 'cause':\n      return `Cause.${node.causeOp}`;\n\n    case 'exit':\n      return `Exit.${node.exitOp}`;\n\n    case 'schedule':\n      return `Schedule.${node.scheduleOp}`;\n\n    case 'interruption':\n      return node.interruptionType;\n\n    case 'channel': {\n      const channelOps = node.pipeline.map((op) => op.operation);\n      return channelOps.length > 0 ? `Channel: ${channelOps.join(' → ')}` : 'Channel';\n    }\n\n    case 'sink': {\n      const sinkOps = node.pipeline.map((op) => op.operation);\n      return sinkOps.length > 0 ? `Sink: ${sinkOps.join(' → ')}` : 'Sink';\n    }\n\n    case 'decision':\n      return truncate(node.condition, 30);\n\n    case 'switch':\n      return `switch(${truncate(node.expression, 25)})`;\n\n    case 'try-catch':\n      return 'try/catch';\n\n    case 'terminal':\n      return node.label ? `${node.terminalKind} ${node.label}` : node.terminalKind;\n\n    case 'opaque':\n      return `Opaque: ${truncate(node.reason, 25)}`;\n\n    case 'unknown':\n      return `Unknown: ${truncate(node.reason, 30)}`;\n  }\n}\n\n// =============================================================================\n// Node Counting\n// =============================================================================\n\n/**\n * Count non-unknown nodes in an IR tree, recursing into children.\n */\nexport const countMeaningfulNodes = (nodes: readonly StaticFlowNode[]): number => {\n  let count = 0;\n  const walk = (list: readonly StaticFlowNode[]) => {\n    for (const node of list) {\n      if (node.type !== 'unknown') count++;\n      const children = Option.getOrElse(getStaticChildren(node), () => [] as readonly StaticFlowNode[]);\n      if (children.length > 0) walk(children);\n    }\n  };\n  walk(nodes);\n  return count;\n};\n\n/**\n * Classify a StaticFlowNode into a SemanticRole for display styling and filtering.\n */\nexport function computeSemanticRole(node: StaticFlowNode): SemanticRole {\n  switch (node.type) {\n    case 'effect': {\n      // Service call detection: explicit serviceCall/serviceMethod fields\n      if (node.serviceCall || node.serviceMethod || node.usePattern) return 'service-call';\n      // Description-based heuristic: descriptions mentioning \"service\" or \"layer\"\n      const desc = node.description?.toLowerCase() ?? '';\n      if (desc.includes('service')) return 'service-call';\n      if (desc.includes('layer') || node.provideKind === 'layer') return 'layer';\n      // Callee-based classification\n      const callee = node.callee.toLowerCase();\n      // Context/service tag access (yield* UserRepo / yield* AppConfig) is environment read, not side effect.\n      if (/^[A-Z][A-Za-z0-9_]*$/.test(node.callee) && !node.constructorKind) {\n        return 'environment';\n      }\n      if (\n        callee.includes('sync') ||\n        callee.includes('promise') ||\n        callee.includes('async') ||\n        callee.includes('log') ||\n        callee.includes('console')\n      ) {\n        return 'side-effect';\n      }\n      if (\n        callee.includes('succeed') ||\n        callee.includes('fail') ||\n        callee.includes('die') ||\n        callee.includes('void') ||\n        callee.includes('never') ||\n        callee.includes('gen') ||\n        callee.includes('make') ||\n        node.constructorKind\n      ) {\n        return 'constructor';\n      }\n      return 'side-effect';\n    }\n\n    case 'generator':\n    case 'pipe':\n      return 'constructor';\n\n    case 'parallel':\n    case 'race':\n    case 'concurrency-primitive':\n      return 'concurrency';\n\n    case 'error-handler':\n    case 'cause':\n    case 'exit':\n      return 'error-handler';\n\n    case 'retry':\n    case 'timeout':\n    case 'schedule':\n      return 'scheduling';\n\n    case 'resource':\n      return 'resource';\n\n    case 'conditional':\n    case 'loop':\n    case 'match':\n    case 'decision':\n    case 'switch':\n    case 'terminal':\n      return 'control-flow';\n\n    case 'try-catch':\n      return 'error-handler';\n\n    case 'opaque':\n      return 'unknown';\n\n    case 'layer':\n      return 'layer';\n\n    case 'stream':\n    case 'channel':\n    case 'sink':\n      return 'stream';\n\n    case 'fiber':\n    case 'interruption':\n      return 'fiber';\n\n    case 'transform':\n      return 'transform';\n\n    case 'unknown':\n      return 'unknown';\n  }\n}\n\n/**\n * Unwrap TypeScript expression wrappers: parenthesized, as, non-null,\n * satisfies, type assertion.\n *\n * A type assertion is not a program. `Effect.succeed(1) as Effect.Effect<number>`\n * is the same effect as `Effect.succeed(1)`, and every analyzer that reads an\n * expression needs to look through the wrapper before deciding what it is.\n *\n * Lives here rather than in `core-analysis.ts`, where it started, because\n * `effect-analysis.ts` needs the same rule and `core-analysis` already imports\n * from it. Both import this module, and this module imports neither.\n */\nexport function unwrapExpression(expr: Node): Node {\n  const { SyntaxKind } = loadTsMorph();\n  switch (expr.getKind()) {\n    case SyntaxKind.ParenthesizedExpression:\n    case SyntaxKind.AsExpression:\n    case SyntaxKind.TypeAssertionExpression:\n    case SyntaxKind.NonNullExpression:\n    case SyntaxKind.SatisfiesExpression:\n      return unwrapExpression(\n        (expr as unknown as { getExpression(): Node }).getExpression(),\n      );\n    default:\n      return expr;\n  }\n}\n","/**\n * Type Signature Extractor\n *\n * Uses ts-morph's TypeChecker to extract Effect type parameters:\n * - A (Success type)\n * - E (Error type)\n * - R (Requirements/Context type)\n */\n\nimport type { Type, Node, TypeChecker, VariableDeclaration, CallExpression, PropertyAccessExpression } from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  EffectTypeSignature,\n  ServiceRequirement,\n  SourceLocation,\n  StreamTypeSignature,\n  LayerTypeSignature,\n  ScheduleTypeSignature,\n  CauseTypeSignature,\n} from './types';\n\n// =============================================================================\n// Type Extraction\n// =============================================================================\n\n/** Regex to parse Effect<A, E, R> from type text when Type API fails */\nconst EFFECT_TYPE_REGEX_3 = /Effect(?:\\.Effect)?<([^,]+),\\s*([^,]+),\\s*([^>]+)>/;\n/** Regex to parse Effect<A, E> (2 params, R defaults to never) */\nconst EFFECT_TYPE_REGEX_2 = /Effect(?:\\.Effect)?<([^,>]+),\\s*([^,>]+)>/;\n\n/**\n * Build EffectTypeSignature from type text using regex (fallback when Type API has no type args).\n */\nexport function effectTypeSignatureFromTypeText(\n  typeText: string,\n): EffectTypeSignature | undefined {\n  const clean = (s: string) =>\n    s\n      .replace(/import\\([^)]+\\)\\./g, '')\n      .replace(/typeof\\s+/g, '')\n      .trim()\n      .substring(0, 200);\n\n  // Try 3-param: Effect<A, E, R>\n  const match3 = EFFECT_TYPE_REGEX_3.exec(typeText);\n  if (match3) {\n    return {\n      successType: clean(match3[1]!),\n      errorType: clean(match3[2]!),\n      requirementsType: clean(match3[3]!),\n      isInferred: false,\n      typeConfidence: 'inferred',\n      rawTypeString: typeText,\n    };\n  }\n\n  // Try 2-param: Effect<A, E> (R defaults to never)\n  const match2 = EFFECT_TYPE_REGEX_2.exec(typeText);\n  if (match2) {\n    return {\n      successType: clean(match2[1]!),\n      errorType: clean(match2[2]!),\n      requirementsType: 'never',\n      isInferred: false,\n      typeConfidence: 'inferred',\n      rawTypeString: typeText,\n    };\n  }\n\n  return undefined;\n}\n\n/**\n * When an error type is a single-letter generic (e.g., \"E\"), try to resolve\n * the concrete type from the inner expression (pipe base or call argument).\n */\nfunction tryResolveGenericFromInnerExpression(\n  node: Node,\n  typeChecker: TypeChecker,\n): { errorType: string } | undefined {\n  try {\n    const { SyntaxKind } = loadTsMorph();\n    if (node.getKind() === SyntaxKind.CallExpression) {\n      const call = node as CallExpression;\n      const expr = call.getExpression();\n      // For pipe chains: base.pipe(Effect.withSpan(\"x\")) — check the base expression\n      if (expr.getKind() === SyntaxKind.PropertyAccessExpression) {\n        const propAccess = expr as PropertyAccessExpression;\n        if (propAccess.getName() === 'pipe') {\n          const baseExpr = propAccess.getExpression();\n          if (baseExpr) {\n            const baseSig = extractEffectTypeSignature(baseExpr, typeChecker);\n            if (baseSig && !/^[A-Z]$/.test(baseSig.errorType)) {\n              return { errorType: baseSig.errorType };\n            }\n          }\n        }\n      }\n      // For curried calls: Effect.withSpan(\"name\")(effect) — check the argument\n      const args = call.getArguments();\n      if (args.length > 0) {\n        for (const arg of args) {\n          const argSig = extractEffectTypeSignature(arg, typeChecker);\n          if (argSig && !/^[A-Z]$/.test(argSig.errorType)) {\n            return { errorType: argSig.errorType };\n          }\n        }\n      }\n    }\n  } catch {\n    // Type resolution can fail; return undefined\n  }\n  return undefined;\n}\n\n/**\n * Extract Effect type signature from a node\n */\nexport const extractEffectTypeSignature = (\n  node: Node,\n  _typeChecker: TypeChecker,\n): EffectTypeSignature | undefined => {\n  // Get the type of the node (can throw when type checker is unavailable)\n  let nodeType;\n  try {\n    nodeType = node.getType();\n  } catch {\n    return undefined;\n  }\n\n  // Check if it's an Effect type\n  if (!isEffectType(nodeType)) {\n    return undefined;\n  }\n\n  // Extract type arguments (A, E, R)\n  const typeArgs = extractTypeArguments(nodeType);\n\n  if (typeArgs) {\n    const [aType, eType, rType] = typeArgs;\n    const errorTypeStr = typeToString(eType);\n\n    // If errorType is a single-letter type parameter (e.g. \"E\"), try to resolve\n    // from the call's inner expression type\n    if (/^[A-Z]$/.test(errorTypeStr)) {\n      const resolved = tryResolveGenericFromInnerExpression(node, _typeChecker);\n      if (resolved) {\n        return {\n          successType: typeToString(aType),\n          errorType: resolved.errorType,\n          requirementsType: typeToString(rType),\n          isInferred: true,\n          typeConfidence: 'inferred',\n          rawTypeString: nodeType.getText(),\n        };\n      }\n    }\n\n    return {\n      successType: typeToString(aType),\n      errorType: errorTypeStr,\n      requirementsType: typeToString(rType),\n      isInferred: true,\n      typeConfidence: 'declared',\n      rawTypeString: nodeType.getText(),\n    };\n  }\n\n  // Fallback: parse A, E, R from type text when Type API doesn't provide type args\n  const typeText = nodeType.getText();\n  const fromText = effectTypeSignatureFromTypeText(typeText);\n  if (fromText) {\n    const eTrim = fromText.errorType.trim();\n    if (/^[A-Z]$/.test(eTrim)) {\n      const resolved = tryResolveGenericFromInnerExpression(node, _typeChecker);\n      if (resolved) {\n        return {\n          ...fromText,\n          errorType: resolved.errorType,\n          isInferred: true,\n          typeConfidence: 'inferred',\n          rawTypeString: nodeType.getText(),\n        };\n      }\n    }\n    return fromText;\n  }\n\n  // Fallback: resolve the callee function's return type annotation\n  const fromCallee = tryExtractFromCalleeReturnType(node);\n  if (fromCallee) return fromCallee;\n\n  return {\n    successType: 'unknown',\n    errorType: 'never',\n    requirementsType: 'never',\n    isInferred: false,\n    typeConfidence: 'unknown',\n    rawTypeString: typeText,\n  };\n};\n\n/**\n * When a call expression's resolved type lacks type args, try to extract\n * Effect<A, E, R> from the callee function's declared return type annotation.\n *\n * For `yield* validate(input)` where `validate` is declared as:\n *   `const validate = (input: T): Effect.Effect<A, E, R> => ...`\n * We resolve `validate` → get its return type annotation text → parse Effect<A, E, R>.\n */\nfunction tryExtractFromCalleeReturnType(node: Node): EffectTypeSignature | undefined {\n  try {\n    // Only works for call expressions\n    if (!('getExpression' in node)) return undefined;\n    const call = node as CallExpression;\n    const callee = call.getExpression();\n\n    // Try to get the callee's return type from its signature\n    const calleeType = callee.getType();\n    const callSignatures = calleeType.getCallSignatures();\n    if (callSignatures.length > 0) {\n      const returnType = callSignatures[0]!.getReturnType();\n\n      // Try type arguments on the return type\n      const returnArgs = extractTypeArguments(returnType);\n      if (returnArgs) {\n        const [aType, eType, rType] = returnArgs;\n        return {\n          successType: typeToString(aType),\n          errorType: typeToString(eType),\n          requirementsType: typeToString(rType),\n          isInferred: true,\n          typeConfidence: 'inferred',\n          rawTypeString: returnType.getText(),\n        };\n      }\n\n      // Try regex on the return type text\n      const returnText = returnType.getText();\n      const fromReturnText = effectTypeSignatureFromTypeText(returnText);\n      if (fromReturnText) return fromReturnText;\n    }\n\n    // Try to resolve the callee to its declaration and read the return type annotation\n    const symbol = callee.getSymbol();\n    if (!symbol) return undefined;\n\n    for (const decl of symbol.getDeclarations()) {\n      // Get the return type annotation text from the declaration\n      let returnTypeText: string | undefined;\n\n      if ('getReturnType' in decl) {\n        // Function/method declarations\n        const declType = (decl as { getReturnType: () => Type }).getReturnType();\n        returnTypeText = declType.getText();\n      } else if ('getType' in decl) {\n        // Variable declarations: get the type of the variable, then its call signatures\n        const varType = (decl as { getType: () => Type }).getType();\n        const sigs = varType.getCallSignatures();\n        if (sigs.length > 0) {\n          const retType = sigs[0]!.getReturnType();\n          const retArgs = extractTypeArguments(retType);\n          if (retArgs) {\n            const [aType, eType, rType] = retArgs;\n            return {\n              successType: typeToString(aType),\n              errorType: typeToString(eType),\n              requirementsType: typeToString(rType),\n              isInferred: true,\n              typeConfidence: 'inferred',\n              rawTypeString: retType.getText(),\n            };\n          }\n          returnTypeText = retType.getText();\n        }\n      }\n\n      if (returnTypeText) {\n        const fromAnnotation = effectTypeSignatureFromTypeText(returnTypeText);\n        if (fromAnnotation) {\n          return { ...fromAnnotation, typeConfidence: 'inferred' };\n        }\n      }\n    }\n  } catch {\n    // Callee resolution can fail for dynamic or unresolvable expressions\n  }\n  return undefined;\n}\n\n/**\n * Check if a type is an Effect type\n */\nconst isEffectType = (type: Type): boolean => {\n  const symbol = type.getSymbol();\n  const typeText = type.getText();\n  \n  // Check by symbol name\n  if (symbol) {\n    const name = symbol.getName();\n    if (name === 'Effect' || name.includes('Effect')) {\n      return true;\n    }\n  }\n  \n  // Check by type text pattern\n  if (typeText.includes('Effect<') || typeText.startsWith('Effect.')) {\n    return true;\n  }\n  \n  // Check for Effect interface\n  const aliasSymbol = type.getAliasSymbol();\n  if (aliasSymbol) {\n    const aliasName = aliasSymbol.getName();\n    if (aliasName === 'Effect' || aliasName.includes('Effect')) {\n      return true;\n    }\n  }\n  \n  return false;\n};\n\n/**\n * Extract type arguments from an Effect type\n * Returns [A, E, R] or undefined\n */\nconst extractTypeArguments = (type: Type): [Type, Type, Type] | undefined => {\n  try {\n    const typeArgs = type.getTypeArguments?.();\n    if (!typeArgs || typeArgs.length < 3) {\n      const aliasTypeArgs = type.getAliasTypeArguments?.();\n      if (aliasTypeArgs && aliasTypeArgs.length >= 3) {\n        return [aliasTypeArgs[0]!, aliasTypeArgs[1]!, aliasTypeArgs[2]!];\n      }\n      return undefined;\n    }\n    return [typeArgs[0]!, typeArgs[1]!, typeArgs[2]!];\n  } catch {\n    return undefined;\n  }\n};\n\n/**\n * Convert a Type to a readable string\n */\nconst typeToString = (type: Type): string => {\n  const text = type.getText();\n  \n  // Clean up the type string\n  return text\n    .replace(/import\\([^)]+\\)\\./g, '') // Remove import paths\n    .replace(/typeof\\s+/g, '') // Remove typeof\n    .substring(0, 200); // Limit length\n};\n\n// =============================================================================\n// Service Requirement Extraction\n// =============================================================================\n\n/**\n * Extract service requirements from a Context type\n */\nexport const extractServiceRequirements = (\n  node: Node,\n  _typeChecker: TypeChecker,\n): ServiceRequirement[] => {\n  const requirements: ServiceRequirement[] = [];\n  \n  // Try to get the type - first from the node, then from type annotation\n  let nodeType = node.getType();\n  let locationNode: Node = node;\n  \n  // If node type doesn't have the required info, try to get declared type from variable\n  let nodeTypeArgs: readonly Type[] | undefined;\n  try {\n    nodeTypeArgs = typeof nodeType.getTypeArguments === 'function' ? nodeType.getTypeArguments() : undefined;\n  } catch {\n    nodeTypeArgs = undefined;\n  }\n  if (!nodeTypeArgs || nodeTypeArgs.length < 3) {\n    const parent = node.getParent();\n    if (parent?.getKindName() === 'VariableDeclaration') {\n      const varDecl = parent as VariableDeclaration;\n      const declaredType = varDecl.getType();\n      if (declaredType) {\n        nodeType = declaredType;\n        locationNode = varDecl;\n      }\n    }\n  }\n  \n  // Check if type contains Context requirements\n  const rType = extractRequirementsType(nodeType);\n  if (!rType) return requirements;\n  \n  // Extract individual services from the Context type\n  const services = extractServicesFromContext(rType);\n  \n  for (const service of services) {\n    const sourceFile = locationNode.getSourceFile();\n    const offset = locationNode.getStart();\n    const { line, column } = sourceFile.getLineAndColumnAtPos(offset);\n    const location: SourceLocation = {\n      filePath: sourceFile.getFilePath(),\n      line,\n      column,\n      offset,\n    };\n    \n    requirements.push({\n      serviceId: service.id,\n      serviceType: service.typeName,\n      requiredAt: location,\n    });\n  }\n  \n  return requirements;\n};\n\n/**\n * Extract the R (requirements) type from an Effect type\n */\nconst extractRequirementsType = (type: Type): Type | undefined => {\n  const typeArgs = extractTypeArguments(type);\n  if (!typeArgs) return undefined;\n  \n  return typeArgs[2]; // R is the third type parameter\n};\n\n/**\n * Extract individual service types from a Context type\n */\nconst extractServicesFromContext = (contextType: Type): { id: string; typeName: string }[] => {\n  const services: { id: string; typeName: string }[] = [];\n  \n  // Check if it's Context<Tag>\n  const typeText = contextType.getText();\n  \n  // Try to extract Tag identifier from Context<Tag>\n  const contextMatch = /Context<([^>]+)>/.exec(typeText);\n  if (contextMatch) {\n    const tagType = contextMatch[1]!;\n    services.push({\n      id: extractTagIdentifier(tagType),\n      typeName: tagType,\n    });\n  }\n  \n  // Check for intersection types (Context<A> | Context<B>)\n  if (typeText.includes('|')) {\n    const parts = splitTopLevelUnion(typeText);\n    for (const part of parts) {\n      const match = /Context<([^>]+)>/.exec(part);\n      if (match) {\n        services.push({\n          id: extractTagIdentifier(match[1]!),\n          typeName: match[1]!,\n        });\n      }\n    }\n  }\n  \n  // Check for never type (no requirements)\n  if (typeText === 'never' || typeText === '{}') {\n    return [];\n  }\n  \n  return services;\n};\n\n/**\n * Extract tag identifier from a Tag type string\n */\nconst extractTagIdentifier = (tagType: string): string => {\n  // Try to extract from Tag<\"identifier\", ...>\n  const match = /Tag<[\"']([^\"']+)[\"']/.exec(tagType);\n  if (match) {\n    return match[1]!;\n  }\n  \n  // Fallback: use the type name\n  return tagType.split('<')[0]!.trim();\n};\n\n// =============================================================================\n// Type Transformation Tracking\n// =============================================================================\n\n/**\n * Track how an Effect type transforms through a pipe operation\n */\nexport const trackTypeTransformation = (\n  inputType: EffectTypeSignature,\n  operation: string,\n  outputType: EffectTypeSignature,\n): { operation: string; typeChange: string } => {\n  const changes: string[] = [];\n  \n  if (inputType.successType !== outputType.successType) {\n    changes.push(`${inputType.successType} → ${outputType.successType}`);\n  }\n  \n  if (inputType.errorType !== outputType.errorType) {\n    changes.push(`${inputType.errorType} → ${outputType.errorType}`);\n  }\n  \n  if (inputType.requirementsType !== outputType.requirementsType) {\n    changes.push(`${inputType.requirementsType} → ${outputType.requirementsType}`);\n  }\n  \n  return {\n    operation,\n    typeChange: changes.length > 0 ? changes.join(', ') : 'no change',\n  };\n};\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Split a type string on top-level `|` only, respecting angle brackets and string literals.\n * e.g. `Envelope<\"A\" | \"B\"> | FooError` → `[\"Envelope<\\\"A\\\" | \\\"B\\\">\", \"FooError\"]`\n */\nexport function splitTopLevelUnion(typeText: string): string[] {\n  const parts: string[] = [];\n  let current = '';\n  let depth = 0;      // angle bracket depth\n  let inString: string | null = null;\n\n  for (let i = 0; i < typeText.length; i++) {\n    const ch = typeText[i]!;\n\n    if (inString) {\n      current += ch;\n      if (ch === inString && typeText[i - 1] !== '\\\\') {\n        inString = null;\n      }\n      continue;\n    }\n\n    if (ch === '\"' || ch === \"'\" || ch === '`') {\n      inString = ch;\n      current += ch;\n      continue;\n    }\n\n    if (ch === '<' || ch === '(') {\n      depth++;\n      current += ch;\n      continue;\n    }\n\n    if (ch === '>' || ch === ')') {\n      depth = Math.max(0, depth - 1);\n      current += ch;\n      continue;\n    }\n\n    if (ch === '|' && depth === 0) {\n      parts.push(current.trim());\n      current = '';\n      continue;\n    }\n\n    current += ch;\n  }\n\n  const last = current.trim();\n  if (last) parts.push(last);\n\n  return parts.filter(Boolean);\n}\n\n/**\n * Format type signature for display\n */\nexport const formatTypeSignature = (sig: EffectTypeSignature): string => {\n  return `Effect<${sig.successType}, ${sig.errorType}, ${sig.requirementsType}>`;\n};\n\n// =============================================================================\n// Stream / Layer / Schedule / Cause type extraction (21.3)\n// =============================================================================\n\nconst cleanTypeArg = (s: string): string =>\n  s\n    .replace(/import\\([^)]+\\)\\./g, '')\n    .replace(/typeof\\s+/g, '')\n    .trim()\n    .substring(0, 200);\n\n/** Regexes for type args when Type API has no type arguments */\nconst STREAM_TYPE_REGEX = /Stream<([^,]+),\\s*([^,]+),\\s*([^>]+)>/;\nconst LAYER_TYPE_REGEX = /Layer<([^,]+),\\s*([^,]+),\\s*([^>]+)>/;\nconst SCHEDULE_TYPE_REGEX = /Schedule<([^,]+),\\s*([^,]+),\\s*([^>]+)>/;\nconst CAUSE_TYPE_REGEX = /Cause<([^>]+)>/;\n\n/**\n * Extract Stream<A, E, R> type args from a node's type (regex fallback).\n */\nexport function extractStreamTypeSignature(node: Node): StreamTypeSignature | undefined {\n  const typeText = node.getType().getText();\n  const match = STREAM_TYPE_REGEX.exec(typeText);\n  if (!match) return undefined;\n  return {\n    successType: cleanTypeArg(match[1]!),\n    errorType: cleanTypeArg(match[2]!),\n    requirementsType: cleanTypeArg(match[3]!),\n    rawTypeString: typeText,\n  };\n}\n\n/**\n * Extract Layer<ROut, E, RIn> type args from a node's type (regex fallback).\n */\nexport function extractLayerTypeSignature(node: Node): LayerTypeSignature | undefined {\n  const typeText = node.getType().getText();\n  const match = LAYER_TYPE_REGEX.exec(typeText);\n  if (!match) return undefined;\n  return {\n    providedType: cleanTypeArg(match[1]!),\n    errorType: cleanTypeArg(match[2]!),\n    requiredType: cleanTypeArg(match[3]!),\n    rawTypeString: typeText,\n  };\n}\n\n/**\n * Extract Schedule<Out, In, R> type args from a node's type (regex fallback).\n */\nexport function extractScheduleTypeSignature(node: Node): ScheduleTypeSignature | undefined {\n  const typeText = node.getType().getText();\n  const match = SCHEDULE_TYPE_REGEX.exec(typeText);\n  if (!match) return undefined;\n  return {\n    outputType: cleanTypeArg(match[1]!),\n    inputType: cleanTypeArg(match[2]!),\n    requirementsType: cleanTypeArg(match[3]!),\n    rawTypeString: typeText,\n  };\n}\n\n/**\n * Extract Cause<E> type arg from a node's type (regex fallback).\n */\nexport function extractCauseTypeSignature(node: Node): CauseTypeSignature | undefined {\n  const typeText = node.getType().getText();\n  const match = CAUSE_TYPE_REGEX.exec(typeText);\n  if (!match) return undefined;\n  return {\n    errorType: cleanTypeArg(match[1]!),\n    rawTypeString: typeText,\n  };\n}\n\n// =============================================================================\n// Schema\n// =============================================================================\n\n/**\n * Check if a type is a Schema type\n */\nexport const isSchemaType = (type: Type): boolean => {\n  const symbol = type.getSymbol();\n  if (symbol) {\n    const name = symbol.getName();\n    return name === 'Schema' || name.includes('Schema');\n  }\n  \n  const typeText = type.getText();\n  return typeText.includes('Schema<') || typeText.startsWith('Schema.');\n};\n\n/**\n * Extract Schema validation information\n */\nexport const extractSchemaInfo = (type: Type): { encoded: string; decoded: string } | undefined => {\n  if (!isSchemaType(type)) return undefined;\n  \n  const typeArgs = type.getTypeArguments();\n  if (typeArgs.length >= 2) {\n    return {\n      encoded: typeToString(typeArgs[1]!),\n      decoded: typeToString(typeArgs[0]!),\n    };\n  }\n  \n  return undefined;\n};\n","/**\n * Pattern maps and semantic helpers for Effect API detection and classification.\n */\n\nimport type {\n  Node,\n  CallExpression,\n  PropertyAccessExpression,\n  ObjectLiteralExpression,\n  PropertyAssignment,\n  Block,\n  AwaitExpression,\n  ConditionalExpression,\n  PrefixUnaryExpression,\n  ArrowFunction,\n  FunctionExpression,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  StaticTransformNode,\n  StaticMatchNode,\n  StaticCauseNode,\n  StaticExitNode,\n  StaticScheduleNode,\n} from './types';\n\n// =============================================================================\n// Error / conditional / resource / collection / fiber patterns\n// =============================================================================\n\nexport const ERROR_HANDLER_PATTERNS = [\n  '.catch',\n  '.catchTag',\n  '.catchCause',\n  '.catchIf',\n  '.catchSome',\n  '.catchSomeCause',\n  '.catchSomeDefect',\n  '.catchDefect',\n  '.catchTags',\n  '.orElse',\n  '.orElseFail',\n  '.orElseSucceed',\n  '.orDie',\n  '.orDieWith',\n  '.flip',\n  '.mapError',\n  '.mapErrorCause',\n  '.mapBoth',\n  '.sandbox',\n  '.unsandbox',\n  '.parallelErrors',\n  '.filterOrDie',\n  '.filterOrDieMessage',\n  '.filterOrElse',\n  '.filterOrFail',\n  '.match',\n  '.matchCause',\n  '.matchEffect',\n  '.matchCauseEffect',\n  '.firstSuccessOf',\n  '.ignore',\n  '.ignoreLogged',\n  '.eventually',\n];\n\nexport const CONDITIONAL_PATTERNS = [\n  '.if',\n  '.when',\n  '.whenEffect',\n  '.whenFiberRef',\n  '.whenRef',\n  '.unless',\n  '.unlessEffect',\n  '.option',\n  '.either',\n  '.exit',\n  '.liftPredicate',\n];\n\nexport const RESOURCE_PATTERNS = [\n  '.acquireRelease',\n  '.acquireUseRelease',\n  '.ensuring',\n  '.addFinalizer',\n  '.onExit',\n  '.onError',\n  '.parallelFinalizers',\n  '.sequentialFinalizers',\n  '.finalizersMask',\n  '.using',\n  '.withEarlyRelease',\n];\n\nexport const COLLECTION_PATTERNS = [\n  '.forEach',\n  '.loop',\n  '.filter',\n  '.filterMap',\n  '.partition',\n  '.reduce',\n  '.reduceRight',\n  '.reduceWhile',\n  '.reduceEffect',\n  '.dropUntil',\n  '.dropWhile',\n  '.takeUntil',\n  '.takeWhile',\n  '.every',\n  '.exists',\n  '.findFirst',\n  '.head',\n  '.mergeAll',\n  '.replicate',\n  '.replicateEffect',\n  '.validateAll',\n  '.validateFirst',\n  '.validate',\n  '.validateWith',\n];\n\nexport const FIBER_PATTERNS = [\n  'Effect.fork',\n  '.fork',\n  '.forkAll',\n  '.forkIn',\n  '.forkWithErrorHandler',\n  'Fiber.',\n];\n\n// =============================================================================\n// Transform / Match / Cause / Exit / Schedule ops\n// =============================================================================\n\nexport const TRANSFORM_OPS: Record<string, StaticTransformNode['transformType']> = {\n  'Effect.map': 'map',\n  'Effect.flatMap': 'flatMap',\n  'Effect.andThen': 'andThen',\n  'Effect.tap': 'tap',\n  'Effect.tapBoth': 'tapBoth',\n  'Effect.tapError': 'tapError',\n  'Effect.tapErrorTag': 'tapErrorTag',\n  'Effect.tapErrorCause': 'tapErrorCause',\n  'Effect.tapDefect': 'tapDefect',\n  'Effect.zipLeft': 'zipLeft',\n  'Effect.zipRight': 'zipRight',\n  'Effect.zipWith': 'zipWith',\n  'Effect.zip': 'zip',\n  'Effect.as': 'as',\n  'Effect.asVoid': 'asVoid',\n  'Effect.asSome': 'asSome',\n  'Effect.asSomeError': 'asSomeError',\n  'Effect.flatten': 'flatten',\n  'Effect.ap': 'ap',\n  'Effect.negate': 'negate',\n  'Effect.merge': 'merge',\n};\nexport const EFFECTFUL_TRANSFORMS = new Set(['flatMap', 'andThen', 'tapBoth', 'tapError', 'tapErrorTag', 'tapErrorCause', 'tapDefect', 'zipWith', 'zipLeft', 'zipRight', 'zip', 'ap', 'flatten']);\nexport const isTransformCall = (callee: string): boolean => callee in TRANSFORM_OPS;\n\nexport const MATCH_OP_MAP: Record<string, StaticMatchNode['matchOp']> = {\n  'Match.type': 'type',\n  'Match.tag': 'tag',\n  'Match.value': 'value',\n  'Match.when': 'when',\n  'Match.whenOr': 'whenOr',\n  'Match.whenAnd': 'whenAnd',\n  'Match.not': 'not',\n  'Match.is': 'is',\n  'Match.exhaustive': 'exhaustive',\n  'Match.orElse': 'orElse',\n  'Match.option': 'option',\n  'Match.either': 'either',\n  'Match.discriminator': 'discriminator',\n  'Match.discriminatorsExhaustive': 'discriminatorsExhaustive',\n  'Match.tags': 'tags',\n  'Match.tagsExhaustive': 'tagsExhaustive',\n  'Match.withReturnType': 'withReturnType',\n  'Match.run': 'run',\n};\nexport const EXHAUSTIVE_OPS = new Set(['exhaustive', 'discriminatorsExhaustive', 'tagsExhaustive']);\nexport const isMatchCall = (callee: string): boolean =>\n  callee.startsWith('Match.') && callee in MATCH_OP_MAP;\n\nexport const CAUSE_OP_MAP: Record<string, StaticCauseNode['causeOp']> = {\n  'Cause.fail': 'fail',\n  'Cause.die': 'die',\n  'Cause.interrupt': 'interrupt',\n  'Cause.parallel': 'parallel',\n  'Cause.sequential': 'sequential',\n  'Cause.empty': 'empty',\n  'Cause.failures': 'failures',\n  'Cause.defects': 'defects',\n  'Cause.interruptors': 'interruptors',\n  'Cause.squash': 'squash',\n  'Cause.squashWith': 'squashWith',\n  'Cause.pretty': 'pretty',\n  'Cause.flatten': 'flatten',\n  'Cause.isDie': 'isDie',\n  'Cause.isFailure': 'isFailure',\n  'Cause.isInterrupted': 'isInterrupted',\n  'Cause.isEmpty': 'isEmpty',\n  'Cause.map': 'map',\n  'Cause.filter': 'filter',\n};\nexport const CAUSE_CONSTRUCTORS = new Set(['fail', 'die', 'interrupt', 'parallel', 'sequential', 'empty']);\nexport const isCauseCall = (callee: string): boolean =>\n  callee.startsWith('Cause.') && callee in CAUSE_OP_MAP;\n\nexport const EXIT_OP_MAP: Record<string, StaticExitNode['exitOp']> = {\n  'Exit.succeed': 'succeed',\n  'Exit.fail': 'fail',\n  'Exit.die': 'die',\n  'Exit.interrupt': 'interrupt',\n  'Exit.void': 'void',\n  'Exit.unit': 'unit',\n  'Exit.match': 'match',\n  'Exit.isSuccess': 'isSuccess',\n  'Exit.isFailure': 'isFailure',\n  'Exit.isInterrupted': 'isInterrupted',\n  'Exit.when': 'when',\n  'Exit.whenEffect': 'whenEffect',\n  'Exit.exists': 'exists',\n  'Exit.contains': 'contains',\n  'Exit.flatten': 'flatten',\n  'Exit.map': 'map',\n  'Exit.mapBoth': 'mapBoth',\n  'Exit.mapError': 'mapError',\n  'Exit.flatMap': 'flatMap',\n  'Exit.zipWith': 'zipWith',\n  'Exit.tap': 'tap',\n  'Exit.tapBoth': 'tapBoth',\n  'Exit.tapError': 'tapError',\n};\nexport const EXIT_CONSTRUCTORS = new Set(['succeed', 'fail', 'die', 'interrupt', 'void', 'unit']);\nexport const isExitCall = (callee: string): boolean =>\n  callee.startsWith('Exit.') && (callee in EXIT_OP_MAP || /^Exit\\.\\w+$/.test(callee));\n\nexport const SCHEDULE_OP_MAP: Record<string, StaticScheduleNode['scheduleOp']> = {\n  'Schedule.exponential': 'exponential',\n  'Schedule.fibonacci': 'fibonacci',\n  'Schedule.spaced': 'spaced',\n  'Schedule.fixed': 'fixed',\n  'Schedule.linear': 'linear',\n  'Schedule.cron': 'cron',\n  'Schedule.windowed': 'windowed',\n  'Schedule.duration': 'duration',\n  'Schedule.elapsed': 'elapsed',\n  'Schedule.delays': 'delays',\n  'Schedule.once': 'once',\n  'Schedule.stop': 'stop',\n  'Schedule.count': 'count',\n  'Schedule.forever': 'forever',\n  'Schedule.jittered': 'jittered',\n  'Schedule.andThen': 'andThen',\n  'Schedule.intersect': 'intersect',\n  'Schedule.union': 'union',\n  'Schedule.compose': 'compose',\n  'Schedule.zipWith': 'zipWith',\n  'Schedule.addDelay': 'addDelay',\n  'Schedule.modifyDelay': 'modifyDelay',\n  'Schedule.check': 'check',\n  'Schedule.resetAfter': 'resetAfter',\n  'Schedule.resetWhen': 'resetWhen',\n  'Schedule.ensure': 'ensure',\n  'Schedule.driver': 'driver',\n  'Schedule.mapInput': 'mapInput',\n};\nexport const isScheduleCall = (callee: string): boolean =>\n  callee.startsWith('Schedule.') && (callee in SCHEDULE_OP_MAP || /^Schedule\\.\\w+$/.test(callee));\n\nexport const INTERRUPTION_PATTERNS = [\n  '.interruptible',\n  '.uninterruptible',\n  '.interruptibleMask',\n  '.uninterruptibleMask',\n  '.onInterrupt',\n  '.disconnect',\n  '.allowInterrupt',\n  'Effect.interrupt',\n  '.interruptWith',\n];\n\nexport const DO_NOTATION_PATTERNS = [\n  '.Do',\n  '.bind',\n  '.bindAll',\n  '.bindTo',\n];\n\nexport const CACHING_PATTERNS = [\n  '.cached',\n  '.cachedWithTTL',\n  '.cachedInvalidateWithTTL',\n  '.cachedFunction',\n  '.once',\n  'Cache.',\n  'ScopedCache.',\n];\n\n// =============================================================================\n// API prefixes and built-in / service classification\n// =============================================================================\n\nexport const API_PREFIXES = [\n  'Effect.',\n  'Layer.',\n  'Schedule.',\n  'Stream.',\n  'Queue.',\n  'PubSub.',\n  'Deferred.',\n  'Semaphore.',\n  'Mailbox.',\n  'SubscriptionRef.',\n  'Scope.',\n  'Fiber.',\n  'Runtime.',\n  'ManagedRuntime.',\n  'NodeRuntime.',\n  'BunRuntime.',\n  'DenoRuntime.',\n  'Cause.',\n  'Exit.',\n  'Data.',\n  'Option.',\n  'Either.',\n  'Chunk.',\n  'HashMap.',\n  'HashSet.',\n  'List.',\n  'SortedMap.',\n  'SortedSet.',\n  'RedBlackTree.',\n  'Trie.',\n  'Graph.',\n  'Match.',\n  'Config.',\n  'Schema.',\n  'Cache.',\n  'ScopedCache.',\n  'RcRef.',\n  'RcMap.',\n  'Reloadable.',\n  'Cache.',\n  'ScopedCache.',\n  'RateLimiter.',\n  'PartitionedSemaphore.',\n  'FiberSet.',\n  'FiberMap.',\n  'FiberHandle.',\n  'Metric.',\n  'Logger.',\n  'Tracer.',\n  'Context.',\n  'HttpClient.',\n  'HttpRouter.',\n  'HttpApi.',\n  'FileSystem.',\n  'Command.',\n  'Socket.',\n  'SocketServer.',\n  'Worker.',\n  'Terminal.',\n  'KeyValueStore.',\n  'Multipart.',\n  'Ndjson.',\n  'MsgPack.',\n  'OpenApi.',\n  'OpenApiJsonSchema.',\n  'Brand.',\n  'Encoding.',\n  'Predicate.',\n  'DateTime.',\n  'Cron.',\n  'BigDecimal.',\n  'HashRing.',\n  'Redacted.',\n  'GlobalValue.',\n  'Channel.',\n  'Sink.',\n  'CliApp.',\n  'Args.',\n  'Options.',\n  'AiModel.',\n  'AiToolkit.',\n  'Completions.',\n  'AiInput.',\n  'AiResponse.',\n  'NodeSdk.',\n  'WebSdk.',\n  'Entity.',\n  'ClusterSchema.',\n  'MessageState.',\n  'Sharding.',\n  'RpcGroup.',\n  'RpcApi.',\n  'RpcClient.',\n  'RpcRouter.',\n  'SqlResolver.',\n  'SqlMigrator.',\n  'Printer.',\n  'Doc.',\n  'DocTree.',\n  'PageWidth.',\n  'Optimize.',\n];\n\nexport const BUILT_IN_TYPE_NAMES = new Set([\n  'Array', 'ReadonlyArray', 'String', 'Number', 'Boolean', 'Object',\n  'Function', 'Promise', 'Math', 'Date', 'RegExp', 'Error', 'Map',\n  'Set', 'WeakMap', 'WeakSet', 'Symbol', 'BigInt', 'JSON', 'Console',\n  'process', 'Buffer', 'EventEmitter', 'Window', 'Document', 'AbortController',\n]);\n\nexport const KNOWN_EFFECT_NAMESPACES = new Set([\n  // Core runtime — these are never services themselves\n  'Effect', 'Layer', 'Stream', 'Queue', 'PubSub', 'Deferred', 'Semaphore',\n  'Mailbox', 'SubscriptionRef', 'Scope', 'Fiber', 'Runtime', 'ManagedRuntime', 'Cause', 'Exit',\n  // Data types\n  'Data', 'Option', 'Either', 'Chunk', 'HashMap', 'HashSet', 'List',\n  'SortedMap', 'SortedSet',\n  // Matching, config, schema (S is a common alias for Schema)\n  'Match', 'Config', 'Schema', 'Schedule', 'S',\n  // Observability\n  'Metric', 'Tracer', 'Logger',\n  // Fiber management\n  'FiberRef', 'FiberHandle', 'FiberSet', 'FiberMap',\n  // Caching\n  'Cache', 'ScopedCache', 'RateLimiter', 'Supervisor',\n  // Refs and state\n  'Ref', 'SynchronizedRef', 'Context',\n  // Pure utilities — never services\n  'Random', 'Clock', 'Duration', 'DateTime', 'Predicate', 'Tuple', 'Struct',\n  'Record', 'Encoding', 'Order', 'Equivalence', 'Brand', 'Inspectable',\n  'Equal', 'Hash', 'Differ', 'Types', 'Unify', 'Pipeable',\n  // Streams / channels / sinks\n  'Sink', 'Channel', 'GroupBy', 'Take',\n  // STM\n  'STM', 'TRef', 'TMap', 'TSet', 'TArray', 'TQueue', 'TPubSub', 'TDeferred', 'TSemaphore',\n  // HTTP request/response builders — utility namespaces, not services\n  'HttpClientRequest', 'HttpClientResponse', 'HttpClientError',\n  'HttpServerRequest', 'HttpServerResponse', 'HttpRouter', 'HttpApiEndpoint',\n  'HttpApiGroup', 'HttpApi', 'HttpApiBuilder', 'HttpApiSecurity', 'HttpMiddleware',\n  'FetchHttpClient', 'NodeHttpClient', 'BunHttpClient',\n  // Command (the Effect platform process command, not a service)\n  'Command',\n  // SQL utilities\n  'SqlSchema', 'SqlResolver', 'SqlMigrator',\n  // RPC utilities\n  'Rpc', 'RpcRouter', 'RpcGroup', 'RpcApi', 'RpcSerialization',\n  // Cluster / distributed\n  'Entity', 'ClusterSchema', 'MessageState', 'Sharding',\n  // Printer / docs\n  'Printer', 'Doc', 'DocTree', 'PageWidth', 'Optimize',\n  // AI\n  'AiToolkit', 'Completions', 'AiInput', 'AiResponse',\n  // OpenTelemetry\n  'NodeSdk', 'WebSdk',\n]);\n\nexport const isServiceTagCallee = (callee: string): boolean => {\n  if (callee.includes('.')) return false;\n  if (KNOWN_EFFECT_NAMESPACES.has(callee)) return false;\n  return /^[A-Z][A-Za-z0-9]*$/.test(callee);\n};\n\n// =============================================================================\n// Semantic description and alias-aware helpers\n// =============================================================================\n\nexport const getSemanticDescription = (callee: string): string | undefined => {\n  if (callee.startsWith('Channel.')) return 'channel';\n  if (callee.startsWith('Sink.')) return 'sink';\n  if (callee.endsWith('.never')) return 'never';\n  if (callee.endsWith('.void')) return 'void-effect';\n  if (callee.endsWith('.fromNullable')) return 'null-coalescing';\n  if (callee.endsWith('.fn')) return 'function-lift';\n  if (callee.endsWith('.fnUntraced')) return 'function-lift';\n  if (\n    callee.includes('.async') ||\n    callee.includes('.asyncEffect') ||\n    callee.includes('.promise') ||\n    callee.includes('.sync') ||\n    callee.includes('.suspend') ||\n    callee.includes('.succeed') ||\n    callee.includes('.fail') ||\n    callee.includes('.try')\n  ) return 'constructor';\n  if (INTERRUPTION_PATTERNS.some((p) => callee.includes(p))) return 'interruption';\n  if (DO_NOTATION_PATTERNS.some((p) => callee.includes(p))) return 'do-notation';\n  if (CACHING_PATTERNS.some((p) => callee.includes(p) || callee.startsWith(p))) return 'caching';\n  if (ERROR_HANDLER_PATTERNS.some((p) => callee.includes(p))) return 'error-handler';\n  if (CONDITIONAL_PATTERNS.some((p) => callee.includes(p))) return 'conditional';\n  if (RESOURCE_PATTERNS.some((p) => callee.includes(p))) return 'resource';\n  if (COLLECTION_PATTERNS.some((p) => callee.includes(p))) return 'collection';\n  if (FIBER_PATTERNS.some((p) => callee.includes(p))) return 'fiber';\n  if (callee.startsWith('Stream.')) return 'stream';\n  if (callee.startsWith('Layer.')) return 'layer';\n  if (callee.startsWith('Schema.')) return 'schema';\n  if (callee.startsWith('Config.')) return 'config';\n  if (callee.startsWith('Cause.')) return 'cause';\n  if (callee.startsWith('Exit.')) return 'exit';\n  if (callee === 'Data.tagged' || callee === 'Data.taggedEnum') return 'tagged-enum';\n  if (callee.startsWith('Data.')) return 'data';\n  if (callee.startsWith('Option.')) return 'option';\n  if (callee.startsWith('Either.')) return 'either';\n  if (callee.startsWith('Match.')) return 'match';\n  if (callee.startsWith('ManagedRuntime.')) return 'runtime';\n  if (callee.startsWith('Runtime.')) return 'runtime';\n  if (callee.startsWith('NodeRuntime.') || callee.startsWith('BunRuntime.') || callee.startsWith('DenoRuntime.')) return 'runtime';\n  if (callee.startsWith('Scope.')) return 'scope';\n  if (callee.startsWith('ScopedRef.') || callee.startsWith('RcRef.') || callee.startsWith('RcMap.')) return 'resource-ref';\n  if (callee.startsWith('Reloadable.') || callee.startsWith('Resource.')) return 'reloadable';\n  if (callee.startsWith('Micro.')) return 'micro';\n  if (callee.startsWith('Brand.')) return 'brand';\n  if (callee.startsWith('Encoding.')) return 'encoding';\n  if (callee.startsWith('Predicate.')) return 'predicate';\n  if (callee.startsWith('DateTime.')) return 'datetime';\n  if (callee.startsWith('Cron.')) return 'cron';\n  if (callee.startsWith('Redacted.')) return 'redacted';\n  if (callee.startsWith('GlobalValue.')) return 'global-value';\n  if (callee.startsWith('Supervisor.')) return 'supervisor';\n  if (\n    callee.includes('.locally') ||\n    callee.includes('.locallyWith') ||\n    callee.includes('.locallyScoped') ||\n    callee.includes('.getFiberRefs') ||\n    callee.includes('.setFiberRefs') ||\n    callee.includes('.inheritFiberRefs') ||\n    callee.includes('FiberRef.')\n  ) return 'fiberref';\n  if (\n    callee.includes('.withConcurrency') ||\n    callee.includes('.withScheduler') ||\n    callee.includes('.withSchedulingPriority') ||\n    callee.includes('.daemonChildren') ||\n    callee.includes('.awaitAllChildren') ||\n    callee.includes('.supervised')\n  ) return 'structured-concurrency';\n  if (\n    callee.startsWith('Context.pick') ||\n    callee.startsWith('Context.omit')\n  ) return 'context';\n  if (\n    callee === 'Effect.provide' ||\n    (callee.startsWith('Effect.') && callee.includes('.provide') && !callee.includes('provideService'))\n  ) return 'context';\n  if (\n    callee.includes('.serviceOption') ||\n    callee.includes('.serviceOptional') ||\n    callee.includes('.serviceFunction') ||\n    callee.includes('.serviceFunctionEffect') ||\n    callee.includes('.serviceFunctions') ||\n    callee.includes('.serviceConstants') ||\n    callee.includes('.serviceMembers') ||\n    callee.includes('.updateService')\n  ) return 'service';\n  if (\n    callee.startsWith('CliApp.') ||\n    callee.startsWith('Args.') ||\n    callee.startsWith('Options.')\n  ) return 'cli';\n  if (\n    callee.startsWith('AiModel.') ||\n    callee.startsWith('AiToolkit.') ||\n    callee.startsWith('Completions.') ||\n    callee.startsWith('AiInput.') ||\n    callee.startsWith('AiResponse.')\n  ) return 'ai';\n  if (\n    callee.startsWith('NodeSdk.') ||\n    callee.startsWith('WebSdk.') ||\n    callee.startsWith('OtelMetrics.')\n  ) return 'opentelemetry';\n  if (\n    callee.startsWith('Entity.') ||\n    callee.startsWith('ClusterSchema.') ||\n    callee.startsWith('MessageState.') ||\n    callee.startsWith('Sharding.')\n  ) return 'cluster';\n  if (\n    callee.startsWith('RpcGroup.') ||\n    callee.startsWith('RpcApi.') ||\n    callee.startsWith('RpcClient.') ||\n    callee.startsWith('RpcRouter.')\n  ) return 'rpc';\n  if (\n    callee.startsWith('SqlResolver.') ||\n    callee.startsWith('SqlMigrator.')\n  ) return 'sql';\n  if (callee.startsWith('DevTools.') || callee.startsWith('Server.')) return 'devtools';\n  if (callee.startsWith('BigDecimal.')) return 'big-decimal';\n  if (callee.startsWith('Graph.')) return 'graph';\n  if (callee.startsWith('HashRing.')) return 'hash-ring';\n  if (callee.startsWith('Chunk.')) return 'chunk';\n  if (callee.startsWith('HashMap.') || callee.startsWith('HashSet.')) return 'immutable-collection';\n  if (\n    callee.startsWith('List.') ||\n    callee.startsWith('SortedMap.') ||\n    callee.startsWith('SortedSet.') ||\n    callee.startsWith('RedBlackTree.') ||\n    callee.startsWith('Trie.')\n  ) return 'immutable-collection';\n  if (\n    callee.includes('.map') ||\n    callee.includes('.flatMap') ||\n    callee.includes('.andThen') ||\n    callee.includes('.tap') ||\n    callee.includes('.tapBoth') ||\n    callee.includes('.tapError') ||\n    callee.includes('.tapErrorTag') ||\n    callee.includes('.tapErrorCause') ||\n    callee.includes('.tapDefect') ||\n    callee.includes('.zip') ||\n    callee.includes('.zipLeft') ||\n    callee.includes('.zipRight') ||\n    callee.includes('.zipWith') ||\n    callee.includes('.as') ||\n    callee.includes('.asVoid') ||\n    callee.includes('.flatten') ||\n    callee.includes('.merge') ||\n    callee.includes('.ap') ||\n    callee.includes('.validate') ||\n    callee.includes('.negate')\n  ) return 'transformation';\n  if (\n    callee.startsWith('Printer.') ||\n    callee.startsWith('Doc.') ||\n    callee.startsWith('DocTree.') ||\n    callee.startsWith('PageWidth.') ||\n    callee.startsWith('Optimize.')\n  ) return 'printer';\n  if (\n    callee.startsWith('Http') ||\n    callee.startsWith('FileSystem.') ||\n    callee.startsWith('Command.') ||\n    callee.startsWith('Socket.') ||\n    callee.startsWith('Worker.')\n  ) return 'platform';\n  if (callee.includes('channel.') && !callee.includes('Channel')) return 'channel';\n  return undefined;\n};\n\nexport const getSemanticDescriptionWithAliases = (\n  callee: string,\n  effectAliases?: Set<string>,\n): string | undefined => {\n  const direct = getSemanticDescription(callee);\n  if (direct) return direct;\n\n  if (effectAliases) {\n    const dotIndex = callee.indexOf('.');\n    if (dotIndex > 0) {\n      const prefix = callee.substring(0, dotIndex);\n      if (effectAliases.has(prefix)) {\n        const method = callee.substring(dotIndex + 1);\n        return getSemanticDescription(`Effect.${method}`);\n      }\n    }\n  }\n  return undefined;\n};\n\nexport const isLikelyDirectEffectInitializer = (\n  initializer: Node,\n  effectImportNames: Set<string>,\n  nonProgramEffectImportNames: Set<string> = new Set(),\n): boolean => {\n  const { SyntaxKind } = loadTsMorph();\n  const isNonProgramName = (name: string): boolean => nonProgramEffectImportNames.has(name);\n  const isRunEntrypointCalleeText = (exprText: string): boolean =>\n    /\\.run(?:Promise(?:Exit)?|Sync(?:Exit)?|Fork|Callback|Main)$/.test(exprText) ||\n    /^Runtime\\.run(?:Promise|Sync|Fork)$/.test(exprText);\n  const isDirectEffectCalleeText = (exprText: string): boolean => {\n    if (isRunEntrypointCalleeText(exprText)) {\n      return false;\n    }\n    const isPipeCall = exprText === 'pipe' || exprText.endsWith('.pipe');\n    const dotIndex = exprText.indexOf('.');\n    if (dotIndex > 0 && isNonProgramName(exprText.slice(0, dotIndex))) {\n      return false;\n    }\n    return (\n      isPipeCall ||\n      [...effectImportNames].some((alias) => exprText.startsWith(`${alias}.`))\n    );\n  };\n\n  const isLikelyEffectCall = (call: CallExpression): boolean => {\n    const callee = call.getExpression();\n    const exprText = callee.getText();\n    if (isRunEntrypointCalleeText(exprText)) {\n      return false;\n    }\n    const isPipeCall = exprText === 'pipe';\n    const isMethodPipeCall =\n      callee.getKind() === SyntaxKind.PropertyAccessExpression &&\n      (callee as PropertyAccessExpression).getName() === 'pipe';\n    if (isPipeCall || isMethodPipeCall) {\n      const argsContainEffect = call.getArguments().some((arg) =>\n        isLikelyDirectEffectInitializer(arg, effectImportNames, nonProgramEffectImportNames)\n      );\n      if (argsContainEffect) {\n        return true;\n      }\n      if (isMethodPipeCall) {\n        const base = (callee as PropertyAccessExpression).getExpression();\n        return isLikelyDirectEffectInitializer(\n          base,\n          effectImportNames,\n          nonProgramEffectImportNames,\n        );\n      }\n      return false;\n    }\n    if (\n      callee.getKind() === SyntaxKind.Identifier &&\n      effectImportNames.has(exprText) &&\n      !isNonProgramName(exprText)\n    ) {\n      return true;\n    }\n    if (isDirectEffectCalleeText(exprText)) {\n      return true;\n    }\n\n    // Builder / wrapper chains: inspect call receiver and arguments for effectful callbacks,\n    // e.g. make(() => Effect.never).identified(\"Never\")\n    if (\n      callee.getKind() === SyntaxKind.PropertyAccessExpression &&\n      isLikelyDirectEffectInitializer(\n        (callee as PropertyAccessExpression).getExpression(),\n        effectImportNames,\n        nonProgramEffectImportNames,\n      )\n    ) {\n      return true;\n    }\n\n    return call.getArguments().some((arg) =>\n      isLikelyDirectEffectInitializer(arg, effectImportNames, nonProgramEffectImportNames)\n    );\n  };\n\n  /** True when `node` is NOT inside a nested function/arrow/method relative to `scope`. */\n  const isInSameScope = (node: Node, scope: Node): boolean => {\n    let current = node.getParent();\n    while (current && current !== scope) {\n      const k = current.getKind();\n      if (\n        k === SyntaxKind.FunctionDeclaration ||\n        k === SyntaxKind.FunctionExpression ||\n        k === SyntaxKind.ArrowFunction ||\n        k === SyntaxKind.MethodDeclaration ||\n        k === SyntaxKind.GetAccessor ||\n        k === SyntaxKind.SetAccessor ||\n        k === SyntaxKind.ClassDeclaration ||\n        k === SyntaxKind.ClassExpression ||\n        k === SyntaxKind.Constructor ||\n        k === SyntaxKind.ClassStaticBlockDeclaration\n      ) {\n        return false;\n      }\n      current = current.getParent();\n    }\n    return true;\n  };\n\n  const blockContainsEffectLikeUsage = (block: import('ts-morph').Block): boolean => {\n    const callExprs = block.getDescendantsOfKind(SyntaxKind.CallExpression);\n    if (callExprs.some((call) => isInSameScope(call, block) && isLikelyEffectCall(call))) {\n      return true;\n    }\n\n    const awaitedExprs = block.getDescendantsOfKind(SyntaxKind.AwaitExpression);\n    if (\n      awaitedExprs.some((awaitExpr) =>\n        isInSameScope(awaitExpr, block) &&\n        isLikelyDirectEffectInitializer(awaitExpr, effectImportNames, nonProgramEffectImportNames)\n      )\n    ) {\n      return true;\n    }\n\n    const propertyAccessExprs = block.getDescendantsOfKind(\n      SyntaxKind.PropertyAccessExpression,\n    );\n    return propertyAccessExprs.some((expr) =>\n      isInSameScope(expr, block) &&\n      isLikelyDirectEffectInitializer(expr, effectImportNames, nonProgramEffectImportNames)\n    );\n  };\n\n  const blockContainsRunEntrypointUsage = (block: import('ts-morph').Block): boolean =>\n    block\n      .getDescendantsOfKind(SyntaxKind.CallExpression)\n      .some((call) => isInSameScope(call, block) && isRunEntrypointCalleeText((call).getExpression().getText()));\n\n  if (initializer.getKind() === SyntaxKind.ObjectLiteralExpression) {\n    const obj = initializer as ObjectLiteralExpression;\n    return obj.getProperties().some((prop) => {\n      if (\n        prop.getKind() === SyntaxKind.PropertyAssignment ||\n        prop.getKind() === SyntaxKind.ShorthandPropertyAssignment\n      ) {\n        const init =\n          prop.getKind() === SyntaxKind.PropertyAssignment\n            ? (prop as PropertyAssignment).getInitializer()\n            : undefined;\n        return init\n          ? isLikelyDirectEffectInitializer(init, effectImportNames, nonProgramEffectImportNames)\n          : false;\n      }\n      if (\n        prop.getKind() === SyntaxKind.MethodDeclaration ||\n        prop.getKind() === SyntaxKind.GetAccessor ||\n        prop.getKind() === SyntaxKind.SetAccessor\n      ) {\n        const body = (\n          prop as\n            | import('ts-morph').MethodDeclaration\n            | import('ts-morph').GetAccessorDeclaration\n            | import('ts-morph').SetAccessorDeclaration\n        ).getBody();\n        return body\n          ? blockContainsEffectLikeUsage(body as Block)\n          : false;\n      }\n      return false;\n    });\n  }\n\n  if (\n    initializer.getKind() === SyntaxKind.ArrowFunction ||\n    initializer.getKind() === SyntaxKind.FunctionExpression\n  ) {\n    const fn = initializer as ArrowFunction | FunctionExpression;\n    const body = fn.getBody();\n\n    if (body.getKind() === SyntaxKind.Block) {\n      const bodyBlock = body as Block;\n      // Check return statements in the current function scope (if/else/switch branches)\n      // but NOT those inside nested functions/callbacks.\n      const returnStmts = bodyBlock.getDescendantsOfKind(SyntaxKind.ReturnStatement);\n      const hasEffectReturn = returnStmts.some((ret) => {\n        if (!isInSameScope(ret, bodyBlock)) return false;\n        const expr = ret.getExpression();\n        return expr !== undefined && isLikelyDirectEffectInitializer(\n          expr,\n          effectImportNames,\n          nonProgramEffectImportNames,\n        );\n      });\n      if (hasEffectReturn) {\n        return true;\n      }\n      // Only fall back to body heuristic if no run* entrypoint is present —\n      // a function that merely executes an Effect (runSync/runPromise/…)\n      // without returning one is not itself an Effect program.\n      if (blockContainsRunEntrypointUsage(bodyBlock)) {\n        return false;\n      }\n      return blockContainsEffectLikeUsage(bodyBlock);\n    }\n\n    return isLikelyDirectEffectInitializer(body, effectImportNames, nonProgramEffectImportNames);\n  }\n\n  if (initializer.getKind() === SyntaxKind.CallExpression) {\n    return isLikelyEffectCall(initializer as CallExpression);\n  }\n\n  if (initializer.getKind() === SyntaxKind.AwaitExpression) {\n    const awaited = (\n      initializer as AwaitExpression\n    ).getExpression();\n    if (awaited.getKind() !== SyntaxKind.CallExpression) {\n      return false;\n    }\n    return isLikelyEffectCall(awaited as CallExpression);\n  }\n\n  if (initializer.getKind() === SyntaxKind.ConditionalExpression) {\n    const conditional = initializer as ConditionalExpression;\n    return (\n      isLikelyDirectEffectInitializer(\n        conditional.getWhenTrue(),\n        effectImportNames,\n        nonProgramEffectImportNames,\n      ) ||\n      isLikelyDirectEffectInitializer(\n        conditional.getWhenFalse(),\n        effectImportNames,\n        nonProgramEffectImportNames,\n      )\n    );\n  }\n\n  if (initializer.getKind() === SyntaxKind.PropertyAccessExpression) {\n    const text = initializer.getText();\n    const dotIndex = text.indexOf('.');\n    if (dotIndex > 0 && isNonProgramName(text.slice(0, dotIndex))) {\n      return false;\n    }\n    return [...effectImportNames].some((alias) => text.startsWith(`${alias}.`));\n  }\n\n  return false;\n};\n\nexport function isEffectPackageSpecifier(specifier: string): boolean {\n  return (\n    specifier === 'effect' ||\n    specifier.startsWith('effect/') ||\n    specifier.startsWith('@effect/')\n  );\n}\n\nexport const EFFECT_NAMESPACE_NAMES = new Set([\n  'Effect', 'Layer', 'Schedule', 'Stream', 'Queue', 'PubSub', 'Deferred',\n  'Semaphore', 'Mailbox', 'SubscriptionRef', 'Scope', 'Fiber', 'Runtime', 'ManagedRuntime',\n  'Cause', 'Exit', 'Data', 'Option', 'Either', 'Chunk', 'HashMap', 'HashSet',\n  'Match', 'Config', 'Schema', 'Cache', 'ScopedCache', 'Metric', 'Logger',\n  'Tracer', 'Context', 'Brand', 'Encoding', 'Predicate', 'DateTime', 'Cron',\n  'BigDecimal', 'Graph', 'HashRing', 'Redacted', 'GlobalValue',\n  'NodeRuntime', 'BunRuntime', 'DenoRuntime', 'Channel', 'Sink',\n]);\n\nexport const KNOWN_INTERNAL_MODULES = new Set([\n  'core', 'core-effect', 'core-stream', 'fiberRuntime', 'effectable', 'channel', 'sink', 'layer', 'schedule', 'mailbox', 'pubsub',\n]);\n\n// =============================================================================\n// Numeric literal and Context type parsing\n// =============================================================================\n\nexport function parseServiceIdsFromContextType(requiredType: string): string[] {\n  const skip = new Set(['never', 'unknown', 'any', '{}', 'object']);\n  const normalized = requiredType.trim();\n  if (!normalized || skip.has(normalized)) return [];\n  const parts = normalized.split(/[\\s|&]+/).map((s) => s.trim().split('<')[0]?.trim() ?? '');\n  return parts.filter((s) => s.length > 0 && !skip.has(s));\n}\n\nexport function getNumericLiteralFromNode(node: Node): number | undefined {\n  const { SyntaxKind } = loadTsMorph();\n  const kind = node.getKind();\n  if (kind === SyntaxKind.NumericLiteral) {\n    const text = node.getText();\n    const n = Number(text);\n    return Number.isFinite(n) ? n : undefined;\n  }\n  if (kind === SyntaxKind.PrefixUnaryExpression) {\n    const unary = node as PrefixUnaryExpression;\n    if (unary.getOperatorToken() === SyntaxKind.MinusToken) {\n      const operand = unary.getOperand();\n      const v = getNumericLiteralFromNode(operand);\n      return v !== undefined ? -v : undefined;\n    }\n  }\n  return undefined;\n}\n","/**\n * Small browser-safe path helpers for source-mode analysis.\n *\n * They intentionally normalize to forward slashes so synthetic browser paths\n * and real Node paths behave consistently for relative import lookups.\n */\n\nexport const PATH_SEPARATOR = '/';\n\nconst normalizeSlashes = (value: string): string =>\n  value.replace(/\\\\/g, PATH_SEPARATOR);\n\nexport const normalizePath = (value: string): string => {\n  const normalized = normalizeSlashes(value);\n  const isAbsolute = normalized.startsWith(PATH_SEPARATOR);\n  const parts = normalized.split(PATH_SEPARATOR);\n  const stack: string[] = [];\n\n  for (const part of parts) {\n    if (part === '' || part === '.') {\n      continue;\n    }\n    if (part === '..') {\n      if (stack.length > 0 && stack[stack.length - 1] !== '..') {\n        stack.pop();\n      } else if (!isAbsolute) {\n        stack.push(part);\n      }\n      continue;\n    }\n    stack.push(part);\n  }\n\n  if (isAbsolute) {\n    return `${PATH_SEPARATOR}${stack.join(PATH_SEPARATOR)}` || PATH_SEPARATOR;\n  }\n\n  return stack.join(PATH_SEPARATOR) || '.';\n};\n\nexport const dirnamePath = (value: string): string => {\n  const normalized = normalizePath(value);\n  if (normalized === '.' || normalized === PATH_SEPARATOR) {\n    return '.';\n  }\n  const lastSeparator = normalized.lastIndexOf(PATH_SEPARATOR);\n  if (lastSeparator <= 0) {\n    return normalized.startsWith(PATH_SEPARATOR) ? PATH_SEPARATOR : '.';\n  }\n  return normalized.slice(0, lastSeparator);\n};\n\nexport const joinPath = (...parts: readonly string[]): string =>\n  normalizePath(parts.filter((part) => part.length > 0).join(PATH_SEPARATOR));\n\nexport const resolvePath = (...parts: readonly string[]): string =>\n  normalizePath(parts.filter((part) => part.length > 0).join(PATH_SEPARATOR));\n\nexport const hasPathPrefix = (value: string, prefix: string): boolean => {\n  const normalizedValue = normalizePath(value);\n  const normalizedPrefix = normalizePath(prefix);\n  return (\n    normalizedValue === normalizedPrefix ||\n    normalizedValue.startsWith(`${normalizedPrefix}${PATH_SEPARATOR}`)\n  );\n};\n","/**\n * Alias and module resolution for Effect: file-level alias caches,\n * barrel resolution, and Effect-like call detection.\n */\n\nimport type { SourceFile, CallExpression, PropertyAccessExpression } from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport {\n  PATH_SEPARATOR,\n  dirnamePath,\n  resolvePath,\n  joinPath,\n  hasPathPrefix,\n} from './path-utils';\nimport {\n  API_PREFIXES,\n  isEffectPackageSpecifier,\n  EFFECT_NAMESPACE_NAMES,\n  KNOWN_INTERNAL_MODULES,\n} from './analysis-patterns';\n\n// =============================================================================\n// Caches\n// =============================================================================\n\n/** Per-SourceFile alias cache — avoids global mutable state and races. */\nconst effectAliasCache = new WeakMap<SourceFile, Set<string>>();\n\n/** Per-SourceFile symbol-resolution cache — avoids repeated TypeChecker lookups. */\nconst symbolResolutionCache = new WeakMap<SourceFile, Map<string, boolean>>();\n\ninterface FsModuleLike {\n  readonly existsSync?: (path: string) => boolean;\n}\n\nconst getNodeExistsSync = (): ((path: string) => boolean) | undefined => {\n  const maybeProcess = (\n    globalThis as {\n      process?: { getBuiltinModule?: (id: string) => unknown };\n    }\n  ).process;\n  const fsBuiltin =\n    maybeProcess?.getBuiltinModule?.('node:fs') ??\n    maybeProcess?.getBuiltinModule?.('fs');\n\n  if (!fsBuiltin || typeof fsBuiltin !== 'object') {\n    return undefined;\n  }\n\n  return (fsBuiltin as FsModuleLike).existsSync;\n};\n\n// =============================================================================\n// Barrel and re-export resolution\n// =============================================================================\n\n/**\n * Names that a barrel file re-exports from Effect (export { X } from 'effect' or export * from 'effect').\n * One level only; does not follow barrel → barrel.\n */\nexport function getNamesReExportedFromEffect(barrelSourceFile: SourceFile): Set<string> {\n  const out = new Set<string>();\n  for (const decl of barrelSourceFile.getExportDeclarations()) {\n    const specifier = decl.getModuleSpecifierValue();\n    if (!specifier || !isEffectPackageSpecifier(specifier)) continue;\n    if (decl.isNamespaceExport()) {\n      EFFECT_NAMESPACE_NAMES.forEach((n) => out.add(n));\n      continue;\n    }\n    for (const named of decl.getNamedExports()) {\n      out.add(named.getName());\n      const alias = named.getAliasNode()?.getText();\n      if (alias) out.add(alias);\n    }\n  }\n  return out;\n}\n\n/**\n * Resolve a relative module specifier to a SourceFile in the project (21.5 barrel).\n * Tries exact path and common extensions / index files.\n */\nexport function resolveBarrelSourceFile(\n  project: { getSourceFile: (path: string) => SourceFile | undefined },\n  currentFilePath: string,\n  specifier: string,\n): SourceFile | undefined {\n  if (!specifier.startsWith('.')) return undefined;\n  const baseDir = dirnamePath(currentFilePath);\n  const resolved = resolvePath(baseDir, specifier);\n  const candidates: string[] = [\n    resolved,\n    `${resolved}.ts`,\n    `${resolved}.tsx`,\n    `${resolved}.js`,\n    `${resolved}.jsx`,\n    joinPath(resolved, 'index.ts'),\n    joinPath(resolved, 'index.tsx'),\n    joinPath(resolved, 'index.js'),\n    joinPath(resolved, 'index.jsx'),\n  ];\n  for (const p of candidates) {\n    const f = project.getSourceFile(p);\n    if (f) return f;\n  }\n  return undefined;\n}\n\n/**\n * Resolve a relative module specifier to an absolute path (first candidate that exists).\n * Used to add a referenced file to the project when symbol resolution doesn't load it.\n */\nexport function resolveModulePath(\n  currentFilePath: string,\n  specifier: string,\n): string | undefined {\n  if (!specifier.startsWith('.')) return undefined;\n  const existsSync = getNodeExistsSync();\n  if (!existsSync) {\n    return undefined;\n  }\n\n  const baseDir = dirnamePath(currentFilePath);\n  const resolved = resolvePath(baseDir, specifier);\n  const candidates: string[] = [\n    resolved,\n    `${resolved}.ts`,\n    `${resolved}.tsx`,\n    `${resolved}.js`,\n    `${resolved}.jsx`,\n    joinPath(resolved, 'index.ts'),\n    joinPath(resolved, 'index.tsx'),\n    joinPath(resolved, 'index.js'),\n    joinPath(resolved, 'index.jsx'),\n  ];\n  return candidates.find((p) => existsSync(p));\n}\n\n/**\n * Returns true when a relative import specifier resolves to a path at or under\n * the configured Effect internals root. Extensionless resolution is intentional:\n * imports often point at `./internal/foo.js` while callers pass the folder root.\n */\nexport function isSpecifierUnderKnownEffectInternalsRoot(\n  currentFilePath: string,\n  specifier: string,\n  knownEffectInternalsRoot?: string,\n): boolean {\n  if (!knownEffectInternalsRoot || !specifier.startsWith('.')) return false;\n  const normalizedSpecifier = specifier.replace(/\\\\/g, '/');\n  const normalizedResolved = resolvePath(dirnamePath(currentFilePath), specifier);\n  const normalizedRoot = resolvePath(knownEffectInternalsRoot);\n  if (hasPathPrefix(normalizedResolved, normalizedRoot)) {\n    return true;\n  }\n\n  // `analyze.source(...)` uses an in-memory synthetic file path (e.g. `temp.ts`),\n  // so path resolution cannot be related to the caller-provided internals root.\n  // Preserve regression coverage in source-mode while keeping path resolution primary\n  // for real files.\n  const isSyntheticSourcePath =\n    currentFilePath === 'temp.ts' ||\n    currentFilePath.endsWith(`${PATH_SEPARATOR}temp.ts`);\n  if (isSyntheticSourcePath) {\n    return normalizedSpecifier.startsWith('./internal/') || normalizedSpecifier.startsWith('../internal/');\n  }\n\n  return false;\n}\n\n/** Gap 5 / 21.5: Collect names that refer to Effect (from 'effect', 'effect/*', '@effect/*', or barrel re-exports). */\nexport function getEffectImportNames(sourceFile: SourceFile): Set<string> {\n  const names = new Set<string>(EFFECT_NAMESPACE_NAMES);\n  const project = sourceFile.getProject();\n  const currentPath = sourceFile.getFilePath();\n\n  for (const decl of sourceFile.getImportDeclarations()) {\n    const specifier = decl.getModuleSpecifierValue();\n    if (isEffectPackageSpecifier(specifier)) {\n      const def = decl.getDefaultImport();\n      if (def) names.add(def.getText());\n      const ns = decl.getNamespaceImport();\n      if (ns) names.add(ns.getText());\n      for (const named of decl.getNamedImports()) {\n        const alias = named.getAliasNode()?.getText();\n        names.add(alias ?? named.getName());\n      }\n      continue;\n    }\n    if (specifier.startsWith('.')) {\n      const barrelFile = resolveBarrelSourceFile(project, currentPath, specifier);\n      if (!barrelFile) continue;\n      const reExported = getNamesReExportedFromEffect(barrelFile);\n\n      // Collect all import names to check\n      const toCheck: { name: string; localName: string }[] = [];\n      const def = decl.getDefaultImport();\n      if (def) {\n        const text = def.getText();\n        toCheck.push({ name: text, localName: text });\n      }\n      const ns = decl.getNamespaceImport();\n      if (ns) {\n        const text = ns.getText();\n        toCheck.push({ name: text, localName: text });\n      }\n      for (const named of decl.getNamedImports()) {\n        toCheck.push({\n          name: named.getName(),\n          localName: named.getAliasNode()?.getText() ?? named.getName(),\n        });\n      }\n\n      // Fast path: check one-level re-exports first\n      let needsDeepTrace = false;\n      for (const entry of toCheck) {\n        if (reExported.has(entry.name)) {\n          names.add(entry.localName);\n        } else {\n          needsDeepTrace = true;\n        }\n      }\n\n      // Slow path: only trace deeper when one-level check missed some imports\n      if (needsDeepTrace) {\n        for (const entry of toCheck) {\n          if (!reExported.has(entry.name) && traceReExportChain(barrelFile, entry.name, project, 3)) {\n            names.add(entry.localName);\n          }\n        }\n      }\n    }\n  }\n  return names;\n}\n\n/**\n * Enhanced alias set: includes standard Effect import names PLUS namespace\n * imports from known internal modules (e.g. `import * as core from \"./core\"`).\n */\nexport function getEffectLikeNamespaceAliases(\n  sourceFile: SourceFile,\n  knownEffectInternalsRoot?: string,\n): Set<string> {\n  const aliases = getEffectImportNames(sourceFile);\n\n  for (const importDecl of sourceFile.getImportDeclarations()) {\n    const moduleSpecifier = importDecl.getModuleSpecifierValue();\n    const namespaceImport = importDecl.getNamespaceImport();\n    if (!namespaceImport) continue;\n\n    const aliasName = namespaceImport.getText();\n\n    if (moduleSpecifier.startsWith('effect') || moduleSpecifier.startsWith('@effect/')) {\n      aliases.add(aliasName);\n      continue;\n    }\n\n    if (\n      isSpecifierUnderKnownEffectInternalsRoot(\n        sourceFile.getFilePath(),\n        moduleSpecifier,\n        knownEffectInternalsRoot,\n      )\n    ) {\n      aliases.add(aliasName);\n      continue;\n    }\n\n    const basename = moduleSpecifier.replace(/\\.(js|ts)$/, '').split('/').pop() ?? '';\n    if (KNOWN_INTERNAL_MODULES.has(basename)) {\n      aliases.add(aliasName);\n    }\n  }\n\n  return aliases;\n}\n\nconst NON_PROGRAM_EFFECT_MODULE_BASENAMES = new Set([\n  'BigDecimal',\n  'BigInt',\n  'Brand',\n  'Cause',\n  'Chunk',\n  'Data',\n  'Exit',\n  'Option',\n  'Either',\n  'HashMap',\n  'HashSet',\n  'List',\n  'Redacted',\n]);\n\n/**\n * Local import names that come from Effect utility/data modules we do not want to\n * treat as direct \"program\" roots (e.g. Option.some / Either.right).\n */\nexport function getNonProgramEffectImportNames(sourceFile: SourceFile): Set<string> {\n  const out = new Set<string>();\n\n  for (const importDecl of sourceFile.getImportDeclarations()) {\n    const specifier = importDecl.getModuleSpecifierValue();\n    const normalized = specifier.replace(/\\\\/g, '/').replace(/\\.(js|ts|tsx|jsx)$/, '');\n    const basename = normalized.split('/').pop() ?? '';\n    if (!NON_PROGRAM_EFFECT_MODULE_BASENAMES.has(basename)) continue;\n\n    const def = importDecl.getDefaultImport();\n    if (def) out.add(def.getText());\n    const ns = importDecl.getNamespaceImport();\n    if (ns) out.add(ns.getText());\n    for (const named of importDecl.getNamedImports()) {\n      out.add(named.getAliasNode()?.getText() ?? named.getName());\n    }\n  }\n\n  return out;\n}\n\n// =============================================================================\n// Public alias accessor (cached)\n// =============================================================================\n\nexport function getAliasesForFile(sf: SourceFile): Set<string> {\n  let aliases = effectAliasCache.get(sf);\n  if (!aliases) {\n    aliases = getEffectLikeNamespaceAliases(sf);\n    effectAliasCache.set(sf, aliases);\n  }\n  return aliases;\n}\n\n/** Cache: sourceFile -> (local alias -> canonical Effect namespace, e.g. \"L\" -> \"Layer\"). */\nconst effectSubmoduleAliasCache = new WeakMap<SourceFile, Map<string, string>>();\n\n/**\n * Derive the canonical Effect namespace from a module specifier.\n * - \"effect\" or \"effect/Effect\" -> \"Effect\"\n * - \"effect/Layer\" -> \"Layer\", \"effect/Stream\" -> \"Stream\", etc.\n */\nfunction canonicalNamespaceFromSpecifier(specifier: string): string {\n  const n = specifier.replace(/\\\\/g, '/').replace(/\\.(js|ts|mts|cts)$/, '');\n  if (n === 'effect' || n.endsWith('/Effect')) return 'Effect';\n  const segment = n.split('/').pop() ?? '';\n  return segment || 'Effect';\n}\n\n/**\n * Returns a map from local namespace alias to canonical Effect submodule name.\n * E.g. import * as L from \"effect/Layer\" => L -> \"Layer\".\n * Used to normalize callees like L.succeed to Layer.succeed for layer/stream detection.\n */\nexport function getEffectSubmoduleAliasMap(sourceFile: SourceFile): Map<string, string> {\n  let map = effectSubmoduleAliasCache.get(sourceFile);\n  if (map) return map;\n  map = new Map();\n  for (const decl of sourceFile.getImportDeclarations()) {\n    const specifier = decl.getModuleSpecifierValue();\n    if (!specifier || !isEffectPackageSpecifier(specifier)) continue;\n\n    // Handle namespace imports: import * as L from \"effect/Layer\" => L -> Layer\n    const nsImport = decl.getNamespaceImport();\n    if (nsImport) {\n      const aliasName = nsImport.getText();\n      const canonical = canonicalNamespaceFromSpecifier(specifier);\n      map.set(aliasName, canonical);\n      continue;\n    }\n\n    // Handle named imports with aliases: import { Match as M } from \"effect\" => M -> Match\n    for (const named of decl.getNamedImports()) {\n      const alias = named.getAliasNode()?.getText();\n      if (alias) {\n        const originalName = named.getName();\n        map.set(alias, originalName);\n      }\n    }\n  }\n  effectSubmoduleAliasCache.set(sourceFile, map);\n  return map;\n}\n\n/**\n * Normalize a callee string using the file's Effect submodule alias map.\n * E.g. \"L.succeed\" with L -> Layer becomes \"Layer.succeed\".\n */\nexport function normalizeEffectCallee(callee: string, sourceFile: SourceFile): string {\n  const dotIdx = callee.indexOf('.');\n  if (dotIdx <= 0) return callee;\n  const ns = callee.slice(0, dotIdx);\n  const rest = callee.slice(dotIdx + 1);\n  const aliasMap = getEffectSubmoduleAliasMap(sourceFile);\n  const canonical = aliasMap.get(ns);\n  if (!canonical) return callee;\n  return `${canonical}.${rest}`;\n}\n\n// =============================================================================\n// Module origin resolution\n// =============================================================================\n\n/**\n * Trace a re-export chain up to `maxDepth` levels to determine if a name\n * ultimately originates from an Effect package.\n */\nfunction traceReExportChain(\n  barrelFile: SourceFile,\n  name: string,\n  project: { getSourceFile: (path: string) => SourceFile | undefined },\n  maxDepth: number,\n): boolean {\n  if (maxDepth <= 0) return false;\n\n  for (const exportDecl of barrelFile.getExportDeclarations()) {\n    const specifier = exportDecl.getModuleSpecifierValue();\n    if (!specifier) continue;\n\n    // Check if this export contains the name, and resolve the original name\n    // through any alias (e.g. export { E as Fx } — name=\"Fx\", originalName=\"E\")\n    let originalName: string | undefined;\n    if (exportDecl.isNamespaceExport()) {\n      originalName = name; // namespace re-export covers all names unchanged\n    } else {\n      for (const namedExport of exportDecl.getNamedExports()) {\n        const alias = namedExport.getAliasNode()?.getText();\n        if (alias === name) {\n          // export { E as Fx } — looking for \"Fx\", original is \"E\"\n          originalName = namedExport.getName();\n          break;\n        }\n        if (namedExport.getName() === name) {\n          // export { E } — no rename\n          originalName = name;\n          break;\n        }\n      }\n    }\n\n    if (originalName === undefined) continue;\n\n    // If it re-exports from an Effect package, we found it\n    if (isEffectPackageSpecifier(specifier)) return true;\n\n    // If it re-exports from a local module, recurse with the original name\n    if (specifier.startsWith('.')) {\n      const nextBarrel = resolveBarrelSourceFile(project, barrelFile.getFilePath(), specifier);\n      if (nextBarrel) {\n        const fromEffect = getNamesReExportedFromEffect(nextBarrel);\n        if (fromEffect.has(originalName)) return true;\n        if (traceReExportChain(nextBarrel, originalName, project, maxDepth - 1)) return true;\n      }\n    }\n  }\n\n  return false;\n}\n\n/**\n * Resolve whether a callee expression originates from an Effect package\n * by tracing its import declaration. Fallback when API_PREFIXES and alias checks don't match.\n */\nfunction resolveCalleeModuleOrigin(calleeText: string, sourceFile: SourceFile): boolean {\n  let cache = symbolResolutionCache.get(sourceFile);\n  if (!cache) {\n    cache = new Map();\n    symbolResolutionCache.set(sourceFile, cache);\n  }\n\n  const dotIdx = calleeText.indexOf('.');\n  const nsText = dotIdx > 0 ? calleeText.slice(0, dotIdx) : calleeText;\n  const cached = cache.get(nsText);\n  if (cached !== undefined) return cached;\n\n  let result = false;\n  try {\n    for (const importDecl of sourceFile.getImportDeclarations()) {\n      const specifier = importDecl.getModuleSpecifierValue();\n\n      const nsImport = importDecl.getNamespaceImport();\n      if (nsImport?.getText() === nsText) {\n        result = isEffectPackageSpecifier(specifier);\n        break;\n      }\n\n      const defImport = importDecl.getDefaultImport();\n      if (defImport?.getText() === nsText) {\n        result = isEffectPackageSpecifier(specifier);\n        break;\n      }\n\n      for (const named of importDecl.getNamedImports()) {\n        const alias = named.getAliasNode()?.getText();\n        const localName = alias ?? named.getName();\n        if (localName === nsText) {\n          if (isEffectPackageSpecifier(specifier)) {\n            result = true;\n          } else if (specifier.startsWith('.')) {\n            const barrelFile = resolveBarrelSourceFile(\n              sourceFile.getProject(), sourceFile.getFilePath(), specifier\n            );\n            if (barrelFile) {\n              const reExported = getNamesReExportedFromEffect(barrelFile);\n              if (reExported.has(named.getName())) {\n                result = true;\n              } else {\n                // Multi-level: trace through barrel → barrel chains (up to 3 levels)\n                result = traceReExportChain(barrelFile, named.getName(), sourceFile.getProject(), 3);\n              }\n            }\n          }\n          break;\n        }\n      }\n      if (result) break;\n    }\n  } catch {\n    result = false;\n  }\n\n  cache.set(nsText, result);\n  return result;\n}\n\n/**\n * Resolve the module specifier for the namespace part of a property access (e.g. E in E.succeed).\n * Returns the import's module specifier string, or undefined if not found.\n */\nfunction resolveNamespaceImportModuleSpecifier(\n  expr: import('ts-morph').PropertyAccessExpression,\n  sourceFile: SourceFile,\n): string | undefined {\n  const nsExpr = expr.getExpression();\n  const nsText = nsExpr.getText();\n  for (const importDecl of sourceFile.getImportDeclarations()) {\n    const specifier = importDecl.getModuleSpecifierValue();\n    const nsImport = importDecl.getNamespaceImport();\n    if (nsImport?.getText() === nsText) return specifier;\n    const defImport = importDecl.getDefaultImport();\n    if (defImport?.getText() === nsText) return specifier;\n    for (const named of importDecl.getNamedImports()) {\n      const alias = named.getAliasNode()?.getText();\n      const localName = alias ?? named.getName();\n      if (localName === nsText) return specifier;\n    }\n  }\n  return undefined;\n}\n\n// =============================================================================\n// Effect-like call detection\n// =============================================================================\n\n/**\n * Symbol/typechecker-backed check for Effect-like call. Fast path: API_PREFIXES + file alias set;\n * fallback: resolve callee namespace to module specifier and classify by origin.\n * Optional knownEffectInternalsRoot: local paths under that root are treated as Effect-like (improve.md §1).\n */\nexport function isEffectLikeCallExpression(\n  call: CallExpression,\n  sourceFile: SourceFile,\n  effectAliases: Set<string>,\n  knownEffectInternalsRoot?: string,\n): boolean {\n  const expr = call.getExpression();\n  const text = expr.getText();\n  if (API_PREFIXES.some((p) => text.startsWith(p)) || text.startsWith('pipe(')) return true;\n  for (const alias of effectAliases) {\n    if (text.startsWith(`${alias}.`)) return true;\n  }\n  const { SyntaxKind } = loadTsMorph();\n  if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) return false;\n  const propAccess = expr as PropertyAccessExpression;\n  const specifier = resolveNamespaceImportModuleSpecifier(propAccess, sourceFile);\n  if (!specifier) return false;\n  if (isEffectPackageSpecifier(specifier)) return true;\n  if (specifier.startsWith('.')) {\n    const barrelFile = resolveBarrelSourceFile(\n      sourceFile.getProject(),\n      sourceFile.getFilePath(),\n      specifier,\n    );\n    if (barrelFile) {\n      const reExported = getNamesReExportedFromEffect(barrelFile);\n      const nsText = propAccess.getExpression().getText();\n      for (const importDecl of sourceFile.getImportDeclarations()) {\n        if (importDecl.getModuleSpecifierValue() !== specifier) continue;\n        for (const named of importDecl.getNamedImports()) {\n          const localName = named.getAliasNode()?.getText() ?? named.getName();\n          if (localName === nsText && reExported.has(named.getName())) return true;\n        }\n      }\n    }\n    if (\n      isSpecifierUnderKnownEffectInternalsRoot(\n        sourceFile.getFilePath(),\n        specifier,\n        knownEffectInternalsRoot,\n      )\n    ) {\n      return true;\n    }\n  }\n  return false;\n}\n\n/**\n * Check if callee text is an Effect API call (prefix, alias, or symbol-resolved).\n */\nexport function isEffectCallee(\n  text: string,\n  effectAliases?: Set<string>,\n  sourceFile?: SourceFile,\n): boolean {\n  if (API_PREFIXES.some((prefix) => text.startsWith(prefix)) || text.startsWith('pipe(')) {\n    return true;\n  }\n  if (effectAliases) {\n    for (const alias of effectAliases) {\n      if (text.startsWith(`${alias}.`)) return true;\n    }\n  }\n  if (sourceFile && text.includes('.')) {\n    return resolveCalleeModuleOrigin(text, sourceFile);\n  }\n  return false;\n}\n","/**\n * Effect program discovery: find Effect.gen, pipe, run, class, and class-member programs.\n */\n\nimport type {\n  SourceFile,\n  Node,\n  CallExpression,\n  VariableDeclaration,\n  PropertyAccessExpression,\n  Identifier,\n  AwaitExpression,\n  ArrowFunction,\n  FunctionExpression,\n  PropertyDeclaration,\n  MethodDeclaration,\n  GetAccessorDeclaration,\n  FunctionDeclaration,\n  ClassDeclaration,\n  ReturnStatement,\n  ExpressionStatement,\n  TypeNode,\n  ObjectLiteralExpression,\n  PropertyAssignment,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type { AnalyzerOptions, ServiceDefinition } from './types';\nimport { extractProgramName, extractEnclosingEffectFnName } from './analysis-utils';\nimport type { EffectProgram } from './analysis-utils';\n\nexport type { EffectProgram } from './analysis-utils';\nimport { isLikelyDirectEffectInitializer } from './analysis-patterns';\nimport {\n  getEffectLikeNamespaceAliases,\n  getNonProgramEffectImportNames,\n  isSpecifierUnderKnownEffectInternalsRoot,\n  isEffectLikeCallExpression,\n} from './alias-resolution';\n\n// =============================================================================\n// Workflow (effect-workflow) helpers\n// =============================================================================\n\nconst WORKFLOW_FACTORY_NAMES = new Set([\n  'createWorkflow',\n  'createSagaWorkflow',\n  'runSaga',\n]);\n\nconst isWorkflowFactoryCall = (calleeText: string): boolean =>\n  Array.from(WORKFLOW_FACTORY_NAMES).some(\n    (name) => calleeText === name || calleeText.endsWith(`.${name}`),\n  );\n\n/** Returns true if call is X.make(name, deps?, fn, options?) with at least 3 args and 3rd is a function. */\nconst isWorkflowMakeCall = (call: CallExpression): boolean => {\n  const expr = call.getExpression();\n  if (expr.getKind() !== loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n    return false;\n  }\n  const prop = expr as PropertyAccessExpression;\n  const args = call.getArguments();\n  if (prop.getName() !== 'make' || args.length < 3 || !args[2]) {\n    return false;\n  }\n  const third = args[2].getKind();\n  const { SyntaxKind } = loadTsMorph();\n  return (\n    third === SyntaxKind.ArrowFunction || third === SyntaxKind.FunctionExpression\n  );\n};\n\n// =============================================================================\n// Effect package workflow\n// =============================================================================\n\n/** True if the module specifier refers to the workflow package. */\nfunction isWorkflowPackageSpecifier(specifier: string, _currentFilePath?: string): boolean {\n  const n = specifier.replace(/\\\\/g, '/');\n  if (n === '@effect/workflow' || n === 'effect/workflow') return true;\n  if (n.endsWith('/workflow') || n.includes('/workflow/')) return true;\n  if (n.endsWith('/Workflow.js') || n.endsWith('/Workflow.ts')) return true;\n  if (n.endsWith('/Activity.js') || n.endsWith('/Activity.ts')) return true;\n  if (n.startsWith('.') && (n.endsWith('Workflow.js') || n.endsWith('Workflow.ts') || n.endsWith('Activity.js') || n.endsWith('Activity.ts'))) return true;\n  return false;\n}\n\nfunction isWorkflowNamespaceFromPackage(\n  localName: string,\n  specifier: string,\n  _currentFilePath?: string,\n): boolean {\n  if (localName !== 'Workflow') return false;\n  return isWorkflowPackageSpecifier(specifier, _currentFilePath);\n}\n\nfunction isActivityNamespaceFromPackage(\n  localName: string,\n  specifier: string,\n  _currentFilePath?: string,\n): boolean {\n  if (localName !== 'Activity') return false;\n  return isWorkflowPackageSpecifier(specifier, _currentFilePath);\n}\n\nfunction objectArgHasAnyProperty(\n  call: CallExpression,\n  propertyNames: readonly string[],\n): boolean {\n  const { SyntaxKind } = loadTsMorph();\n  const args = call.getArguments();\n  if (args.length !== 1 || !args[0]) return false;\n  const arg = args[0];\n  if (arg.getKind() !== SyntaxKind.ObjectLiteralExpression) return false;\n  const obj = arg as ObjectLiteralExpression;\n  const props = obj.getProperties();\n  const names = new Set(propertyNames);\n  for (const p of props) {\n    if (p.getKind() === SyntaxKind.PropertyAssignment) {\n      const name = (p as PropertyAssignment).getName();\n      if (names.has(name)) return true;\n    }\n  }\n  return false;\n}\n\nfunction isWorkflowMakeOptionsCall(\n  call: CallExpression,\n  importSpecifierByLocalName: Map<string, string>,\n  currentFilePath: string,\n): boolean {\n  const { SyntaxKind } = loadTsMorph();\n  const expr = call.getExpression();\n  if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) return false;\n  const prop = expr as PropertyAccessExpression;\n  if (prop.getName() !== 'make') return false;\n  const baseText = prop.getExpression().getText();\n  const specifier = importSpecifierByLocalName.get(baseText);\n  if (!specifier || !isWorkflowNamespaceFromPackage(baseText, specifier, currentFilePath)) return false;\n  return objectArgHasAnyProperty(call, ['name', 'payload', 'idempotencyKey']);\n}\n\nfunction isActivityMakeOptionsCall(\n  call: CallExpression,\n  importSpecifierByLocalName: Map<string, string>,\n  currentFilePath: string,\n): boolean {\n  const { SyntaxKind } = loadTsMorph();\n  const expr = call.getExpression();\n  if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) return false;\n  const prop = expr as PropertyAccessExpression;\n  if (prop.getName() !== 'make') return false;\n  const baseText = prop.getExpression().getText();\n  const specifier = importSpecifierByLocalName.get(baseText);\n  if (!specifier || !isActivityNamespaceFromPackage(baseText, specifier, currentFilePath)) return false;\n  return objectArgHasAnyProperty(call, ['name', 'execute']);\n}\n\n/**\n * For X.run(singleArg) (e.g. effect-workflow Workflow.run(workflow)), resolve the single\n * argument to the workflow body (the callback passed to Workflow.make). Returns the AST\n * node for that callback or null.\n */\nexport const getWorkflowBodyNodeForRunCall = (\n  runCall: CallExpression,\n  sourceFile: SourceFile,\n): Node | null => {\n  const expr = runCall.getExpression();\n  if (expr.getKind() !== loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n    return null;\n  }\n  const prop = expr as PropertyAccessExpression;\n  if (prop.getName() !== 'run') {\n    return null;\n  }\n  const args = runCall.getArguments();\n  if (args.length < 1 || !args[0]) {\n    return null;\n  }\n  const arg = args[0];\n  const { SyntaxKind } = loadTsMorph();\n\n  if (arg.getKind() === SyntaxKind.CallExpression) {\n    const innerCall = arg as CallExpression;\n    if (isWorkflowMakeCall(innerCall)) {\n      const makeArgs = innerCall.getArguments();\n      return makeArgs[2] ?? null;\n    }\n    return null;\n  }\n\n  if (arg.getKind() !== SyntaxKind.Identifier) {\n    return null;\n  }\n  const id = arg as Identifier;\n  const name = id.getText();\n  const varDecls = sourceFile.getDescendantsOfKind(\n    SyntaxKind.VariableDeclaration,\n  );\n  for (const decl of varDecls) {\n    if ((decl).getName() !== name) {\n      continue;\n    }\n    const initializer = (decl).getInitializer();\n    if (\n      initializer?.getKind() === SyntaxKind.CallExpression &&\n      isWorkflowMakeCall(initializer as CallExpression)\n    ) {\n      const makeArgs = (initializer as CallExpression).getArguments();\n      return makeArgs[2] ?? null;\n    }\n  }\n  return null;\n};\n\n// =============================================================================\n// Scope and run detection\n// =============================================================================\n\nconst isInsideEffectGen = (node: Node): boolean => {\n  const { SyntaxKind } = loadTsMorph();\n  let current = node.getParent();\n  while (current) {\n    if (current.getKind() === SyntaxKind.CallExpression) {\n      const expr = (current as CallExpression).getExpression();\n      const text = expr.getText();\n      if (text.includes('.gen') || text === 'gen') {\n        return true;\n      }\n    }\n    current = current.getParent();\n  }\n  return false;\n};\n\nconst isTopLevelVariableDeclaration = (decl: VariableDeclaration): boolean => {\n  const { SyntaxKind } = loadTsMorph();\n  const statement = decl.getFirstAncestorByKind(SyntaxKind.VariableStatement);\n  return statement?.getParent()?.getKind() === SyntaxKind.SourceFile;\n};\n\nconst isYieldBoundDeclaration = (decl: VariableDeclaration): boolean => {\n  const { SyntaxKind } = loadTsMorph();\n  const initializer = decl.getInitializer();\n  if (!initializer) return false;\n  if (initializer.getKind() === SyntaxKind.YieldExpression) return true;\n  if (\n    initializer.getKind() === SyntaxKind.AwaitExpression &&\n    (\n      initializer as AwaitExpression\n    ).getExpression().getKind() === SyntaxKind.YieldExpression\n  ) {\n    return true;\n  }\n  return false;\n};\n\nconst getCallExpressionFromInitializer = (\n  initializer: Node,\n): CallExpression | undefined => {\n  const { SyntaxKind } = loadTsMorph();\n  if (initializer.getKind() === SyntaxKind.CallExpression) {\n    return initializer as CallExpression;\n  }\n  if (initializer.getKind() === SyntaxKind.AwaitExpression) {\n    const awaited = (\n      initializer as AwaitExpression\n    ).getExpression();\n    if (awaited.getKind() === SyntaxKind.CallExpression) {\n      return awaited as CallExpression;\n    }\n  }\n  return undefined;\n};\n\ntype DiscoveryConfidence = NonNullable<EffectProgram['discoveryConfidence']>;\n\ninterface DiscoveryInfo {\n  readonly discoveryConfidence: DiscoveryConfidence;\n  readonly discoveryReason: string;\n}\n\nconst buildDiscoveryInfo = (\n  discoveryConfidence: DiscoveryConfidence,\n  discoveryReason: string,\n): DiscoveryInfo => ({ discoveryConfidence, discoveryReason });\n\nconst EFFECT_FAMILY_TYPE_HINTS = [\n  'Effect<',\n  'Layer<',\n  'Layer.Layer<',\n  'Stream<',\n  'Stream.Stream<',\n  'Channel<',\n  'Channel.Channel<',\n  'Sink<',\n  'Sink.Sink<',\n  'STM<',\n  'STM.STM<',\n  'Schedule<',\n  'Schedule.Schedule<',\n];\n\nconst hasEffectFamilyTypeHint = (text: string | undefined): boolean =>\n  text !== undefined && EFFECT_FAMILY_TYPE_HINTS.some((hint) => text.includes(hint));\n\nconst DISCOVERY_CONFIDENCE_RANK: Record<DiscoveryConfidence, number> = {\n  low: 0,\n  medium: 1,\n  high: 2,\n};\n\nconst isRunCall = (call: CallExpression): boolean => {\n  const exprText = call.getExpression().getText();\n  return (\n    exprText.includes('.runPromise') ||\n    exprText.includes('.runPromiseExit') ||\n    exprText.includes('.runSync') ||\n    exprText.includes('.runSyncExit') ||\n    exprText.includes('.runFork') ||\n    exprText.includes('.runCallback') ||\n    exprText.includes('.runMain') ||\n    exprText.includes('Runtime.runPromise') ||\n    exprText.includes('Runtime.runSync') ||\n    exprText.includes('Runtime.runFork')\n  );\n};\n\n/**\n * Check if a function-like node's body contains runMain/runPromise/runSync/runFork.\n * Used for indirect runMain wrapper detection (improve.md §9).\n */\nfunction bodyContainsRunMainOrRunPromise(node: Node): boolean {\n  const body = (node as unknown as { getBody?: () => Node }).getBody?.();\n  if (!body) return false;\n  const text = body.getText();\n  return (\n    text.includes('.runMain') ||\n    text.includes('.runPromise') ||\n    text.includes('.runSync') ||\n    text.includes('.runFork') ||\n    text.includes('Runtime.runPromise') ||\n    text.includes('Runtime.runSync') ||\n    text.includes('NodeRuntime.runMain') ||\n    text.includes('BunRuntime.runMain') ||\n    text.includes('DenoRuntime.runMain')\n  );\n}\n\n/**\n * Resolve identifier to a function declaration/expression and check if its body contains runMain/runPromise.\n */\nfunction isIndirectRunMainWrapper(call: CallExpression, _sourceFile: SourceFile): boolean {\n  const expr = call.getExpression();\n  if (expr.getKind() !== loadTsMorph().SyntaxKind.Identifier) return false;\n  const id = expr as Identifier;\n  const sym = id.getSymbol();\n  const decl = sym?.getValueDeclaration();\n  if (!decl) return false;\n  const kind = decl.getKind();\n  const { SyntaxKind } = loadTsMorph();\n  if (\n    kind === SyntaxKind.FunctionDeclaration ||\n    kind === SyntaxKind.ArrowFunction ||\n    kind === SyntaxKind.FunctionExpression\n  ) {\n    return bodyContainsRunMainOrRunPromise(decl);\n  }\n  if (kind === SyntaxKind.VariableDeclaration) {\n    const init = (decl as VariableDeclaration).getInitializer();\n    if (init && (init.getKind() === SyntaxKind.ArrowFunction || init.getKind() === SyntaxKind.FunctionExpression)) {\n      return bodyContainsRunMainOrRunPromise(init);\n    }\n  }\n  return false;\n}\n\n/**\n * Detect curried runtime form: Runtime.runPromise(runtime)(effect) — improve.md §9.\n * The outer call has one argument (the effect); the callee is itself a call with one argument (the runtime).\n */\nexport function isRuntimeCurriedForm(call: CallExpression): boolean {\n  const expr = call.getExpression();\n  if (call.getArguments().length !== 1) return false;\n  const { SyntaxKind } = loadTsMorph();\n  if (expr.getKind() !== SyntaxKind.CallExpression) return false;\n  const innerCall = expr as CallExpression;\n  if (innerCall.getArguments().length !== 1) return false;\n  const innerExprText = innerCall.getExpression().getText();\n  return (\n    innerExprText.includes('.runPromise') ||\n    innerExprText.includes('.runSync') ||\n    innerExprText.includes('.runFork') ||\n    innerExprText.includes('.runCallback') ||\n    innerExprText.includes('Runtime.runPromise') ||\n    innerExprText.includes('Runtime.runSync') ||\n    innerExprText.includes('Runtime.runFork')\n  );\n}\n\n// =============================================================================\n// Program discovery\n// =============================================================================\n\nexport const findEffectPrograms = (\n  sourceFile: SourceFile,\n  _opts: Required<AnalyzerOptions>,\n): readonly EffectProgram[] => {\n  const programs: EffectProgram[] = [];\n  const { SyntaxKind } = loadTsMorph();\n  const seenCallStarts = new Set<number>();\n  const workflowProgramBuilders = new Set<string>();\n  const effectImportNames = getEffectLikeNamespaceAliases(\n    sourceFile,\n    _opts.knownEffectInternalsRoot,\n  );\n  const nonProgramEffectImportNames = getNonProgramEffectImportNames(sourceFile);\n  const importSpecifierByLocalName = new Map<string, string>();\n\n  for (const importDecl of sourceFile.getImportDeclarations()) {\n    const specifier = importDecl.getModuleSpecifierValue();\n    const def = importDecl.getDefaultImport();\n    if (def) importSpecifierByLocalName.set(def.getText(), specifier);\n    const ns = importDecl.getNamespaceImport();\n    if (ns) importSpecifierByLocalName.set(ns.getText(), specifier);\n    for (const named of importDecl.getNamedImports()) {\n      importSpecifierByLocalName.set(\n        named.getAliasNode()?.getText() ?? named.getName(),\n        specifier,\n      );\n    }\n  }\n\n  const inferAliasBackedDiscovery = (aliasName: string): DiscoveryInfo | undefined => {\n    const specifier = importSpecifierByLocalName.get(aliasName);\n    if (!specifier) return undefined;\n    if (specifier.startsWith('effect') || specifier.startsWith('@effect/')) {\n      return buildDiscoveryInfo('high', `imported from ${specifier}`);\n    }\n    if (\n      isSpecifierUnderKnownEffectInternalsRoot(\n        sourceFile.getFilePath(),\n        specifier,\n        _opts.knownEffectInternalsRoot,\n      )\n    ) {\n      return buildDiscoveryInfo(\n        'high',\n        'namespace import resolved under knownEffectInternalsRoot',\n      );\n    }\n    if (specifier.startsWith('.') && /(?:^|\\/)Effect(?:\\.[jt]sx?)?$/.test(specifier)) {\n      return buildDiscoveryInfo('high', `relative Effect module namespace import (${specifier})`);\n    }\n    return undefined;\n  };\n\n  const inferDirectInitializerDiscovery = (initializer: Node): DiscoveryInfo => {\n    const inferFromNestedEffectAliasUsage = (node: Node): DiscoveryInfo | undefined => {\n      const propertyAccesses = node.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression);\n      for (const expr of propertyAccesses) {\n        const base = expr.getExpression().getText();\n        if (effectImportNames.has(base) && !nonProgramEffectImportNames.has(base)) {\n          const aliasInfo = inferAliasBackedDiscovery(base);\n          if (aliasInfo?.discoveryConfidence === 'high') {\n            return buildDiscoveryInfo('high', `function body uses ${base}.* from trusted Effect alias`);\n          }\n          return buildDiscoveryInfo('medium', `function body uses Effect-like alias ${base}.*`);\n        }\n      }\n\n      const calls = node.getDescendantsOfKind(SyntaxKind.CallExpression);\n      for (const c of calls) {\n        const callee = (c).getExpression();\n        if (callee.getKind() === SyntaxKind.Identifier) {\n          const local = callee.getText();\n          if (effectImportNames.has(local) && !nonProgramEffectImportNames.has(local)) {\n            const aliasInfo = inferAliasBackedDiscovery(local);\n            if (aliasInfo?.discoveryConfidence === 'high') {\n              return buildDiscoveryInfo('high', `function body calls trusted Effect import ${local}(...)`);\n            }\n            return buildDiscoveryInfo('medium', `function body calls Effect-like import ${local}(...)`);\n          }\n        }\n      }\n\n      return undefined;\n    };\n\n    if (\n      initializer.getKind() === SyntaxKind.ArrowFunction ||\n      initializer.getKind() === SyntaxKind.FunctionExpression\n    ) {\n      const fn = initializer as\n        | ArrowFunction\n        | FunctionExpression;\n      const body = fn.getBody();\n      if (body.getKind() === SyntaxKind.Block) {\n        const nested = inferFromNestedEffectAliasUsage(body);\n        if (nested) return nested;\n      } else {\n        const nested = inferFromNestedEffectAliasUsage(body);\n        if (nested) return nested;\n      }\n    }\n\n    const call = getCallExpressionFromInitializer(initializer);\n    if (call) {\n      const callee = call.getExpression();\n      const calleeText = callee.getText();\n      if (callee.getKind() === SyntaxKind.Identifier) {\n        const local = calleeText;\n        if (\n          effectImportNames.has(local) &&\n          !nonProgramEffectImportNames.has(local)\n        ) {\n          return (\n            inferAliasBackedDiscovery(local) ??\n            buildDiscoveryInfo('high', `named import call (${local})`)\n          );\n        }\n        if (local === 'pipe') {\n          return buildDiscoveryInfo('medium', 'exact pipe() call detection');\n        }\n      }\n      if (callee.getKind() === SyntaxKind.PropertyAccessExpression) {\n        const prop = callee as PropertyAccessExpression;\n        const baseText = prop.getExpression().getText();\n        if (effectImportNames.has(baseText) && !nonProgramEffectImportNames.has(baseText)) {\n          return (\n            inferAliasBackedDiscovery(baseText) ??\n            buildDiscoveryInfo('medium', `Effect-like namespace prefix (${baseText}.*)`)\n          );\n        }\n        if (prop.getName() === 'pipe') {\n          return buildDiscoveryInfo('medium', 'exact .pipe() call detection');\n        }\n      }\n    }\n\n    if (initializer.getKind() === SyntaxKind.PropertyAccessExpression) {\n      const prop = initializer as PropertyAccessExpression;\n      const baseText = prop.getExpression().getText();\n      if (effectImportNames.has(baseText) && !nonProgramEffectImportNames.has(baseText)) {\n        return (\n          inferAliasBackedDiscovery(baseText) ??\n          buildDiscoveryInfo('medium', `Effect-like namespace property access (${baseText}.*)`)\n        );\n      }\n    }\n\n    if (initializer.getKind() === SyntaxKind.AwaitExpression) {\n      const awaited = (initializer as AwaitExpression).getExpression();\n      if (awaited.getKind() === SyntaxKind.CallExpression) {\n        return inferDirectInitializerDiscovery(awaited);\n      }\n    }\n\n    return buildDiscoveryInfo('low', 'heuristic direct initializer match');\n  };\n\n  const inferTypeAnnotatedDiscovery = (\n    node:\n      | VariableDeclaration\n      | PropertyDeclaration\n      | MethodDeclaration\n      | GetAccessorDeclaration,\n  ): DiscoveryInfo | undefined => {\n    const getTypeNodeText = (\n      n: unknown,\n    ): string | undefined => {\n      const typeNode = (\n        n as { getTypeNode?: () => { getText: () => string } | undefined }\n      ).getTypeNode?.();\n      return typeNode?.getText();\n    };\n\n    const typeText = getTypeNodeText(node);\n    if (hasEffectFamilyTypeHint(typeText)) {\n      return buildDiscoveryInfo('high', 'explicit Effect-family type annotation');\n    }\n\n    const isExportedDecl = (() => {\n      if (node.getKind() === SyntaxKind.VariableDeclaration) {\n        const stmt = (node as VariableDeclaration).getFirstAncestorByKind(\n          SyntaxKind.VariableStatement,\n        );\n        return stmt?.isExported() ?? false;\n      }\n      if (node.getKind() === SyntaxKind.PropertyDeclaration) {\n        const cls = node.getFirstAncestorByKind(SyntaxKind.ClassDeclaration);\n        return cls?.isExported() ?? false;\n      }\n      if (\n        node.getKind() === SyntaxKind.MethodDeclaration ||\n        node.getKind() === SyntaxKind.GetAccessor\n      ) {\n        const cls = node.getFirstAncestorByKind(SyntaxKind.ClassDeclaration);\n        return cls?.isExported() ?? false;\n      }\n      return false;\n    })();\n\n    if (\n      node.getKind() === SyntaxKind.VariableDeclaration ||\n      node.getKind() === SyntaxKind.PropertyDeclaration\n    ) {\n      const initializer = (\n        node as VariableDeclaration | PropertyDeclaration\n      ).getInitializer();\n      if (\n        initializer &&\n        (initializer.getKind() === SyntaxKind.ArrowFunction ||\n          initializer.getKind() === SyntaxKind.FunctionExpression)\n      ) {\n        const fn = initializer as\n          | import('ts-morph').ArrowFunction\n          | import('ts-morph').FunctionExpression;\n        const fnReturnTypeText = fn.getReturnTypeNode()?.getText();\n        if (hasEffectFamilyTypeHint(fnReturnTypeText)) {\n          return buildDiscoveryInfo('high', 'function return type annotated as Effect-family');\n        }\n        if (isExportedDecl && typeText) {\n          return buildDiscoveryInfo('medium', 'explicit exported function API type signature');\n        }\n      }\n      if (initializer?.getKind() === SyntaxKind.CallExpression) {\n        const call = initializer as CallExpression;\n        const typeArgText = call\n          .getTypeArguments()\n          .map((arg) => arg.getText())\n          .join(' ');\n        if (hasEffectFamilyTypeHint(typeArgText)) {\n          return buildDiscoveryInfo('high', 'call type arguments reference Effect-family types');\n        }\n        if (isExportedDecl && typeText) {\n          return buildDiscoveryInfo('medium', 'explicit exported call-based API type signature');\n        }\n      }\n    }\n\n    if (\n      node.getKind() === SyntaxKind.MethodDeclaration ||\n      node.getKind() === SyntaxKind.GetAccessor\n    ) {\n      const fnReturnTypeText = (\n        node as MethodDeclaration | GetAccessorDeclaration\n      ).getReturnTypeNode?.()?.getText();\n      if (hasEffectFamilyTypeHint(fnReturnTypeText)) {\n        return buildDiscoveryInfo('high', 'method/getter return type annotated as Effect-family');\n      }\n      if (isExportedDecl && typeText) {\n        return buildDiscoveryInfo('medium', 'explicit exported method/getter API type signature');\n      }\n    }\n\n    return undefined;\n  };\n\n  const isProgramRootExported = (program: EffectProgram): boolean => {\n    const node = program.node;\n    const kind = node.getKind();\n    if (kind === SyntaxKind.CallExpression) {\n      // Top-level entrypoint statements / assigned runs don't have a direct export modifier.\n      return true;\n    }\n    if (kind === SyntaxKind.VariableDeclaration) {\n      const stmt = (node as VariableDeclaration).getFirstAncestorByKind(\n        SyntaxKind.VariableStatement,\n      );\n      return stmt?.isExported() ?? false;\n    }\n    if (kind === SyntaxKind.FunctionDeclaration || kind === SyntaxKind.ClassDeclaration) {\n      return (\n        node as FunctionDeclaration | ClassDeclaration\n      ).isExported();\n    }\n    if (\n      kind === SyntaxKind.PropertyDeclaration ||\n      kind === SyntaxKind.MethodDeclaration ||\n      kind === SyntaxKind.GetAccessor\n    ) {\n      const cls = node.getFirstAncestorByKind(SyntaxKind.ClassDeclaration);\n      return cls?.isExported() ?? false;\n    }\n    return true;\n  };\n\n  const inferMethodReturnDiscovery = (\n    returnStatements: readonly ReturnStatement[],\n  ): DiscoveryInfo => {\n    for (const ret of returnStatements) {\n      const expr = ret.getExpression();\n      if (!expr) continue;\n      if (\n        isLikelyDirectEffectInitializer(\n          expr,\n          effectImportNames,\n          nonProgramEffectImportNames,\n        )\n      ) {\n        return inferDirectInitializerDiscovery(expr);\n      }\n    }\n    return buildDiscoveryInfo('low', 'heuristic method return match');\n  };\n\n  const filePath = sourceFile.getFilePath();\n  const varDeclarations = sourceFile.getDescendantsOfKind(\n    SyntaxKind.VariableDeclaration,\n  );\n  for (const decl of varDeclarations) {\n    const initializer = decl.getInitializer();\n    if (\n      initializer?.getKind() === SyntaxKind.CallExpression &&\n      isWorkflowFactoryCall(\n        (initializer as CallExpression).getExpression().getText(),\n      )\n    ) {\n      workflowProgramBuilders.add(decl.getName());\n    }\n    if (\n      _opts.enableEffectWorkflow &&\n      initializer?.getKind() === SyntaxKind.CallExpression\n    ) {\n      const initCall = initializer as CallExpression;\n      if (\n        isWorkflowMakeOptionsCall(initCall, importSpecifierByLocalName, filePath) ||\n        isActivityMakeOptionsCall(initCall, importSpecifierByLocalName, filePath)\n      ) {\n        workflowProgramBuilders.add(decl.getName());\n      }\n    }\n  }\n\n  const genCalls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n\n  for (const call of genCalls) {\n    const expression = call.getExpression();\n    const exprText = expression.getText();\n    const callStart = call.getStart();\n\n    let isWorkflowInvocation = false;\n    if (expression.getKind() === SyntaxKind.Identifier) {\n      isWorkflowInvocation = workflowProgramBuilders.has(exprText);\n    } else if (expression.getKind() === SyntaxKind.PropertyAccessExpression) {\n      const propertyAccess =\n        expression as PropertyAccessExpression;\n      const objectText = propertyAccess.getExpression().getText();\n      const methodName = propertyAccess.getName();\n      isWorkflowInvocation =\n        workflowProgramBuilders.has(objectText) && methodName === 'run';\n      if (\n        _opts.enableEffectWorkflow &&\n        !isWorkflowInvocation &&\n        methodName === 'run' &&\n        call.getArguments().length === 1 &&\n        !exprText.includes('runPromise') &&\n        !exprText.includes('runSync') &&\n        !exprText.includes('runFork') &&\n        !exprText.includes('runCallback') &&\n        !seenCallStarts.has(callStart)\n      ) {\n        const name =\n          extractProgramName(call) ?? `workflow-${programs.length + 1}`;\n        programs.push({\n          name,\n          node: call,\n          type: 'run',\n          ...buildDiscoveryInfo('low', 'workflow-like .run(...) shape heuristic'),\n        });\n        seenCallStarts.add(callStart);\n        continue;\n      }\n    }\n    if (isWorkflowInvocation && !seenCallStarts.has(callStart)) {\n      const name = extractProgramName(call) ?? `workflow-${programs.length + 1}`;\n      programs.push({\n        name,\n        node: call,\n        type: 'run',\n        ...buildDiscoveryInfo('medium', 'workflow builder invocation'),\n      });\n      seenCallStarts.add(callStart);\n      continue;\n    }\n\n    if (\n      _opts.enableEffectWorkflow &&\n      expression.getKind() === SyntaxKind.PropertyAccessExpression\n    ) {\n      const propertyAccess = expression as PropertyAccessExpression;\n      const objectText = propertyAccess.getExpression().getText();\n      const methodName = propertyAccess.getName();\n      const isExecuteEntrypoint =\n        (methodName === 'execute' || methodName === 'executeEncoded') &&\n        workflowProgramBuilders.has(objectText) &&\n        !seenCallStarts.has(callStart);\n      if (isExecuteEntrypoint) {\n        const name =\n          extractProgramName(call) ?? `${objectText}.${methodName}`;\n        programs.push({\n          name,\n          node: call,\n          type: 'workflow-execute',\n          ...buildDiscoveryInfo('medium', 'workflow/activity .execute entrypoint'),\n        });\n        seenCallStarts.add(callStart);\n        continue;\n      }\n    }\n\n    if ((exprText === 'gen' || (exprText.endsWith('.gen') && isEffectLikeCallExpression(call, sourceFile, effectImportNames, _opts.knownEffectInternalsRoot))) && !seenCallStarts.has(callStart)) {\n      const name = extractProgramName(call) ?? extractEnclosingEffectFnName(call) ?? `program-${programs.length + 1}`;\n      programs.push({\n        name,\n        node: call,\n        type: 'generator',\n        ...(exprText === 'gen'\n          ? buildDiscoveryInfo('medium', 'unqualified gen(...) call')\n          : buildDiscoveryInfo('high', 'Effect-like .gen(...) call')),\n      });\n      seenCallStarts.add(callStart);\n    }\n\n    const pipeName = extractProgramName(call);\n    if (\n      exprText.includes('pipe') &&\n      hasEffectInArgs(call, effectImportNames) &&\n      !seenCallStarts.has(callStart) &&\n      expression.getKind() !== SyntaxKind.PropertyAccessExpression &&\n      pipeName !== undefined &&\n      !isInsideEffectGen(call)\n    ) {\n      programs.push({\n        name: pipeName,\n        node: call,\n        type: 'pipe',\n        ...buildDiscoveryInfo('medium', 'exact pipe(...) call with Effect-like args'),\n      });\n      seenCallStarts.add(callStart);\n    }\n\n    if ((isRunCall(call) || isRuntimeCurriedForm(call)) && !seenCallStarts.has(callStart)) {\n      const name = extractProgramName(call) ?? `run-${programs.length + 1}`;\n      programs.push({\n        name,\n        node: call,\n        type: 'run',\n        ...buildDiscoveryInfo('high', 'recognized Runtime/Effect run* entrypoint'),\n      });\n      seenCallStarts.add(callStart);\n    }\n  }\n\n  for (const decl of varDeclarations) {\n    if (!isTopLevelVariableDeclaration(decl)) continue;\n    if (isYieldBoundDeclaration(decl)) continue;\n    const initializer = decl.getInitializer();\n    if (initializer) {\n      const name = decl.getName();\n      const callInitializer = getCallExpressionFromInitializer(initializer);\n      if (callInitializer && isRunCall(callInitializer)) {\n        continue;\n      }\n      if (initializer.getKind() === SyntaxKind.ObjectLiteralExpression) {\n        continue;\n      }\n      const looksLikeEffect = isLikelyDirectEffectInitializer(\n        initializer,\n        effectImportNames,\n        nonProgramEffectImportNames,\n      );\n      if (looksLikeEffect && !programs.some((p) => p.name === name)) {\n        programs.push({\n          name,\n          node: decl,\n          type: 'direct',\n          ...(inferTypeAnnotatedDiscovery(decl) ?? inferDirectInitializerDiscovery(initializer)),\n        });\n      } else if (!looksLikeEffect && !programs.some((p) => p.name === name)) {\n        // Even if the initializer doesn't look like Effect code, check type annotations\n        // This catches arrow functions like: export const f = (args, deps): Effect.Effect<T> => deps.call(args)\n        const typeDiscovery = inferTypeAnnotatedDiscovery(decl);\n        if (typeDiscovery) {\n          programs.push({\n            name,\n            node: decl,\n            type: 'direct',\n            ...typeDiscovery,\n          });\n        }\n      }\n    }\n  }\n\n  const topLevelStatements = sourceFile.getStatements();\n  for (const stmt of topLevelStatements) {\n    if (stmt.getKind() !== SyntaxKind.ExpressionStatement) continue;\n    const expr = (stmt as ExpressionStatement).getExpression();\n    if (expr.getKind() !== SyntaxKind.CallExpression) continue;\n\n    const call = expr as CallExpression;\n    const callStart = call.getStart();\n    if (seenCallStarts.has(callStart)) continue;\n\n    const calleeExpr = call.getExpression();\n    const calleeText = calleeExpr.getText();\n\n    if (isRunCall(call)) {\n      const name = `run-${programs.length + 1}`;\n      programs.push({\n        name,\n        node: call,\n        type: 'run',\n        ...buildDiscoveryInfo('high', 'recognized top-level run* entrypoint'),\n      });\n      seenCallStarts.add(callStart);\n      continue;\n    }\n\n    if (calleeText.endsWith('.pipe') || calleeText === 'pipe') {\n      const args = call.getArguments();\n      const lastArg = args[args.length - 1];\n      if (!lastArg) continue;\n\n      const lastArgText = lastArg.getText();\n      const isRunTerminated =\n        lastArgText.includes('.runMain') ||\n        lastArgText.includes('.runPromise') ||\n        lastArgText.includes('.runSync') ||\n        lastArgText.includes('.runFork');\n\n      if (isRunTerminated) {\n        let baseName: string | undefined;\n        if (calleeExpr.getKind() === SyntaxKind.PropertyAccessExpression) {\n          const propAccess = calleeExpr as PropertyAccessExpression;\n          const baseExpr = propAccess.getExpression();\n          baseName = baseExpr.getText().split('.').pop();\n        }\n        const name = baseName && !programs.some(p => p.name === baseName)\n          ? baseName\n          : `entrypoint-${programs.length + 1}`;\n        programs.push({\n          name,\n          node: call,\n          type: 'run',\n          ...buildDiscoveryInfo('medium', 'top-level pipe(...).run* terminator pattern'),\n        });\n        seenCallStarts.add(callStart);\n      }\n    }\n\n    if (calleeExpr.getKind() === SyntaxKind.Identifier && call.getArguments().length >= 1) {\n      const name = (calleeExpr as Identifier).getText();\n      const isIndirectWrapper = isIndirectRunMainWrapper(call, sourceFile);\n      if (isIndirectWrapper && !programs.some(p => p.name === name)) {\n        programs.push({\n          name,\n          node: call,\n          type: 'run',\n          ...buildDiscoveryInfo('low', 'indirect run wrapper body heuristic'),\n        });\n        seenCallStarts.add(callStart);\n      }\n    }\n  }\n\n  const DATA_SCHEMA_CLASS_PATTERNS = [\n    'Data.TaggedError',\n    'Data.TaggedClass',\n    'Data.Class',\n    'Data.Error',\n    'Schema.Class',\n    'Schema.TaggedClass',\n    'Schema.TaggedError',\n    'Schema.TaggedRequest',\n    'Context.Tag',\n    'Context.Service',\n    'Context.Reference',\n    'Effect.Service',\n  ];\n  const classDeclarations = sourceFile.getDescendantsOfKind(SyntaxKind.ClassDeclaration);\n  for (const classDecl of classDeclarations) {\n    const name = classDecl.getName();\n    if (!name) continue;\n    if (programs.some((p) => p.name === name)) continue;\n    const heritageClauses = classDecl.getHeritageClauses();\n    const matchesPattern = heritageClauses.some((clause) => {\n      const clauseText = clause.getText();\n      return DATA_SCHEMA_CLASS_PATTERNS.some((p) => clauseText.includes(p));\n    });\n    if (matchesPattern) {\n      programs.push({\n        name,\n        node: classDecl,\n        type: 'class',\n        ...buildDiscoveryInfo('medium', 'known Data/Schema/Context class pattern'),\n      });\n    }\n  }\n\n  const topLevelClasses = classDeclarations.filter((c) => {\n    const parent = c.getParent();\n    return parent === sourceFile || parent?.getParent() === sourceFile;\n  });\n  for (const classDecl of topLevelClasses) {\n    const className = classDecl.getName() ?? 'Anonymous';\n\n    const members = classDecl.getMembers();\n    const properties = members.filter(\n      m => m.getKind() === SyntaxKind.PropertyDeclaration\n    ) as PropertyDeclaration[];\n\n    for (const prop of properties) {\n      const initializer = prop.getInitializer();\n      if (!initializer) continue;\n      const memberName = prop.getName();\n      const fullName = `${className}.${memberName}`;\n      if (programs.some(p => p.name === fullName)) continue;\n\n      if (\n        isLikelyDirectEffectInitializer(\n          initializer,\n          effectImportNames,\n          nonProgramEffectImportNames,\n        )\n      ) {\n        programs.push({\n          name: fullName,\n          node: prop,\n          type: 'classProperty',\n          ...(inferTypeAnnotatedDiscovery(prop) ?? inferDirectInitializerDiscovery(initializer)),\n        });\n      }\n    }\n\n    const methods = members.filter(\n      m => m.getKind() === SyntaxKind.MethodDeclaration\n    ) as MethodDeclaration[];\n\n    for (const method of methods) {\n      const memberName = method.getName();\n      const fullName = `${className}.${memberName}`;\n      if (programs.some(p => p.name === fullName)) continue;\n\n      const body = method.getBody();\n      if (!body) continue;\n\n      const returnStatements = body.getDescendantsOfKind(SyntaxKind.ReturnStatement);\n      const hasEffectReturn = returnStatements.some(ret => {\n        const expr = (ret).getExpression();\n        return expr\n          ? isLikelyDirectEffectInitializer(\n              expr,\n              effectImportNames,\n              nonProgramEffectImportNames,\n            )\n          : false;\n      });\n\n      if (hasEffectReturn) {\n        programs.push({\n          name: fullName,\n          node: method,\n          type: 'classMethod',\n          ...(inferTypeAnnotatedDiscovery(method) ?? inferMethodReturnDiscovery(returnStatements)),\n        });\n      }\n    }\n\n    const getters = members.filter(\n      m => m.getKind() === SyntaxKind.GetAccessor\n    ) as GetAccessorDeclaration[];\n\n    for (const getter of getters) {\n      const memberName = getter.getName();\n      const fullName = `${className}.${memberName}`;\n      if (programs.some(p => p.name === fullName)) continue;\n\n      const body = getter.getBody();\n      if (!body) continue;\n\n      const returnStatements = body.getDescendantsOfKind(SyntaxKind.ReturnStatement);\n      const hasEffectReturn = returnStatements.some(ret => {\n        const expr = (ret).getExpression();\n        return expr\n          ? isLikelyDirectEffectInitializer(\n              expr,\n              effectImportNames,\n              nonProgramEffectImportNames,\n            )\n          : false;\n      });\n\n      if (hasEffectReturn) {\n        programs.push({\n          name: fullName,\n          node: getter,\n          type: 'classMethod',\n          ...(inferTypeAnnotatedDiscovery(getter) ?? inferMethodReturnDiscovery(returnStatements)),\n        });\n      }\n    }\n  }\n\n  // Discover exported function declarations whose return type is Effect.Effect\n  const functionDeclarations = sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration);\n  for (const fnDecl of functionDeclarations) {\n    const name = fnDecl.getName();\n    if (!name) continue;\n    if (programs.some((p) => p.name === name)) continue;\n    if (!fnDecl.isExported()) continue;\n    // Skip overload signatures (no body) — only discover the implementation\n    if (!fnDecl.getBody()) continue;\n\n    const returnTypeNode = fnDecl.getReturnTypeNode();\n    if (returnTypeNode && hasEffectFamilyTypeHint(returnTypeNode.getText())) {\n      programs.push({\n        name,\n        node: fnDecl,\n        type: 'functionDeclaration',\n        ...buildDiscoveryInfo('high', 'exported function with Effect-family return type'),\n      });\n    }\n  }\n\n  return programs.filter((program) => {\n    const threshold = _opts.minDiscoveryConfidence ?? 'low';\n    const confidence = program.discoveryConfidence ?? 'low';\n    if (DISCOVERY_CONFIDENCE_RANK[confidence] < DISCOVERY_CONFIDENCE_RANK[threshold]) {\n      return false;\n    }\n    if (_opts.onlyExportedPrograms && !isProgramRootExported(program)) {\n      return false;\n    }\n    return true;\n  });\n};\n\nconst hasEffectInArgs = (\n  call: CallExpression,\n  effectImportNames: Set<string>,\n): boolean => {\n  const args = call.getArguments();\n  const argTexts = args.map((arg) => arg.getText());\n  return argTexts.some((text) =>\n    [...effectImportNames].some((alias) => text.includes(`${alias}.`)),\n  );\n};\n\n// =============================================================================\n// Service definitions\n// =============================================================================\n\nexport function extractServiceDefinitionsFromFile(sourceFile: SourceFile): ServiceDefinition[] {\n  const { SyntaxKind } = loadTsMorph();\n  const results: ServiceDefinition[] = [];\n  const typeChecker = sourceFile.getProject().getTypeChecker();\n  const classDeclarations = sourceFile.getDescendantsOfKind(SyntaxKind.ClassDeclaration);\n  for (const classDecl of classDeclarations) {\n    const name = classDecl.getName();\n    if (!name) continue;\n    const extExpr = classDecl.getExtends();\n    if (!extExpr) continue;\n    const extText = extExpr.getText();\n    if (!extText.includes('Context.Service') && !extText.includes('Context.Tag') && !extText.includes('Effect.Service')) continue;\n    let typeArgs: readonly TypeNode[] = extExpr.getTypeArguments();\n    if (typeArgs.length < 2) {\n      const inner = extExpr.getExpression();\n      if (inner && 'getTypeArguments' in inner && typeof (inner as { getTypeArguments: () => unknown[] }).getTypeArguments === 'function') {\n        typeArgs = (inner as { getTypeArguments: () => readonly TypeNode[] }).getTypeArguments();\n      }\n    }\n    if (typeArgs.length < 2) continue;\n    const interfaceTypeNode = typeArgs[1];\n    if (!interfaceTypeNode) continue;\n    try {\n      const type = typeChecker.getTypeAtLocation(interfaceTypeNode);\n      const methods: string[] = [];\n      const properties: string[] = [];\n      for (const sym of type.getProperties()) {\n        const propName = sym.getName();\n        if (propName.startsWith('_') || propName === 'constructor') continue;\n        const propType = typeChecker.getTypeOfSymbolAtLocation(sym, interfaceTypeNode);\n        const callSigs = propType.getCallSignatures();\n        if (callSigs.length > 0) methods.push(propName);\n        else properties.push(propName);\n      }\n      const classText = classDecl.getText();\n      const hasCustomEquality = classText.includes('Equal.symbol') || classText.includes('[Equal') || classText.includes('equal(');\n      const hasCustomHash = classText.includes('Hash.symbol') || classText.includes('[Hash') || classText.includes('hash(');\n      results.push({\n        tagId: name, methods, properties,\n        ...(hasCustomEquality ? { hasCustomEquality } : {}),\n        ...(hasCustomHash ? { hasCustomHash } : {}),\n      });\n    } catch {\n      // skip\n    }\n  }\n\n  for (const classDecl of classDeclarations) {\n    const name = classDecl.getName();\n    if (!name) continue;\n    const extExpr = classDecl.getExtends();\n    if (!extExpr) continue;\n    const extText = extExpr.getText();\n    if (!extText.includes('Data.Class') && !extText.includes('Data.TaggedClass')) continue;\n    if (results.some(r => r.tagId === name)) continue;\n    const classText = classDecl.getText();\n    const hasCustomEquality = classText.includes('Equal.symbol') || classText.includes('[Equal') || classText.includes('equal(');\n    const hasCustomHash = classText.includes('Hash.symbol') || classText.includes('[Hash') || classText.includes('hash(');\n    if (hasCustomEquality || hasCustomHash) {\n      results.push({ tagId: name, methods: [], properties: [], hasCustomEquality, hasCustomHash });\n    }\n  }\n\n  return results;\n}\n","/**\n * Core program analysis: analyzeProgram, analyzeProgramNode,\n * analyzeGeneratorFunction, analyzeRunEntrypointExpression.\n */\n\nimport { Effect, Option, Clock } from 'effect';\nimport type {\n  SourceFile,\n  Node,\n  CallExpression,\n  ArrowFunction,\n  FunctionDeclaration,\n  FunctionExpression,\n  VariableDeclaration,\n  ClassDeclaration,\n  PropertyDeclaration,\n  MethodDeclaration,\n  GetAccessorDeclaration,\n  StringLiteral,\n  NumericLiteral,\n  ObjectLiteralExpression,\n  PropertyAssignment,\n  PropertyAccessExpression,\n  ArrayLiteralExpression,\n  YieldExpression,\n  ExpressionStatement,\n  VariableStatement,\n  IfStatement,\n  SwitchStatement,\n  CaseClause,\n  ForStatement,\n  ForOfStatement,\n  ForInStatement,\n  WhileStatement,\n  DoStatement,\n  TryStatement,\n  ReturnStatement,\n  ThrowStatement,\n  LabeledStatement,\n  Block,\n  ConditionalExpression,\n  BinaryExpression,\n  Identifier,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  StaticEffectIR,\n  StaticEffectProgram,\n  StaticFlowNode,\n  StaticEffectNode,\n  StaticGeneratorNode,\n  StaticDecisionNode,\n  StaticSwitchNode,\n  StaticSwitchCase,\n  StaticTryCatchNode,\n  StaticTerminalNode,\n  StaticOpaqueNode,\n  StaticLoopNode,\n  StaticParallelNode,\n  StaticRaceNode,\n  StaticRetryNode,\n  StaticLayerNode,\n  AnalysisError,\n  AnalyzerOptions,\n  AnalysisWarning,\n  AnalysisStats,\n} from './types';\nimport {\n  extractEffectTypeSignature,\n  extractServiceRequirements,\n} from './type-extractor';\nimport type { EffectProgram } from './analysis-utils';\nimport { unwrapExpression } from './analysis-utils';\nimport {\n  createEmptyStats,\n  generateId,\n  extractLocation,\n  collectDependencies,\n  collectErrorTypes,\n  getJSDocFromParentVariable,\n  extractJSDocDescription,\n  extractJSDocTags,\n  extractYieldVariableName,\n  computeDisplayName,\n  computeSemanticRole,\n} from './analysis-utils';\nimport { isServiceTagCallee } from './analysis-patterns';\nimport { getAliasesForFile, isEffectLikeCallExpression } from './alias-resolution';\nimport {\n  extractServiceDefinitionsFromFile,\n  getWorkflowBodyNodeForRunCall,\n} from './program-discovery';\nimport {\n  analyzePipeChain,\n  analyzeEffectExpression,\n  analyzeEffectCall,\n} from './effect-analysis';\n\n// =============================================================================\n// Program Analysis\n// =============================================================================\n\nexport const analyzeProgram = (\n  program: EffectProgram,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  tsVersion: string,\n): Effect.Effect<StaticEffectIR, AnalysisError> =>\n  Effect.gen(function* () {\n    const warnings: AnalysisWarning[] = [];\n    const stats = createEmptyStats();\n\n    const children = yield* analyzeProgramNode(\n      program.node,\n      program.type,\n      sourceFile,\n      filePath,\n      opts,\n      warnings,\n      stats,\n    );\n\n    const programJSDoc = getJSDocFromParentVariable(program.node);\n\n    const typeChecker = sourceFile.getProject().getTypeChecker();\n    const typeSignature = extractEffectTypeSignature(program.node, typeChecker);\n    const requiredServices = extractServiceRequirements(program.node, typeChecker);\n\n    const root: StaticEffectProgram = {\n      id: generateId(),\n      type: 'program',\n      programName: program.name,\n      source: program.type,\n      ...(program.discoveryConfidence\n        ? { discoveryConfidence: program.discoveryConfidence }\n        : {}),\n      ...(program.discoveryReason ? { discoveryReason: program.discoveryReason } : {}),\n      children,\n      dependencies: collectDependencies(children),\n      errorTypes: collectErrorTypes(children),\n      typeSignature,\n      requiredServices,\n      location: extractLocation(\n        program.node,\n        filePath,\n        opts.includeLocations ?? false,\n      ),\n      jsdocDescription: programJSDoc,\n      jsdocTags: extractJSDocTags(program.node),\n    };\n\n    const serviceDefinitions = extractServiceDefinitionsFromFile(sourceFile);\n    return {\n      root,\n      metadata: {\n        analyzedAt: yield* Clock.currentTimeMillis,\n        filePath,\n        tsVersion,\n        warnings,\n        stats,\n        ...(serviceDefinitions.length > 0 ? { serviceDefinitions } : {}),\n      },\n      references: new Map(),\n    };\n  });\n\n// =============================================================================\n// Node Analysis\n// =============================================================================\n\nexport const analyzeProgramNode = (\n  node: Node,\n  programType: EffectProgram['type'],\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<readonly StaticFlowNode[], AnalysisError> =>\n  Effect.gen(function* () {\n    switch (programType) {\n      case 'generator': {\n        const genCall = node as CallExpression;\n        const args = genCall.getArguments();\n        if (args.length === 0 || !args[0]) return [];\n        const genChildren = yield* analyzeGeneratorFunction(\n          args[0],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n\n        // If the gen call is the base of an enclosing `.pipe(...)`, analyze the\n        // pipe's Effect-level transformations (retry/timeout/catch/etc.) so\n        // wrappers around the gen are captured in the IR and stats.\n        const outerPipe = findOuterPipeOnGen(genCall);\n        if (outerPipe) {\n          return yield* applyOuterPipeTransformsToGen(\n            genChildren,\n            outerPipe,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n          );\n        }\n        const outerLayerUnwrap = findOuterLayerUnwrapOnGen(genCall);\n        if (outerLayerUnwrap) {\n          const unwrapNode: StaticLayerNode = {\n            id: generateId(),\n            type: 'layer',\n            name: 'Layer.unwrapEffect(gen)',\n            operations: [...genChildren],\n            isMerged: false,\n            lifecycle: 'default',\n            location: extractLocation(\n              outerLayerUnwrap,\n              filePath,\n              opts.includeLocations ?? false,\n            ),\n          };\n          return [{\n            ...unwrapNode,\n            displayName: computeDisplayName(unwrapNode),\n            semanticRole: computeSemanticRole(unwrapNode),\n          }];\n        }\n        return genChildren;\n      }\n\n      case 'pipe': {\n        return yield* analyzePipeChain(\n          node as CallExpression,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      }\n\n      case 'run': {\n        const call = node as CallExpression;\n        const { SyntaxKind } = loadTsMorph();\n        const pipeResult = yield* analyzeRunEntrypointExpression(\n          call,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n        if (Option.isSome(pipeResult)) {\n          return pipeResult.value;\n        }\n\n        const args = call.getArguments();\n        const callbackInArgs = args.find(\n          (arg) =>\n            arg.getKind() === SyntaxKind.ArrowFunction ||\n            arg.getKind() === SyntaxKind.FunctionExpression,\n        );\n        const workflowBody =\n          opts.enableEffectWorkflow &&\n          callbackInArgs === undefined &&\n          args.length === 1\n            ? getWorkflowBodyNodeForRunCall(call, sourceFile)\n            : null;\n        const effect = callbackInArgs ?? workflowBody ?? args[0];\n        if (effect) {\n          const analyzed = yield* analyzeEffectExpression(\n            effect,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n          );\n          return [analyzed];\n        }\n        return [];\n      }\n\n      case 'workflow-execute': {\n        const call = node as CallExpression;\n        const exprText = call.getExpression().getText();\n        const syntheticNode: StaticEffectNode = {\n          id: generateId(),\n          type: 'effect',\n          callee: exprText,\n          name: exprText,\n          semanticRole: 'side-effect',\n          location: extractLocation(call, filePath, opts.includeLocations ?? false),\n        };\n        return [syntheticNode];\n      }\n\n      case 'direct': {\n        const initializer = (node as VariableDeclaration).getInitializer();\n        if (initializer) {\n          // Detect Effect.fn(\"name\")(function* () { ... }) curried call pattern\n          const { SyntaxKind: SK } = loadTsMorph();\n          if (initializer.getKind() === SK.CallExpression) {\n            const outerCall = initializer as CallExpression;\n            const outerExpr = outerCall.getExpression();\n            // Check if the outer expression is itself a call to Effect.fn/Effect.fnUntraced\n            if (outerExpr.getKind() === SK.CallExpression) {\n              const innerCall = outerExpr as CallExpression;\n              const innerCallee = innerCall.getExpression().getText();\n              if (innerCallee.endsWith('.fn') || innerCallee.endsWith('.fnUntraced')) {\n                // The generator function is the first argument of the outer call\n                const outerArgs = outerCall.getArguments();\n                const genArg = outerArgs.find(\n                  (arg) =>\n                    arg.getKind() === SK.FunctionExpression ||\n                    arg.getKind() === SK.ArrowFunction,\n                );\n                if (genArg) {\n                  // Extract traced name from Effect.fn(\"name\")\n                  const fnArgs = innerCall.getArguments();\n                  let tracedName: string | undefined;\n                  if (fnArgs.length > 0) {\n                    const firstArg = fnArgs[0]?.getText() ?? '';\n                    const strMatch = /^[\"'`](.+?)[\"'`]$/.exec(firstArg);\n                    if (strMatch) tracedName = strMatch[1];\n                  }\n                  const constructorKind = innerCallee.endsWith('.fnUntraced') ? 'fnUntraced' as const : 'fn' as const;\n\n                  // Create Effect.fn metadata node preserving constructor info\n                  const fnMetaNode: StaticEffectNode = {\n                    id: generateId(),\n                    type: 'effect',\n                    callee: innerCallee,\n                    location: extractLocation(innerCall, filePath, opts.includeLocations ?? false),\n                    constructorKind,\n                    ...(tracedName ? { tracedName } : {}),\n                  };\n                  stats.totalEffects++;\n                  const enrichedFnNode: StaticEffectNode = {\n                    ...fnMetaNode,\n                    displayName: computeDisplayName(fnMetaNode),\n                    semanticRole: computeSemanticRole(fnMetaNode),\n                  };\n\n                  // Analyze the generator body\n                  const genChildren = yield* analyzeGeneratorFunction(\n                    genArg,\n                    sourceFile,\n                    filePath,\n                    opts,\n                    warnings,\n                    stats,\n                  );\n\n                  return [enrichedFnNode, ...genChildren];\n                }\n              }\n            }\n          }\n          const analyzed = yield* analyzeEffectExpression(\n            initializer,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n          );\n          return [analyzed];\n        }\n        return [];\n      }\n\n      case 'class': {\n        const classDecl = node as ClassDeclaration;\n        let callee = 'Data.Class';\n        for (const clause of classDecl.getHeritageClauses()) {\n          const clauseText = clause.getText();\n          if (clauseText.includes('Data.TaggedError')) { callee = 'Data.TaggedError'; break; }\n          if (clauseText.includes('Data.TaggedClass')) { callee = 'Data.TaggedClass'; break; }\n          if (clauseText.includes('Data.Error')) { callee = 'Data.Error'; break; }\n          if (clauseText.includes('Schema.TaggedRequest')) { callee = 'Schema.TaggedRequest'; break; }\n          if (clauseText.includes('Schema.TaggedError')) { callee = 'Schema.TaggedError'; break; }\n          if (clauseText.includes('Schema.TaggedClass')) { callee = 'Schema.TaggedClass'; break; }\n          if (clauseText.includes('Schema.Class')) { callee = 'Schema.Class'; break; }\n          if (clauseText.includes('Context.Tag')) { callee = 'Context.Tag'; break; }\n          if (clauseText.includes('Context.Service')) { callee = 'Context.Service'; break; }\n          if (clauseText.includes('Context.Reference')) { callee = 'Context.Reference'; break; }\n          if (clauseText.includes('Effect.Service')) { callee = 'Effect.Service'; break; }\n        }\n        const description =\n          callee.includes('Error') ? 'error-type' :\n          callee.includes('Schema') ? 'schema' :\n          callee === 'Context.Service' || callee === 'Context.Tag' || callee === 'Context.Reference' || callee === 'Effect.Service' ? 'service-tag' :\n          'data';\n        const classEffectNode: StaticEffectNode = {\n          id: generateId(),\n          type: 'effect',\n          callee,\n          description,\n          location: extractLocation(node, filePath, opts.includeLocations ?? false),\n          jsdocDescription: extractJSDocDescription(classDecl),\n          jsdocTags: extractJSDocTags(classDecl),\n        };\n        stats.totalEffects++;\n        return [classEffectNode];\n      }\n\n      case 'classProperty': {\n        const prop = node as PropertyDeclaration;\n        const initializer = prop.getInitializer();\n        if (initializer) {\n          const result = yield* analyzeEffectExpression(\n            initializer, sourceFile, filePath, opts, warnings, stats,\n          );\n          return [result];\n        }\n        return [];\n      }\n\n      case 'classMethod': {\n        const method = node as MethodDeclaration | GetAccessorDeclaration;\n        const body = method.getBody();\n        if (!body) return [];\n\n        const { SyntaxKind: SK } = loadTsMorph();\n        const returnStatements = body.getDescendantsOfKind(SK.ReturnStatement);\n        const children: StaticFlowNode[] = [];\n        for (const ret of returnStatements) {\n          const expr = (ret).getExpression();\n          if (expr) {\n            const result = yield* analyzeEffectExpression(\n              expr, sourceFile, filePath, opts, warnings, stats,\n            );\n            children.push(result);\n          }\n        }\n        return children;\n      }\n\n      case 'functionDeclaration': {\n        const fnDecl = node as FunctionDeclaration;\n        const body = fnDecl.getBody();\n        if (!body) return [];\n\n        const { SyntaxKind: SK2 } = loadTsMorph();\n        const returnStatements = body.getDescendantsOfKind(SK2.ReturnStatement);\n        const children: StaticFlowNode[] = [];\n        for (const ret of returnStatements) {\n          const expr = (ret).getExpression();\n          if (expr) {\n            const result = yield* analyzeEffectExpression(\n              expr, sourceFile, filePath, opts, warnings, stats,\n            );\n            children.push(result);\n          }\n        }\n        return children;\n      }\n\n      default:\n        return [];\n    }\n  });\n\n// =============================================================================\n// Statement-Level Walker Helpers\n// =============================================================================\n\n/**\n * Check if a node is a function boundary that should NOT be descended into\n * when searching for generator yields.\n */\nfunction isFunctionBoundary(node: Node): boolean {\n  const { SyntaxKind } = loadTsMorph();\n  const kind = node.getKind();\n  return (\n    kind === SyntaxKind.FunctionDeclaration ||\n    kind === SyntaxKind.FunctionExpression ||\n    kind === SyntaxKind.ArrowFunction ||\n    kind === SyntaxKind.MethodDeclaration ||\n    kind === SyntaxKind.ClassDeclaration ||\n    kind === SyntaxKind.ClassExpression ||\n    kind === SyntaxKind.Constructor\n  );\n}\n\n/**\n * Boundary-aware check: does `node` contain (or is itself) a YieldExpression\n * without crossing into nested function/class bodies?\n */\nfunction containsGeneratorYield(node: Node): boolean {\n  const { SyntaxKind } = loadTsMorph();\n  // Check the node itself first\n  if (node.getKind() === SyntaxKind.YieldExpression) return true;\n  let found = false;\n  node.forEachChild((child) => {\n    if (found) return;\n    if (isFunctionBoundary(child)) return; // SKIP nested functions\n    if (child.getKind() === SyntaxKind.YieldExpression) {\n      found = true;\n      return;\n    }\n    if (containsGeneratorYield(child)) {\n      found = true;\n      return;\n    }\n  });\n  return found;\n}\n\n/**\n * Extract a literal value from an expression node if it's a simple literal.\n * Returns the string representation or undefined if not a literal.\n */\nfunction extractLiteralValue(expr: Node): string | undefined {\n  const { SyntaxKind } = loadTsMorph();\n  const kind = expr.getKind();\n  switch (kind) {\n    case SyntaxKind.StringLiteral:\n      return (expr as StringLiteral).getLiteralValue();\n    case SyntaxKind.NumericLiteral:\n      return (expr as NumericLiteral).getLiteralValue().toString();\n    case SyntaxKind.TrueKeyword:\n      return 'true';\n    case SyntaxKind.FalseKeyword:\n      return 'false';\n    case SyntaxKind.NullKeyword:\n      return 'null';\n    case SyntaxKind.NoSubstitutionTemplateLiteral:\n      return expr.getText().replace(/^`|`$/g, '');\n    default:\n      return undefined;\n  }\n}\n\n/**\n * Resolve const values in a condition string by substituting known const identifiers.\n */\nfunction resolveConditionConsts(condition: string, constValues: Map<string, string>): string {\n  if (constValues.size === 0) return condition;\n  let resolved = condition;\n  for (const [name, value] of constValues) {\n    // Replace standalone identifier references (word boundary) with the resolved value\n    const pattern = new RegExp(`\\\\b${name}\\\\b`, 'g');\n    const replacement = /^\\d/.test(value) || value === 'true' || value === 'false' || value === 'null'\n      ? value\n      : `'${value}'`;\n    resolved = resolved.replace(pattern, replacement);\n  }\n  return resolved;\n}\n\n/**\n * Simplify boolean expressions: true && X → X, false || X → X, etc.\n */\nfunction simplifyBooleanExpression(expr: string): string {\n  let result = expr;\n  // true && X → X\n  result = result.replace(/\\btrue\\b\\s*&&\\s*/g, '');\n  result = result.replace(/\\s*&&\\s*\\btrue\\b/g, '');\n  // false || X → X\n  result = result.replace(/\\bfalse\\b\\s*\\|\\|\\s*/g, '');\n  result = result.replace(/\\s*\\|\\|\\s*\\bfalse\\b/g, '');\n  // false && X → false\n  result = result.replace(/\\bfalse\\b\\s*&&\\s*[^|&]+/g, 'false');\n  // true || X → true\n  result = result.replace(/\\btrue\\b\\s*\\|\\|\\s*[^|&]+/g, 'true');\n  return result.trim();\n}\n\n/**\n * Check if a statement has a terminator (break/return/throw/continue) at the end.\n */\nfunction hasTerminatorStatement(stmts: readonly Node[]): boolean {\n  const { SyntaxKind } = loadTsMorph();\n  if (stmts.length === 0) return false;\n  const last = stmts[stmts.length - 1];\n  if (!last) return false;\n  const kind = last.getKind();\n  return (\n    kind === SyntaxKind.ReturnStatement ||\n    kind === SyntaxKind.ThrowStatement ||\n    kind === SyntaxKind.BreakStatement ||\n    kind === SyntaxKind.ContinueStatement\n  );\n}\n\n/**\n * Collect all yield* expressions from a node in depth-first left-to-right order,\n * respecting function boundaries.\n */\nfunction collectYieldExpressionsDF(node: Node): Node[] {\n  const { SyntaxKind } = loadTsMorph();\n  const results: Node[] = [];\n  node.forEachChild((child) => {\n    if (isFunctionBoundary(child)) return;\n    if (child.getKind() === SyntaxKind.YieldExpression) {\n      results.push(child);\n    } else {\n      results.push(...collectYieldExpressionsDF(child));\n    }\n  });\n  return results;\n}\n\nfunction collectCallExpressionsBoundaryAware(node: Node): CallExpression[] {\n  const { SyntaxKind } = loadTsMorph();\n  const calls: CallExpression[] = [];\n  const visit = (current: Node): void => {\n    current.forEachChild((child) => {\n      if (isFunctionBoundary(child)) return;\n      if (child.getKind() === SyntaxKind.CallExpression) {\n        calls.push(child as CallExpression);\n      }\n      visit(child);\n    });\n  };\n  visit(node);\n  return calls;\n}\n\n// =============================================================================\n// effect-flow Step.* Detection Helpers\n// =============================================================================\n\n/** Known Step.* function names from the effect-flow library. */\nconst STEP_FUNCTIONS = new Set([\n  'Step.run', 'Step.decide', 'Step.branch', 'Step.all',\n  'Step.forEach', 'Step.retry', 'Step.race', 'Step.sleep',\n]);\n\n/**\n * Check if a node is a CallExpression whose callee matches `Step.*` patterns.\n */\nfunction isStepCall(node: Node): boolean {\n  const { SyntaxKind } = loadTsMorph();\n  if (node.getKind() !== SyntaxKind.CallExpression) return false;\n  const callee = (node as CallExpression).getExpression().getText();\n  return STEP_FUNCTIONS.has(callee);\n}\n\n/**\n * Extract the string literal text from a node, or undefined if not a string literal.\n */\nfunction extractStringLiteral(node: Node | undefined): string | undefined {\n  if (!node) return undefined;\n  const { SyntaxKind } = loadTsMorph();\n  if (node.getKind() === SyntaxKind.StringLiteral) {\n    return (node as StringLiteral).getLiteralText();\n  }\n  return undefined;\n}\n\n/**\n * Parse an ObjectLiteralExpression into StaticSwitchCase[] for Step.branch cases.\n */\nfunction parseBranchCases(casesObj: Node | undefined): StaticSwitchCase[] {\n  if (!casesObj) return [];\n  const { SyntaxKind } = loadTsMorph();\n  if (casesObj.getKind() !== SyntaxKind.ObjectLiteralExpression) return [];\n  const cases: StaticSwitchCase[] = [];\n  const objLit = casesObj as ObjectLiteralExpression;\n  for (const prop of objLit.getProperties()) {\n    if (prop.getKind() === SyntaxKind.PropertyAssignment) {\n      const name = (prop as PropertyAssignment).getName();\n      cases.push({\n        labels: [name],\n        isDefault: name === 'default',\n        body: [], // The effect in the property value would need deep analysis\n      });\n    }\n  }\n  return cases;\n}\n\n/**\n * Analyze a Step.* call expression and produce enriched IR nodes.\n * Only called when `ctx.opts.enableEffectFlow` is true.\n */\nfunction analyzeStepCall(\n  callExpr: CallExpression,\n  ctx: WalkerContext,\n): Effect.Effect<StaticFlowNode, AnalysisError> {\n  return Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n    const callee = callExpr.getExpression().getText();\n    const args = callExpr.getArguments();\n\n    switch (callee) {\n      case 'Step.run': {\n        // Step.run(id, effect) -> analyze the inner effect, enrich with step ID\n        const stepId = extractStringLiteral(args[0]);\n        const innerEffect = args[1];\n        if (!innerEffect) {\n          const node: StaticEffectNode = {\n            id: generateId(),\n            type: 'effect',\n            callee: 'Step.run',\n            name: stepId,\n            displayName: stepId,\n          };\n          ctx.stats.totalEffects++;\n          return node;\n        }\n        const analyzed = yield* analyzeEffectExpression(\n          innerEffect,\n          ctx.sourceFile,\n          ctx.filePath,\n          ctx.opts,\n          ctx.warnings,\n          ctx.stats,\n          ctx.serviceScope,\n        );\n        return {\n          ...analyzed,\n          displayName: stepId ?? analyzed.displayName,\n          name: stepId ?? analyzed.name,\n        };\n      }\n\n      case 'Step.decide': {\n        // Step.decide(id, label, conditionEffect) -> StaticDecisionNode\n        const stepId = extractStringLiteral(args[0]);\n        const label = extractStringLiteral(args[1]);\n        ctx.stats.decisionCount++;\n        const decisionNode: StaticDecisionNode = {\n          id: generateId(),\n          type: 'decision',\n          decisionId: stepId ?? generateId(),\n          label: label ?? stepId ?? 'decision',\n          condition: args[2]?.getText() ?? 'unknown',\n          source: 'effect-flow',\n          onTrue: [],   // The if/else around it captures branches\n          onFalse: undefined,\n        };\n        return decisionNode;\n      }\n\n      case 'Step.branch': {\n        // Step.branch(id, expression, cases) -> StaticSwitchNode\n        const stepId = extractStringLiteral(args[0]);\n        const expression = args[1]?.getText() ?? 'unknown';\n        const casesObj = args[2];\n        const cases = parseBranchCases(casesObj);\n        ctx.stats.switchCount++;\n        const switchNode: StaticSwitchNode = {\n          id: generateId(),\n          type: 'switch',\n          switchId: stepId,\n          expression,\n          cases,\n          source: 'effect-flow',\n          hasDefault: cases.some((c) => c.isDefault),\n          hasFallthrough: false,\n        };\n        return switchNode;\n      }\n\n      case 'Step.all': {\n        // Step.all(id, effects) -> StaticParallelNode with enriched name\n        const stepId = extractStringLiteral(args[0]);\n        const effectsArg = args[1];\n        const children: StaticFlowNode[] = [];\n        if (effectsArg?.getKind() === SyntaxKind.ArrayLiteralExpression) {\n          const arrayLit = effectsArg as ArrayLiteralExpression;\n          for (const element of arrayLit.getElements()) {\n            const analyzed = yield* analyzeEffectExpression(\n              element,\n              ctx.sourceFile,\n              ctx.filePath,\n              ctx.opts,\n              ctx.warnings,\n              ctx.stats,\n              ctx.serviceScope,\n            );\n            children.push(analyzed);\n          }\n        }\n        ctx.stats.parallelCount++;\n        const parallelNode: StaticParallelNode = {\n          id: generateId(),\n          type: 'parallel',\n          name: stepId,\n          displayName: stepId,\n          children,\n          mode: 'parallel',\n          callee: 'Step.all',\n        };\n        return parallelNode;\n      }\n\n      case 'Step.forEach': {\n        // Step.forEach(id, items, fn) -> StaticLoopNode with enriched name\n        const stepId = extractStringLiteral(args[0]);\n        const iterSource = args[1]?.getText();\n        const fn = args[2];\n        let body: StaticFlowNode = { id: generateId(), type: 'effect', callee: 'unknown' };\n        if (fn) {\n          const analyzed = yield* analyzeEffectExpression(\n            fn,\n            ctx.sourceFile,\n            ctx.filePath,\n            ctx.opts,\n            ctx.warnings,\n            ctx.stats,\n            ctx.serviceScope,\n          );\n          body = analyzed;\n        }\n        ctx.stats.loopCount++;\n        const loopNode: StaticLoopNode = {\n          id: generateId(),\n          type: 'loop',\n          name: stepId,\n          displayName: stepId,\n          loopType: 'forEach',\n          iterSource,\n          body,\n        };\n        return loopNode;\n      }\n\n      case 'Step.retry': {\n        // Step.retry(id, effect, options) -> StaticRetryNode\n        const stepId = extractStringLiteral(args[0]);\n        const innerEffect = args[1];\n        if (!innerEffect) {\n          const node: StaticEffectNode = {\n            id: generateId(),\n            type: 'effect',\n            callee: 'Step.retry',\n            name: stepId,\n            displayName: stepId,\n          };\n          ctx.stats.totalEffects++;\n          return node;\n        }\n        const analyzed = yield* analyzeEffectExpression(\n          innerEffect,\n          ctx.sourceFile,\n          ctx.filePath,\n          ctx.opts,\n          ctx.warnings,\n          ctx.stats,\n          ctx.serviceScope,\n        );\n        ctx.stats.retryCount++;\n        const retryNode: StaticRetryNode = {\n          id: generateId(),\n          type: 'retry',\n          name: stepId,\n          displayName: stepId,\n          source: analyzed,\n          hasFallback: false,\n        };\n        return retryNode;\n      }\n\n      case 'Step.race': {\n        // Step.race(id, effects) -> StaticRaceNode\n        const stepId = extractStringLiteral(args[0]);\n        const effectsArg = args[1];\n        const children: StaticFlowNode[] = [];\n        if (effectsArg?.getKind() === SyntaxKind.ArrayLiteralExpression) {\n          const arrayLit = effectsArg as ArrayLiteralExpression;\n          for (const element of arrayLit.getElements()) {\n            const analyzed = yield* analyzeEffectExpression(\n              element,\n              ctx.sourceFile,\n              ctx.filePath,\n              ctx.opts,\n              ctx.warnings,\n              ctx.stats,\n              ctx.serviceScope,\n            );\n            children.push(analyzed);\n          }\n        }\n        ctx.stats.raceCount++;\n        const raceNode: StaticRaceNode = {\n          id: generateId(),\n          type: 'race',\n          name: stepId,\n          displayName: stepId,\n          children,\n          callee: 'Step.race',\n        };\n        return raceNode;\n      }\n\n      case 'Step.sleep': {\n        // Step.sleep(id, duration) -> StaticEffectNode with scheduling role\n        const stepId = extractStringLiteral(args[0]);\n        const effectNode: StaticEffectNode = {\n          id: generateId(),\n          type: 'effect',\n          callee: 'Step.sleep',\n          name: stepId,\n          displayName: stepId,\n          semanticRole: 'scheduling',\n        };\n        ctx.stats.totalEffects++;\n        return effectNode;\n      }\n\n      default: {\n        // Unknown Step.* call — fallback to generic effect analysis\n        const node: StaticEffectNode = {\n          id: generateId(),\n          type: 'effect',\n          callee,\n          name: callee,\n          displayName: callee,\n        };\n        ctx.stats.totalEffects++;\n        return node;\n      }\n    }\n  });\n}\n\n/** Walker context threaded through statement analysis. */\ninterface WalkerContext {\n  readonly sourceFile: SourceFile;\n  readonly filePath: string;\n  readonly opts: Required<AnalyzerOptions>;\n  readonly warnings: AnalysisWarning[];\n  readonly stats: AnalysisStats;\n  readonly serviceScope: Map<string, string>;\n  /** Parameter names accepted by Effect.gen callback adapters, e.g. `_` in `Effect.gen(function*(_) {})`. */\n  readonly generatorAdapterParams: ReadonlySet<string>;\n  /** Tracks const declarations with literal initializers for condition simplification */\n  readonly constValues: Map<string, string>;\n}\n\n/**\n * Analyze a single yield expression: call analyzeEffectExpression on\n * its inner expression, enrich, and track service scope.\n */\nfunction analyzeYieldNode(\n  yieldNode: Node,\n  ctx: WalkerContext,\n): Effect.Effect<{ variableName: string | undefined; effect: StaticFlowNode }, AnalysisError> {\n  return Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n    const yieldExpr = yieldNode as YieldExpression;\n    const isDelegated = yieldExpr.getText().startsWith('yield*');\n    const expr = yieldExpr.getExpression();\n\n    // Plain yield (not yield*)\n    if (!isDelegated) {\n      const opaqueNode: StaticOpaqueNode = {\n        id: generateId(),\n        type: 'opaque',\n        reason: 'plain-yield',\n        sourceText: yieldNode.getText().slice(0, 80),\n      };\n      ctx.stats.opaqueCount++;\n      ctx.warnings.push({\n        code: 'PLAIN_YIELD',\n        message: `Plain yield (not yield*) detected; this is unusual in Effect generators: ${yieldNode.getText().slice(0, 60)}`,\n        location: extractLocation(yieldNode, ctx.filePath, ctx.opts.includeLocations ?? false),\n      });\n      return { variableName: extractYieldVariableName(yieldNode), effect: opaqueNode };\n    }\n\n    if (!expr) {\n      const opaqueNode: StaticOpaqueNode = {\n        id: generateId(),\n        type: 'opaque',\n        reason: 'yield-no-expression',\n        sourceText: yieldNode.getText().slice(0, 80),\n      };\n      ctx.stats.opaqueCount++;\n      return { variableName: undefined, effect: opaqueNode };\n    }\n\n    // Effect.gen adapter form: yield* _(effect)\n    // Widely used in Effect ecosystem examples and wrappers.\n    let effectExpr: Node = expr;\n    const unwrappedCall = unwrapExpression(expr);\n    if (unwrappedCall.getKind() === SyntaxKind.CallExpression) {\n      const call = unwrappedCall as CallExpression;\n      const calleeExpr = call.getExpression();\n      if (\n        calleeExpr.getKind() === SyntaxKind.Identifier &&\n        ctx.generatorAdapterParams.has((calleeExpr as Identifier).getText()) &&\n        call.getArguments().length >= 1\n      ) {\n        effectExpr = (call.getArguments()[0]) ?? expr;\n      }\n    }\n\n    // effect-flow: intercept Step.* calls when enableEffectFlow is active\n    const unwrappedExpr = unwrapExpression(effectExpr);\n    if (ctx.opts.enableEffectFlow && isStepCall(unwrappedExpr)) {\n      const stepResult = yield* analyzeStepCall(unwrappedExpr as CallExpression, ctx);\n      const variableName = extractYieldVariableName(yieldNode);\n      const enrichedStep = {\n        ...stepResult,\n        displayName: stepResult.displayName ?? computeDisplayName(stepResult, variableName),\n        semanticRole: stepResult.semanticRole ?? computeSemanticRole(stepResult),\n      };\n      return { variableName, effect: enrichedStep };\n    }\n\n    const analyzed = yield* analyzeEffectExpression(\n      effectExpr,\n      ctx.sourceFile,\n      ctx.filePath,\n      ctx.opts,\n      ctx.warnings,\n      ctx.stats,\n      ctx.serviceScope,\n    );\n    const variableName = extractYieldVariableName(yieldNode);\n    if (\n      variableName &&\n      analyzed.type === 'effect' &&\n      isServiceTagCallee((analyzed).callee)\n    ) {\n      ctx.serviceScope.set(variableName, (analyzed).callee);\n    }\n    const enrichedEffect = {\n      ...analyzed,\n      ...(variableName && analyzed.type === 'fiber' ? { name: variableName } : {}),\n      displayName: computeDisplayName(analyzed, variableName),\n      semanticRole: analyzed.semanticRole ?? computeSemanticRole(analyzed),\n    };\n    return { variableName, effect: enrichedEffect };\n  });\n}\n\n/**\n * Walk a block (or block-like body) statement-by-statement and produce structured IR.\n */\nfunction analyzeGeneratorBody(\n  block: import('ts-morph').Block,\n  ctx: WalkerContext,\n): Effect.Effect<StaticGeneratorNode['yields'], AnalysisError> {\n  return Effect.gen(function* () {\n    const stmts = block.getStatements();\n    const result: StaticGeneratorNode['yields'][number][] = [];\n    for (const stmt of stmts) {\n      const nodes = yield* analyzeStatement(stmt, ctx);\n      result.push(...nodes);\n    }\n    return result;\n  });\n}\n\n/**\n * Main statement dispatcher: analyze a single statement and return yield entries.\n */\nfunction analyzeStatement(\n  stmt: Node,\n  ctx: WalkerContext,\n): Effect.Effect<StaticGeneratorNode['yields'], AnalysisError> {\n  return Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n    const kind = stmt.getKind();\n\n    switch (kind) {\n      // -------------------------------------------------------------------\n      // ExpressionStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.ExpressionStatement: {\n        const exprStmt = stmt as ExpressionStatement;\n        const expr = exprStmt.getExpression();\n        return yield* analyzeExpressionForYields(expr, ctx);\n      }\n\n      // -------------------------------------------------------------------\n      // VariableStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.VariableStatement: {\n        const varStmt = stmt as VariableStatement;\n        const result: StaticGeneratorNode['yields'][number][] = [];\n        const { VariableDeclarationKind } = loadTsMorph();\n        const isConst = varStmt.getDeclarationKind() === VariableDeclarationKind.Const;\n        for (const decl of varStmt.getDeclarations()) {\n          const init = decl.getInitializer();\n\n          // Track const declarations with literal initializers for condition resolution\n          if (isConst && init) {\n            const literalValue = extractLiteralValue(init);\n            if (literalValue !== undefined) {\n              ctx.constValues.set(decl.getName(), literalValue);\n            }\n          }\n\n          // Preserve Context.pick/Context.omit steps even when not yield*'d.\n          // These are pure but context-shaping and are part of intended IR coverage.\n          if (init && !containsGeneratorYield(init) && init.getKind() === SyntaxKind.CallExpression) {\n            const callExpr = init as CallExpression;\n            const calleeText = callExpr.getExpression().getText();\n            if (calleeText === 'Context.pick' || calleeText === 'Context.omit') {\n              const analyzed = yield* analyzeEffectExpression(\n                callExpr,\n                ctx.sourceFile,\n                ctx.filePath,\n                ctx.opts,\n                ctx.warnings,\n                ctx.stats,\n                ctx.serviceScope,\n              );\n              if (analyzed.type === 'effect' && analyzed.description === 'context') {\n                result.push({ variableName: decl.getName(), effect: analyzed });\n              }\n              continue;\n            }\n          }\n\n          if (init && containsGeneratorYield(init)) {\n            const yieldEntries = yield* analyzeExpressionForYields(init, ctx);\n            // Try to get variable name from the declaration for the last yield\n            if (yieldEntries.length > 0) {\n              const declName = decl.getName();\n              const lastEntry = yieldEntries[yieldEntries.length - 1];\n              if (lastEntry) {\n                yieldEntries[yieldEntries.length - 1] = {\n                  ...lastEntry,\n                  variableName: lastEntry.variableName ?? declName,\n                };\n              }\n            }\n            result.push(...yieldEntries);\n          }\n        }\n        return result;\n      }\n\n      // -------------------------------------------------------------------\n      // IfStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.IfStatement: {\n        if (!containsGeneratorYield(stmt)) return [];\n        const ifStmt = stmt as IfStatement;\n        const condition = ifStmt.getExpression().getText();\n\n        // Check if condition itself has yields\n        const condYields = yield* analyzeExpressionForYields(\n          ifStmt.getExpression(),\n          ctx,\n        );\n\n        const thenStmt = ifStmt.getThenStatement();\n        const elseStmt = ifStmt.getElseStatement();\n\n        const onTrue = yield* analyzeStatementBlock(thenStmt, ctx);\n        const onFalse = elseStmt\n          ? yield* analyzeStatementBlock(elseStmt, ctx)\n          : undefined;\n\n        const resolvedCondition = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n        const decisionLabel = resolvedCondition.length > 40 ? resolvedCondition.slice(0, 40) + '...' : resolvedCondition;\n        const decisionNode: StaticDecisionNode = {\n          id: generateId(),\n          type: 'decision',\n          decisionId: generateId(),\n          label: decisionLabel,\n          condition,\n          source: 'raw-if',\n          onTrue: onTrue.map((y) => y.effect),\n          onFalse: onFalse && onFalse.length > 0 ? onFalse.map((y) => y.effect) : undefined,\n        };\n        ctx.stats.decisionCount++;\n\n        return [\n          ...condYields,\n          { effect: decisionNode },\n        ];\n      }\n\n      // -------------------------------------------------------------------\n      // SwitchStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.SwitchStatement: {\n        if (!containsGeneratorYield(stmt)) return [];\n        const switchStmt = stmt as SwitchStatement;\n        const expression = switchStmt.getExpression().getText();\n\n        const clauses = switchStmt.getClauses();\n        const cases: StaticSwitchCase[] = [];\n        let hasFallthrough = false;\n        let hasDefault = false;\n\n        // Build fallthrough groups\n        let currentLabels: string[] = [];\n        let currentBodyYields: StaticGeneratorNode['yields'] = [];\n        let currentIsDefault = false;\n\n        for (const clause of clauses) {\n          const isDefault = clause.getKind() === SyntaxKind.DefaultClause;\n          if (isDefault) {\n            hasDefault = true;\n            currentIsDefault = true;\n            currentLabels.push('default');\n          } else {\n            const caseClause = clause as CaseClause;\n            currentLabels.push(caseClause.getExpression().getText());\n          }\n\n          const clauseStmts = clause.getStatements();\n          if (clauseStmts.length === 0) {\n            // Empty clause body = fallthrough\n            hasFallthrough = true;\n            continue;\n          }\n\n          // Analyze clause body\n          for (const clauseStmt of clauseStmts) {\n            const yieldEntries = yield* analyzeStatement(clauseStmt, ctx);\n            currentBodyYields.push(...yieldEntries);\n          }\n\n          const hasTerminator = hasTerminatorStatement(clauseStmts);\n          if (!hasTerminator) {\n            hasFallthrough = true;\n          }\n\n          cases.push({\n            labels: currentLabels,\n            isDefault: currentIsDefault,\n            body: currentBodyYields.map((y) => y.effect),\n          });\n          currentLabels = [];\n          currentBodyYields = [];\n          currentIsDefault = false;\n        }\n\n        // Flush remaining group\n        if (currentLabels.length > 0) {\n          cases.push({\n            labels: currentLabels,\n            isDefault: currentIsDefault,\n            body: currentBodyYields.map((y) => y.effect),\n          });\n        }\n\n        const resolvedExpression = resolveConditionConsts(expression, ctx.constValues);\n        const switchNode: StaticSwitchNode = {\n          id: generateId(),\n          type: 'switch',\n          switchId: generateId(),\n          expression: resolvedExpression,\n          cases,\n          source: 'raw-js',\n          hasDefault,\n          hasFallthrough,\n        };\n        ctx.stats.switchCount++;\n\n        return [{ effect: switchNode }];\n      }\n\n      // -------------------------------------------------------------------\n      // ForStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.ForStatement: {\n        if (!containsGeneratorYield(stmt)) return [];\n        const forStmt = stmt as ForStatement;\n\n        // Check for yields in header (initializer / incrementor)\n        const headerYields: StaticFlowNode[] = [];\n        const initializer = forStmt.getInitializer();\n        if (initializer && containsGeneratorYield(initializer)) {\n          const entries = yield* analyzeExpressionForYields(initializer, ctx);\n          headerYields.push(...entries.map((e) => e.effect));\n        }\n        const incrementor = forStmt.getIncrementor();\n        if (incrementor && containsGeneratorYield(incrementor)) {\n          const entries = yield* analyzeExpressionForYields(incrementor, ctx);\n          headerYields.push(...entries.map((e) => e.effect));\n        }\n\n        const bodyStmt = forStmt.getStatement();\n        const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n        const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n        const condition = forStmt.getCondition();\n        const iterSource = condition ? condition.getText() : undefined;\n\n        const loopBody: StaticFlowNode =\n          bodyYields.length === 1 && bodyYields[0]\n            ? bodyYields[0].effect\n            : {\n                id: generateId(),\n                type: 'generator' as const,\n                yields: bodyYields,\n              };\n\n        const loopNode: StaticLoopNode = {\n          id: generateId(),\n          type: 'loop',\n          loopType: 'for',\n          iterSource,\n          body: loopBody,\n          ...(hasEarlyExit ? { hasEarlyExit } : {}),\n          ...(headerYields.length > 0 ? { headerYields } : {}),\n        };\n        ctx.stats.loopCount++;\n\n        return [{ effect: loopNode }];\n      }\n\n      // -------------------------------------------------------------------\n      // ForOfStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.ForOfStatement: {\n        if (!containsGeneratorYield(stmt)) return [];\n        const forOfStmt = stmt as ForOfStatement;\n\n        const iterExpr = forOfStmt.getExpression();\n        const iterSource = iterExpr.getText();\n\n        // Check for yield* in the iterable expression: `for (const x of yield* items)`\n        const headerYields: StaticFlowNode[] = [];\n        if (containsGeneratorYield(iterExpr)) {\n          const entries = yield* analyzeExpressionForYields(iterExpr, ctx);\n          headerYields.push(...entries.map((e) => e.effect));\n        }\n\n        const iterVariable = forOfStmt.getInitializer().getText();\n\n        const bodyStmt = forOfStmt.getStatement();\n        const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n        const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n        const loopBody: StaticFlowNode =\n          bodyYields.length === 1 && bodyYields[0]\n            ? bodyYields[0].effect\n            : {\n                id: generateId(),\n                type: 'generator' as const,\n                yields: bodyYields,\n              };\n\n        const loopNode: StaticLoopNode = {\n          id: generateId(),\n          type: 'loop',\n          loopType: 'forOf',\n          iterSource,\n          body: loopBody,\n          ...(hasEarlyExit ? { hasEarlyExit } : {}),\n          ...(headerYields.length > 0 ? { headerYields } : {}),\n          iterVariable,\n        };\n        ctx.stats.loopCount++;\n\n        return [{ effect: loopNode }];\n      }\n\n      // -------------------------------------------------------------------\n      // ForInStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.ForInStatement: {\n        if (!containsGeneratorYield(stmt)) return [];\n        const forInStmt = stmt as ForInStatement;\n\n        const iterSource = forInStmt.getExpression().getText();\n        const iterVariable = forInStmt.getInitializer().getText();\n\n        const bodyStmt = forInStmt.getStatement();\n        const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n        const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n        const loopBody: StaticFlowNode =\n          bodyYields.length === 1 && bodyYields[0]\n            ? bodyYields[0].effect\n            : {\n                id: generateId(),\n                type: 'generator' as const,\n                yields: bodyYields,\n              };\n\n        const loopNode: StaticLoopNode = {\n          id: generateId(),\n          type: 'loop',\n          loopType: 'forIn',\n          iterSource,\n          body: loopBody,\n          ...(hasEarlyExit ? { hasEarlyExit } : {}),\n          iterVariable,\n        };\n        ctx.stats.loopCount++;\n\n        return [{ effect: loopNode }];\n      }\n\n      // -------------------------------------------------------------------\n      // WhileStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.WhileStatement: {\n        if (!containsGeneratorYield(stmt)) return [];\n        const whileStmt = stmt as WhileStatement;\n\n        const condition = whileStmt.getExpression().getText();\n\n        const bodyStmt = whileStmt.getStatement();\n        const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n        const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n        const loopBody: StaticFlowNode =\n          bodyYields.length === 1 && bodyYields[0]\n            ? bodyYields[0].effect\n            : {\n                id: generateId(),\n                type: 'generator' as const,\n                yields: bodyYields,\n              };\n\n        const loopNode: StaticLoopNode = {\n          id: generateId(),\n          type: 'loop',\n          loopType: 'while',\n          iterSource: condition,\n          body: loopBody,\n          ...(hasEarlyExit ? { hasEarlyExit } : {}),\n        };\n        ctx.stats.loopCount++;\n\n        return [{ effect: loopNode }];\n      }\n\n      // -------------------------------------------------------------------\n      // DoStatement (do-while)\n      // -------------------------------------------------------------------\n      case SyntaxKind.DoStatement: {\n        if (!containsGeneratorYield(stmt)) return [];\n        const doStmt = stmt as DoStatement;\n\n        const condition = doStmt.getExpression().getText();\n\n        const bodyStmt = doStmt.getStatement();\n        const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n        const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n        const loopBody: StaticFlowNode =\n          bodyYields.length === 1 && bodyYields[0]\n            ? bodyYields[0].effect\n            : {\n                id: generateId(),\n                type: 'generator' as const,\n                yields: bodyYields,\n              };\n\n        const loopNode: StaticLoopNode = {\n          id: generateId(),\n          type: 'loop',\n          loopType: 'doWhile',\n          iterSource: condition,\n          body: loopBody,\n          ...(hasEarlyExit ? { hasEarlyExit } : {}),\n        };\n        ctx.stats.loopCount++;\n\n        return [{ effect: loopNode }];\n      }\n\n      // -------------------------------------------------------------------\n      // TryStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.TryStatement: {\n        if (!containsGeneratorYield(stmt)) return [];\n        const tryStmt = stmt as TryStatement;\n\n        const tryBlock = tryStmt.getTryBlock();\n        const tryYields = yield* analyzeGeneratorBody(tryBlock, ctx);\n\n        const catchClause = tryStmt.getCatchClause();\n        let catchVariable: string | undefined;\n        let catchYields: StaticGeneratorNode['yields'] | undefined;\n        if (catchClause) {\n          const variableDecl = catchClause.getVariableDeclaration();\n          catchVariable = variableDecl?.getName();\n          const catchBlock = catchClause.getBlock();\n          catchYields = yield* analyzeGeneratorBody(catchBlock, ctx);\n        }\n\n        const finallyBlock = tryStmt.getFinallyBlock();\n        let finallyYields: StaticGeneratorNode['yields'] | undefined;\n        if (finallyBlock) {\n          finallyYields = yield* analyzeGeneratorBody(finallyBlock, ctx);\n        }\n\n        const hasTerminalInTry = hasTerminatorStatement(tryBlock.getStatements());\n\n        const tryCatchNode: StaticTryCatchNode = {\n          id: generateId(),\n          type: 'try-catch',\n          tryBody: tryYields.map((y) => y.effect),\n          ...(catchVariable ? { catchVariable } : {}),\n          ...(catchYields && catchYields.length > 0\n            ? { catchBody: catchYields.map((y) => y.effect) }\n            : {}),\n          ...(finallyYields && finallyYields.length > 0\n            ? { finallyBody: finallyYields.map((y) => y.effect) }\n            : {}),\n          hasTerminalInTry,\n        };\n        ctx.stats.tryCatchCount++;\n\n        return [{ effect: tryCatchNode }];\n      }\n\n      // -------------------------------------------------------------------\n      // ReturnStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.ReturnStatement: {\n        const retStmt = stmt as ReturnStatement;\n        const expr = retStmt.getExpression();\n\n        if (!expr) {\n          return [];\n        }\n\n        if (!containsGeneratorYield(expr)) {\n          const { SyntaxKind } = loadTsMorph();\n          const entries: StaticFlowNode[] = [];\n          if (expr.getKind() === SyntaxKind.CallExpression) {\n            const analyzed = yield* analyzeEffectExpression(\n              expr,\n              ctx.sourceFile,\n              ctx.filePath,\n              ctx.opts,\n              ctx.warnings,\n              ctx.stats,\n              ctx.serviceScope,\n            );\n            if (analyzed.type !== 'unknown') {\n              entries.push(analyzed);\n            }\n          }\n\n          const descendantCalls = expr.getDescendantsOfKind(SyntaxKind.CallExpression);\n          for (const call of descendantCalls) {\n            const analyzed = yield* analyzeEffectExpression(\n              call,\n              ctx.sourceFile,\n              ctx.filePath,\n              ctx.opts,\n              ctx.warnings,\n              ctx.stats,\n              ctx.serviceScope,\n            );\n            if (analyzed.type !== 'unknown') {\n              const duplicate = entries.some(\n                (entry) =>\n                  entry.type === analyzed.type &&\n                  'id' in entry &&\n                  ((entry as StaticFlowNode & { callee?: string }).callee ===\n                    (analyzed as StaticFlowNode & { callee?: string }).callee),\n              );\n              if (!duplicate) entries.push(analyzed);\n            }\n          }\n\n          if (entries.length === 0) return [];\n          const termNode: StaticTerminalNode = {\n            id: generateId(),\n            type: 'terminal',\n            terminalKind: 'return',\n            value: entries,\n          };\n          ctx.stats.terminalCount++;\n          return [{ effect: termNode }];\n        }\n\n        // return yield* X or return (yield* X) — analyze the yield expression\n        const yieldEntries = yield* analyzeExpressionForYields(expr, ctx);\n        const termNode: StaticTerminalNode = {\n          id: generateId(),\n          type: 'terminal',\n          terminalKind: 'return',\n          value: yieldEntries.map((y) => y.effect),\n        };\n        ctx.stats.terminalCount++;\n        return [{ effect: termNode }];\n      }\n\n      // -------------------------------------------------------------------\n      // ThrowStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.ThrowStatement: {\n        const throwStmt = stmt as ThrowStatement;\n        const expr = throwStmt.getExpression();\n        if (!containsGeneratorYield(expr)) {\n          // throw without yields — skip (not interesting for the IR at top level)\n          return [];\n        }\n\n        const valueYields = yield* analyzeExpressionForYields(expr, ctx);\n\n        const termNode: StaticTerminalNode = {\n          id: generateId(),\n          type: 'terminal',\n          terminalKind: 'throw',\n          ...(valueYields.length > 0 ? { value: valueYields.map((y) => y.effect) } : {}),\n        };\n        ctx.stats.terminalCount++;\n        return [{ effect: termNode }];\n      }\n\n      // -------------------------------------------------------------------\n      // BreakStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.BreakStatement: {\n        // Only emit break as a terminal when inside a yield-containing control flow.\n        // We always skip at the top level since it can't appear there anyway,\n        // but it may appear inside switch/loop bodies that we recurse into.\n        return [];\n      }\n\n      // -------------------------------------------------------------------\n      // ContinueStatement\n      // -------------------------------------------------------------------\n      case SyntaxKind.ContinueStatement: {\n        // Same as break — skip as a yield entry.\n        return [];\n      }\n\n      // -------------------------------------------------------------------\n      // LabeledStatement — unwrap inner statement\n      // -------------------------------------------------------------------\n      case SyntaxKind.LabeledStatement: {\n        const labeledStmt = stmt as LabeledStatement;\n        return yield* analyzeStatement(labeledStmt.getStatement(), ctx);\n      }\n\n      // -------------------------------------------------------------------\n      // Block — recurse\n      // -------------------------------------------------------------------\n      case SyntaxKind.Block: {\n        return yield* analyzeGeneratorBody(stmt as Block, ctx);\n      }\n\n      // -------------------------------------------------------------------\n      // Default — skip non-yield-containing statements\n      // -------------------------------------------------------------------\n      default:\n        return [];\n    }\n  });\n}\n\n/**\n * Analyze a statement or block-like node into yield entries.\n * If the node is a Block, delegate to analyzeGeneratorBody.\n * Otherwise, treat it as a single statement (e.g., an if-then body without braces).\n */\nfunction analyzeStatementBlock(\n  stmt: Node,\n  ctx: WalkerContext,\n): Effect.Effect<StaticGeneratorNode['yields'], AnalysisError> {\n  const { SyntaxKind } = loadTsMorph();\n  if (stmt.getKind() === SyntaxKind.Block) {\n    return analyzeGeneratorBody(stmt as Block, ctx);\n  }\n  return analyzeStatement(stmt, ctx);\n}\n\n/**\n * Check if a statement body contains an early exit (break/return) at any depth,\n * respecting function boundaries.\n */\nfunction checkEarlyExit(stmt: Node): boolean {\n  const { SyntaxKind } = loadTsMorph();\n  let found = false;\n  stmt.forEachChild((child) => {\n    if (found) return;\n    if (isFunctionBoundary(child)) return;\n    const k = child.getKind();\n    if (k === SyntaxKind.BreakStatement || k === SyntaxKind.ReturnStatement) {\n      found = true;\n      return;\n    }\n    if (checkEarlyExit(child)) {\n      found = true;\n      return;\n    }\n  });\n  return found;\n}\n\n/**\n * Analyze an expression node for yield expressions. Handles:\n * - Direct yield/yield* expressions\n * - Ternary expressions: cond ? yield* A : yield* B\n * - Short-circuit: cond && yield* A, cond || yield* B, x ?? yield* A\n * - Fallback: collect all yield* in evaluation order\n */\nfunction analyzeExpressionForYields(\n  expr: Node,\n  ctx: WalkerContext,\n): Effect.Effect<StaticGeneratorNode['yields'], AnalysisError> {\n  return Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n\n    if (!containsGeneratorYield(expr)) return [];\n\n    const unwrapped = unwrapExpression(expr);\n    const exprKind = unwrapped.getKind();\n\n    // Direct yield expression\n    if (exprKind === SyntaxKind.YieldExpression) {\n      const entry = yield* analyzeYieldNode(unwrapped, ctx);\n      return [entry];\n    }\n\n    // Ternary: cond ? (yield* A) : (yield* B)\n    if (exprKind === SyntaxKind.ConditionalExpression) {\n      const ternary = unwrapped as ConditionalExpression;\n      const condition = ternary.getCondition().getText();\n      const whenTrue = ternary.getWhenTrue();\n      const whenFalse = ternary.getWhenFalse();\n\n      const trueYields = yield* analyzeExpressionForYields(whenTrue, ctx);\n      const falseYields = yield* analyzeExpressionForYields(whenFalse, ctx);\n\n      if (trueYields.length > 0 || falseYields.length > 0) {\n        const resolvedCond = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n        const decisionNode: StaticDecisionNode = {\n          id: generateId(),\n          type: 'decision',\n          decisionId: generateId(),\n          label: resolvedCond.length > 40 ? resolvedCond.slice(0, 40) + '...' : resolvedCond,\n          condition,\n          source: 'raw-ternary',\n          onTrue: trueYields.map((y) => y.effect),\n          onFalse: falseYields.length > 0 ? falseYields.map((y) => y.effect) : undefined,\n        };\n        ctx.stats.decisionCount++;\n        return [{ effect: decisionNode }];\n      }\n    }\n\n    // Binary expression: short-circuit (&&, ||, ??)\n    if (exprKind === SyntaxKind.BinaryExpression) {\n      const binary = unwrapped as BinaryExpression;\n      const operatorToken = binary.getOperatorToken().getKind();\n      const left = binary.getLeft();\n      const right = binary.getRight();\n\n      // && short-circuit: cond && (yield* A)\n      if (operatorToken === SyntaxKind.AmpersandAmpersandToken) {\n        const rightYields = yield* analyzeExpressionForYields(right, ctx);\n        if (rightYields.length > 0) {\n          const condition = left.getText();\n          const resolvedCond = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n          const decisionNode: StaticDecisionNode = {\n            id: generateId(),\n            type: 'decision',\n            decisionId: generateId(),\n            label: resolvedCond.length > 40 ? resolvedCond.slice(0, 40) + '...' : resolvedCond,\n            condition,\n            source: 'raw-short-circuit',\n            onTrue: rightYields.map((y) => y.effect),\n            onFalse: [],\n          };\n          ctx.stats.decisionCount++;\n          return [{ effect: decisionNode }];\n        }\n      }\n\n      // || short-circuit: cond || (yield* B)\n      if (operatorToken === SyntaxKind.BarBarToken) {\n        const rightYields = yield* analyzeExpressionForYields(right, ctx);\n        if (rightYields.length > 0) {\n          const condition = left.getText();\n          const resolvedCond = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n          const decisionNode: StaticDecisionNode = {\n            id: generateId(),\n            type: 'decision',\n            decisionId: generateId(),\n            label: resolvedCond.length > 40 ? resolvedCond.slice(0, 40) + '...' : resolvedCond,\n            condition,\n            source: 'raw-short-circuit',\n            onTrue: [],\n            onFalse: rightYields.map((y) => y.effect),\n          };\n          ctx.stats.decisionCount++;\n          return [{ effect: decisionNode }];\n        }\n      }\n\n      // ?? nullish coalescing: x ?? (yield* A)\n      if (operatorToken === SyntaxKind.QuestionQuestionToken) {\n        const rightYields = yield* analyzeExpressionForYields(right, ctx);\n        if (rightYields.length > 0) {\n          const condition = `${left.getText()} != null`;\n          const resolvedCond = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n          const decisionNode: StaticDecisionNode = {\n            id: generateId(),\n            type: 'decision',\n            decisionId: generateId(),\n            label: resolvedCond.length > 40 ? resolvedCond.slice(0, 40) + '...' : resolvedCond,\n            condition,\n            source: 'raw-short-circuit',\n            onTrue: [],\n            onFalse: rightYields.map((y) => y.effect),\n          };\n          ctx.stats.decisionCount++;\n          return [{ effect: decisionNode }];\n        }\n      }\n    }\n\n    // Fallback: collect all yield expressions in depth-first order\n    const yieldExprs = collectYieldExpressionsDF(expr);\n    const result: StaticGeneratorNode['yields'] = [];\n    for (const yieldExpr of yieldExprs) {\n      const entry = yield* analyzeYieldNode(yieldExpr, ctx);\n      result.push(entry);\n    }\n    return result;\n  });\n}\n\n// =============================================================================\n// Generator Function Analysis (rewritten with statement-level walker)\n// =============================================================================\n\nexport const analyzeGeneratorFunction = (\n  node: Node,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<readonly StaticFlowNode[], AnalysisError> =>\n  Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n\n    let body: Node | undefined;\n\n    if (\n      node.getKind() === SyntaxKind.ArrowFunction ||\n      node.getKind() === SyntaxKind.FunctionExpression\n    ) {\n      body = (\n        node as\n          | import('ts-morph').ArrowFunction\n          | import('ts-morph').FunctionExpression\n      ).getBody();\n    } else if (node.getKind() === SyntaxKind.FunctionDeclaration) {\n      body = (node as FunctionDeclaration).getBody();\n    }\n\n    if (!body) {\n      return [];\n    }\n\n    const serviceScope = new Map<string, string>();\n    const constValues = new Map<string, string>();\n    const generatorAdapterParams = new Set<string>();\n    if (\n      node.getKind() === SyntaxKind.ArrowFunction ||\n      node.getKind() === SyntaxKind.FunctionExpression ||\n      node.getKind() === SyntaxKind.FunctionDeclaration\n    ) {\n      const fnLike = node as ArrowFunction | FunctionExpression | FunctionDeclaration;\n      for (const param of fnLike.getParameters()) {\n        generatorAdapterParams.add(param.getName());\n      }\n    }\n    const ctx: WalkerContext = {\n      sourceFile,\n      filePath,\n      opts,\n      warnings,\n      stats,\n      serviceScope,\n      generatorAdapterParams,\n      constValues,\n    };\n\n    let yields: StaticGeneratorNode['yields'];\n\n    // If the body is a Block (the normal case), use the statement-level walker\n    if (body.getKind() === SyntaxKind.Block) {\n      yields = yield* analyzeGeneratorBody(body as Block, ctx);\n    } else {\n      // Expression body (arrow function): analyze the expression directly\n      const entries = yield* analyzeExpressionForYields(body, ctx);\n      yields = entries;\n    }\n\n    // Also scan for non-yielded Effect-like call expressions (same as before),\n    // but skip calls that live inside statements already handled by the\n    // statement-level yield walker. This avoids duplicating callback internals,\n    // resource constructors, and return-branch subexpressions as flat siblings.\n    if (body.getKind() === SyntaxKind.Block) {\n      for (const stmt of (body as Block).getStatements()) {\n        if (containsGeneratorYield(stmt)) continue;\n        const stmtKind = stmt.getKind();\n        if (\n          stmtKind !== SyntaxKind.ExpressionStatement &&\n          stmtKind !== SyntaxKind.VariableStatement\n        ) {\n          continue;\n        }\n        const calls = collectCallExpressionsBoundaryAware(stmt);\n        for (const call of calls) {\n          const callCallee = call.getExpression().getText();\n          if (callCallee.includes('withSpan')) continue;\n          const aliases = getAliasesForFile(sourceFile);\n          if (isEffectLikeCallExpression(call, sourceFile, aliases, opts.knownEffectInternalsRoot)) {\n            const analyzed = yield* analyzeEffectCall(\n              call,\n              sourceFile,\n              filePath,\n              opts,\n              warnings,\n              stats,\n              serviceScope,\n            );\n            yields.push({\n              effect: analyzed,\n            });\n          }\n        }\n      }\n    }\n\n    const generatorJSDoc = extractJSDocDescription(node);\n\n    const generatorNode: StaticGeneratorNode = {\n      id: generateId(),\n      type: 'generator',\n      yields,\n      jsdocDescription: generatorJSDoc,\n      jsdocTags: extractJSDocTags(node),\n    };\n    const enrichedGeneratorNode: StaticGeneratorNode = {\n      ...generatorNode,\n      displayName: computeDisplayName(generatorNode),\n      semanticRole: computeSemanticRole(generatorNode),\n    };\n\n    return [enrichedGeneratorNode];\n  });\n\n// =============================================================================\n// Outer `.pipe(...)` on a gen call — wrap the analyzed gen body in retry /\n// timeout / error-handler nodes when the gen call is the base of an outer pipe.\n// =============================================================================\n\n/**\n * If `genCall` is the base of an enclosing `.pipe(...)` (i.e. the expression\n * is `genCall.pipe(...)`), return that pipe CallExpression. Otherwise undefined.\n */\nfunction findOuterPipeOnGen(genCall: CallExpression): CallExpression | undefined {\n  const { SyntaxKind } = loadTsMorph();\n  const parent = genCall.getParent();\n  if (parent?.getKind() !== SyntaxKind.PropertyAccessExpression) return undefined;\n  const pa = parent as PropertyAccessExpression;\n  if (pa.getName() !== 'pipe') return undefined;\n  if (pa.getExpression() !== genCall) return undefined;\n  const grandparent = pa.getParent();\n  if (grandparent?.getKind() !== SyntaxKind.CallExpression) return undefined;\n  const call = grandparent as CallExpression;\n  if (call.getExpression() !== pa) return undefined;\n  return call;\n}\n\n/**\n * If `genCall` is the first argument to `Layer.unwrapEffect(...)`, return\n * that enclosing call so generator analysis can preserve explicit layer semantics.\n */\nfunction findOuterLayerUnwrapOnGen(genCall: CallExpression): CallExpression | undefined {\n  const { SyntaxKind } = loadTsMorph();\n  const parent = genCall.getParent();\n  if (parent?.getKind() !== SyntaxKind.CallExpression) return undefined;\n  const outer = parent as CallExpression;\n  if ((outer.getArguments()[0] ?? undefined) !== genCall) return undefined;\n  const callee = outer.getExpression().getText();\n  if (callee === 'Layer.unwrapEffect') return outer;\n  return undefined;\n}\n\n/**\n * Apply each transformation of an outer `.pipe(...)` call to the accumulated\n * child nodes from a gen body. Known Effect-level wrappers (retry, timeout,\n * catch, catchTag, orElse*, mapError, tap, tapError, ensuring, withSpan)\n * produce corresponding IR nodes and bump the relevant stats.\n *\n * This is a targeted implementation that covers the transformations people\n * most commonly attach to a gen program. Unrecognized transforms are analyzed\n * individually and appended so nothing is silently dropped.\n */\nconst applyOuterPipeTransformsToGen = (\n  genChildren: readonly StaticFlowNode[],\n  pipeCall: CallExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<readonly StaticFlowNode[], AnalysisError> =>\n  Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n    const transformArgs = pipeCall.getArguments();\n\n    // Build a synthetic \"generator\" wrapper so transforms have a coherent source.\n    const wrapChildren = (\n      children: readonly StaticFlowNode[],\n    ): StaticFlowNode => {\n      if (children.length === 1 && children[0]) return children[0];\n      const gen: StaticGeneratorNode = {\n        id: generateId(),\n        type: 'generator',\n        yields: children.map((c) => ({ effect: c })),\n      };\n      return {\n        ...gen,\n        displayName: computeDisplayName(gen),\n        semanticRole: computeSemanticRole(gen),\n      };\n    };\n\n    let current: readonly StaticFlowNode[] = genChildren;\n\n    for (const arg of transformArgs) {\n      if (arg.getKind() !== SyntaxKind.CallExpression) continue;\n      const argCall = arg as CallExpression;\n      const argExpr = argCall.getExpression();\n      const argExprText = argExpr.getText();\n      const text = arg.getText().trim();\n      const argArgs = argCall.getArguments();\n      const location = extractLocation(\n        argCall,\n        filePath,\n        opts.includeLocations ?? false,\n      );\n\n      // Effect.retry(schedule)\n      if (/^Effect\\.retry\\s*\\(/.test(text)) {\n        const source = wrapChildren(current);\n        const scheduleArg = argArgs[0];\n        const schedule = scheduleArg?.getText();\n        const scheduleNode = scheduleArg\n          ? yield* analyzeEffectExpression(\n              scheduleArg,\n              sourceFile,\n              filePath,\n              opts,\n              warnings,\n              stats,\n            )\n          : undefined;\n        stats.retryCount++;\n        const retryNode: StaticRetryNode = {\n          id: generateId(),\n          type: 'retry',\n          source,\n          ...(schedule ? { schedule } : {}),\n          ...(scheduleNode ? { scheduleNode } : {}),\n          hasFallback: false,\n          retryEdgeLabel: schedule ? `retry: ${schedule}` : 'retry',\n          location,\n        };\n        current = [\n          {\n            ...retryNode,\n            displayName: computeDisplayName(retryNode),\n            semanticRole: computeSemanticRole(retryNode),\n          },\n        ];\n        continue;\n      }\n\n      // Fallback: analyze the arg as an ordinary effect expression so it\n      // appears in the IR and stats (e.g., Effect.timeout, Effect.catch,\n      // Effect.withSpan). We append rather than wrap — the structural\n      // semantics of each wrapper is specialized above only where needed.\n      const analyzed = yield* analyzeEffectCall(\n        argCall,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n      // Suppress purely annotative transforms (withSpan) from visible output\n      if (\n        argExprText === 'Effect.withSpan' ||\n        argExprText.endsWith('.withSpan')\n      ) {\n        continue;\n      }\n      current = [...current, analyzed];\n    }\n\n    return current;\n  });\n\nexport function analyzeRunEntrypointExpression(\n  call: CallExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<Option.Option<readonly StaticFlowNode[]>, AnalysisError> {\n  const calleeExpr = call.getExpression();\n  const calleeText = calleeExpr.getText();\n  const isPipeCall = calleeText.endsWith('.pipe') || calleeText === 'pipe';\n  if (!isPipeCall) return Effect.succeed(Option.none());\n  const args = call.getArguments();\n  const lastArg = args[args.length - 1];\n  if (!lastArg) return Effect.succeed(Option.none());\n  const lastArgText = lastArg.getText();\n  const isRunTerminated =\n    lastArgText.includes('.runMain') ||\n    lastArgText.includes('.runPromise') ||\n    lastArgText.includes('.runSync') ||\n    lastArgText.includes('.runFork');\n  if (!isRunTerminated) return Effect.succeed(Option.none());\n  return Effect.map(\n    analyzePipeChain(call, sourceFile, filePath, opts, warnings, stats),\n    (nodes) => Option.some(nodes),\n  );\n}\n","/**\n * Effect expression analysis: pipe chains, effect calls, and domain-specific analyzers.\n */\n\nimport { Effect, Option } from 'effect';\nimport type {\n  SourceFile,\n  Node,\n  CallExpression,\n  ArrowFunction,\n  FunctionExpression,\n  Block,\n  ReturnStatement,\n  ObjectLiteralExpression,\n  PropertyAssignment,\n  PropertyAccessExpression,\n  ExpressionStatement,\n  Identifier,\n  ArrayLiteralExpression,\n  TaggedTemplateExpression,\n  NewExpression,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type { AnalysisError, AnalyzerOptions, AnalysisWarning, AnalysisStats } from './types';\nimport type {\n  StaticFlowNode,\n  StaticEffectNode,\n  StaticPipeNode,\n  StaticErrorHandlerNode,\n  StaticLayerNode,\n  StaticStreamNode,\n  StaticFiberNode,\n  StaticUnknownNode,\n  LayerLifecycle,\n  EffectTypeSignature,\n} from './types';\nimport { getStaticChildren } from './types';\nimport {\n  extractEffectTypeSignature,\n  extractServiceRequirements,\n  extractLayerTypeSignature,\n} from './type-extractor';\nimport {\n  generateId,\n  extractLocation,\n  extractJSDocDescription,\n  extractJSDocTags,\n  computeDisplayName,\n  computeSemanticRole,\n  unwrapExpression,\n} from './analysis-utils';\nimport {\n  ERROR_HANDLER_PATTERNS,\n  CONDITIONAL_PATTERNS,\n  COLLECTION_PATTERNS,\n  FIBER_PATTERNS,\n  INTERRUPTION_PATTERNS,\n  isTransformCall,\n  isMatchCall,\n  isCauseCall,\n  isExitCall,\n  isScheduleCall,\n  getSemanticDescriptionWithAliases,\n  parseServiceIdsFromContextType,\n  BUILT_IN_TYPE_NAMES,\n  KNOWN_EFFECT_NAMESPACES,\n} from './analysis-patterns';\nimport {\n  getAliasesForFile,\n  isEffectCallee,\n  isEffectLikeCallExpression,\n  normalizeEffectCallee,\n} from './alias-resolution';\nimport {\n  buildCallbackSummaryNodes,\n  summarizeNamedCallbackHandlers,\n} from './callback-summary';\nimport { resolveIdentifierToLayerInitializer } from './layer-initializer-resolution';\nimport {\n  isEffectRuntimePrimitive,\n  isLikelyServiceStreamProperty,\n  tryResolveServicePropertyAccess,\n  classifyUseCallbackKind,\n} from './service-type-heuristics';\nimport {\n  bindAnalysisContext,\n  createAnalysisContext,\n} from './analysis-context';\nimport {\n  analyzeStreamCall as _analyzeStreamCall,\n  analyzeChannelCall as _analyzeChannelCall,\n  analyzeSinkCall as _analyzeSinkCall,\n} from './stream-channel-sink-analyzers';\nimport {\n  analyzeRetryCall as _analyzeRetryCall,\n  analyzeTimeoutCall as _analyzeTimeoutCall,\n  analyzeScheduleCall,\n} from './retry-timeout-analyzers';\nimport {\n  analyzeConcurrencyPrimitiveCall,\n  analyzeFiberCall as _analyzeFiberCall,\n  analyzeInterruptionCall as _analyzeInterruptionCall,\n} from './concurrency-fiber-analyzers';\nimport {\n  analyzeParallelCall as _analyzeParallelCall,\n  analyzeRaceCall as _analyzeRaceCall,\n} from './parallel-race-analyzers';\nimport { analyzeErrorHandlerCall as _analyzeErrorHandlerCall, classifyErrorHandlerName } from './error-handler-analyzer';\nimport { analyzeResourceCall as _analyzeResourceCall } from './resource-analyzer';\nimport {\n  analyzeConditionalCall as _analyzeConditionalCall,\n  analyzeLoopCall as _analyzeLoopCall,\n  analyzeMatchCall,\n  analyzeCauseCall as _analyzeCauseCall,\n  analyzeExitCall,\n  analyzeTransformCall as _analyzeTransformCall,\n} from './control-flow-analyzers';\n\n/**\n * Deferred reference to `analyzeEffectExpression` used by extracted analyzers\n * (stream/channel/sink) that need to recurse. The getter resolves at call time,\n * which is after the module's top-level evaluation, so the export is in scope.\n */\nconst analysisContext = createAnalysisContext(() => analyzeEffectExpression);\n\nconst analyzeStreamCall = bindAnalysisContext(analysisContext, _analyzeStreamCall);\nconst analyzeChannelCall = bindAnalysisContext(analysisContext, _analyzeChannelCall);\nconst analyzeSinkCall = bindAnalysisContext(analysisContext, _analyzeSinkCall);\nconst analyzeRetryCall = bindAnalysisContext(analysisContext, _analyzeRetryCall);\nconst analyzeTimeoutCall = bindAnalysisContext(analysisContext, _analyzeTimeoutCall);\nconst analyzeFiberCall = bindAnalysisContext(analysisContext, _analyzeFiberCall);\nconst analyzeInterruptionCall = bindAnalysisContext(analysisContext, _analyzeInterruptionCall);\nconst analyzeParallelCall = bindAnalysisContext(analysisContext, _analyzeParallelCall);\nconst analyzeRaceCall = bindAnalysisContext(analysisContext, _analyzeRaceCall);\nconst analyzeErrorHandlerCall = bindAnalysisContext(analysisContext, _analyzeErrorHandlerCall);\nconst analyzeResourceCall = bindAnalysisContext(analysisContext, _analyzeResourceCall);\nconst analyzeConditionalCall = bindAnalysisContext(analysisContext, _analyzeConditionalCall);\nconst analyzeLoopCall = bindAnalysisContext(analysisContext, _analyzeLoopCall);\nconst analyzeCauseCall = bindAnalysisContext(analysisContext, _analyzeCauseCall);\nconst analyzeTransformCall = bindAnalysisContext(analysisContext, _analyzeTransformCall);\n\n// Schema decode/encode operations are NOT collection operations.\nconst SCHEMA_OPS = [\n  'Schema.decode',\n  'Schema.decodeUnknown',\n  'Schema.encode',\n  'Schema.validate',\n  'Schema.decodeOption',\n  'Schema.decodeEither',\n  'Schema.encodeUnknown',\n  'Schema.decodeSync',\n  'Schema.encodeSync',\n  'Schema.decodeUnknownSync',\n  'Schema.decodeUnknownOption',\n  'Schema.decodeUnknownEither',\n  'Schema.decodePromise',\n  'Schema.encodePromise',\n  'Schema.decodeUnknownPromise',\n];\n\n\n/**\n * Heuristic: does this `.pipe(...)` call apply Effect-level operations?\n *\n * Used to route pipe calls whose base is not literally `Effect.*` but whose\n * transformations are (e.g. `service.doThing().pipe(Effect.retry(...))`).\n * Matches the textual prefix of each arg against the Effect module's common\n * combinators — cheap, no type-checker needed.\n */\nconst EFFECT_PIPE_OP_REGEX =\n  /^Effect\\.(retry|retryOrElse|retryN|timeout(?:Fail|FailCause|Option|To)?|catch\\w*|orElse|orElseSucceed|orElseFail|orElseFailWith|orDie|orDieWith|ignore|ignoreLogged|sandbox|unsandbox|flip|tap|tapBoth|tapDefect|tapError|tapErrorCause|tapErrorTag|mapError|mapBoth|withSpan|annotateLogs|annotateSpans|ensuring|ensuringWith|delay|repeat|repeatN|repeatOrElse|zip|zipLeft|zipRight|matchEffect|match)\\s*(?:\\(|$)/;\n\nconst pipeArgsIncludeEffectOp = (call: CallExpression): boolean => {\n  for (const arg of call.getArguments()) {\n    if (EFFECT_PIPE_OP_REGEX.test(arg.getText())) return true;\n  }\n  return false;\n};\n\n/**\n * `Effect.orDie` and `Effect.ignore` are unary, so a pipe passes them uncalled\n * and the call-based handler analyzer never sees them.\n */\nconst asErrorHandler = (\n  analyzed: StaticFlowNode,\n  arg: Node,\n  stats: AnalysisStats,\n): StaticFlowNode => {\n  if (analyzed.type !== 'effect') return analyzed;\n  if (arg.getKind() === loadTsMorph().SyntaxKind.CallExpression) return analyzed;\n  const text = arg.getText();\n  if (!ERROR_HANDLER_PATTERNS.some((pattern) => text.includes(pattern))) {\n    return analyzed;\n  }\n  const handlerType = classifyErrorHandlerName(text);\n  stats.errorHandlerCount++;\n  const node: StaticErrorHandlerNode = {\n    id: generateId(),\n    type: 'error-handler',\n    handlerType,\n    // Uncalled combinator: the effect it applies to is the pipe's own base,\n    // which `walkPropagation` already has in hand when it reaches this node.\n    source: { id: generateId(), type: 'effect', callee: text },\n    ...(analyzed.location ? { location: analyzed.location } : {}),\n  };\n  return {\n    ...node,\n    displayName: computeDisplayName(node),\n    semanticRole: computeSemanticRole(node),\n  };\n};\n\nexport const analyzePipeChain = (\n  node: CallExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>,\n): Effect.Effect<readonly StaticFlowNode[], AnalysisError> =>\n  Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n    const args = node.getArguments();\n    const expr = node.getExpression();\n    const isMethodPipe =\n      expr.getKind() === SyntaxKind.PropertyAccessExpression &&\n      (expr as PropertyAccessExpression).getName() === 'pipe';\n    const baseExpr = isMethodPipe\n      ? (expr as PropertyAccessExpression).getExpression()\n      : args[0];\n    const transformArgs = isMethodPipe ? args : args.slice(1);\n    if (!baseExpr) return [];\n\n    // GAP: pipe-chain when base is a variable — resolve to Layer initializer (same- or cross-file)\n    const baseNode = resolveIdentifierToLayerInitializer(baseExpr);\n    let baseSourceFile = baseNode.getSourceFile();\n    const basePath = baseSourceFile.getFilePath();\n    const project = sourceFile.getProject();\n    // Ensure the resolved file is in the project so alias resolution (e.g. L→Layer) works\n    if (!project.getSourceFile(basePath)) {\n      const added = project.addSourceFileAtPath(basePath);\n      if (added) baseSourceFile = added;\n    } else {\n      const inProject = project.getSourceFile(basePath);\n      if (inProject) baseSourceFile = inProject;\n    }\n    const initial = yield* analyzeEffectExpression(\n      baseNode,\n      baseSourceFile,\n      baseSourceFile.getFilePath(),\n      opts,\n      warnings,\n      stats,\n      serviceScope,\n    );\n\n    const transformations: StaticFlowNode[] = [];\n    for (const arg of transformArgs) {\n      if (arg) {\n        const analyzed = yield* analyzeEffectExpression(\n          arg,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n          serviceScope,\n        );\n        transformations.push(asErrorHandler(analyzed, arg, stats));\n      }\n    }\n\n    // Detect Effect.withSpan in transformations and merge as annotation\n    const sourceOrderedSpanNames: string[] = [];\n    let spanNameDynamic = false;\n    const filteredTransformations = transformations.filter((t) => {\n      if (t.type === 'effect' && t.callee.includes('withSpan')) {\n        return false; // Remove withSpan from transformations list\n      }\n      return true;\n    });\n\n    // Extract span name from the AST transform arguments\n    for (const arg of transformArgs) {\n      if (arg) {\n        const argText = arg.getText();\n        if (argText.includes('withSpan')) {\n          const match = /withSpan\\s*\\(\\s*[\"']([^\"']+)[\"']/.exec(argText);\n          if (match?.[1]) {\n            sourceOrderedSpanNames.push(match[1]);\n          } else {\n            spanNameDynamic = true;\n          }\n        }\n      }\n    }\n    const spanNames = [...sourceOrderedSpanNames].reverse();\n    const spanName = spanNames.at(-1);\n\n    // Extract type flow through pipe chain\n    let typeFlow: EffectTypeSignature[] | undefined;\n    yield* Effect.try(() => {\n      const typeChecker = sourceFile.getProject().getTypeChecker();\n      const flow: EffectTypeSignature[] = [];\n      // Extract initial type\n      const initialSig = extractEffectTypeSignature(baseExpr, typeChecker);\n      if (initialSig) flow.push(initialSig);\n      // Extract type at each transform step\n      for (const argNode of transformArgs) {\n        if (argNode) {\n          const sig = extractEffectTypeSignature(argNode, typeChecker);\n          if (sig) flow.push(sig);\n        }\n      }\n      if (flow.length > 0) typeFlow = flow;\n      // Type extraction can fail; leaving typeFlow unset is the fallback.\n    }).pipe(Effect.ignore);\n\n    // A pipe whose only transforms were annotations (Effect.withSpan) adds no\n    // step of its own. Emitting a \"Pipe (0 steps)\" node between every real call\n    // buries the flow; collapse to the base effect and carry the span across.\n    if (filteredTransformations.length === 0) {\n      // Chained annotation pipes stack: `x.pipe(withSpan('inner')).pipe(\n      // withSpan('outer'))` collapses twice onto the same base, so the names\n      // already on it are the inner ones. Concatenating keeps `spanNames`\n      // outermost-first, which is the order `indexIR` builds span paths in;\n      // overwriting would drop the inner span and lose the trace match.\n      const innerSpanNames =\n        initial.spanNames ?? (initial.spanName ? [initial.spanName] : []);\n      const mergedSpanNames = [...spanNames, ...innerSpanNames];\n      const innermost = mergedSpanNames.at(-1);\n      return [{\n        ...initial,\n        ...(innermost ? { spanName: innermost } : {}),\n        ...(mergedSpanNames.length > 0 ? { spanNames: mergedSpanNames } : {}),\n        ...(spanNameDynamic || initial.spanNameDynamic\n          ? { spanNameDynamic: true }\n          : {}),\n      }];\n    }\n\n    const pipeNode: StaticPipeNode = {\n      id: generateId(),\n      type: 'pipe',\n      initial,\n      transformations: filteredTransformations,\n      ...(typeFlow ? { typeFlow } : {}),\n      ...(spanName ? { spanName } : {}),\n      ...(spanNames.length > 0 ? { spanNames } : {}),\n      ...(spanNameDynamic ? { spanNameDynamic: true } : {}),\n    };\n    const enrichedPipeNode: StaticPipeNode = {\n      ...pipeNode,\n      displayName: computeDisplayName(pipeNode),\n      semanticRole: computeSemanticRole(pipeNode),\n    };\n\n    return [enrichedPipeNode];\n  });\n\n// =============================================================================\n// Effect Expression Analysis\n// =============================================================================\n\nexport const analyzeEffectExpression = (\n  node: Node,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>,\n): Effect.Effect<StaticFlowNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n\n    /**\n     * A type assertion is not a program. Look through `as`, `satisfies`, `!`,\n     * `<T>` and parentheses before deciding what this expression is, or the\n     * walker stops at the wrapper and reports an unknown node.\n     *\n     * Auditing Effect's own source found this was the analyzer's single\n     * largest resolution gap: 108 of the 141 nodes in the `Could not determine\n     * effect type` bucket were `AsExpression`.\n     */\n    node = unwrapExpression(node);\n\n    // Handle function wrappers that return an Effect (common in workflow APIs)\n    if (\n      node.getKind() === SyntaxKind.ArrowFunction ||\n      node.getKind() === SyntaxKind.FunctionExpression\n    ) {\n      const fnNode = node as ArrowFunction | FunctionExpression;\n      const body = fnNode.getBody();\n\n      if (!body) {\n        const unknownNode: StaticUnknownNode = {\n          id: generateId(),\n          type: 'unknown',\n          reason: 'Function has no body',\n          sourceCode: node.getText().slice(0, 100),\n          location: extractLocation(\n            node,\n            filePath,\n            opts.includeLocations ?? false,\n          ),\n        };\n        stats.unknownCount++;\n        return unknownNode;\n      }\n\n      if (body.getKind() === SyntaxKind.Block) {\n        const statements = (\n          body as Block\n        ).getStatements();\n        const returnStmt = statements.find(\n          (stmt) => stmt.getKind() === SyntaxKind.ReturnStatement,\n        ) as ReturnStatement | undefined;\n\n        const returnedExpr = returnStmt?.getExpression();\n        if (returnedExpr) {\n          return yield* analyzeEffectExpression(\n            returnedExpr,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n            serviceScope,\n          );\n        }\n      } else {\n        return yield* analyzeEffectExpression(\n          body,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n          serviceScope,\n        );\n      }\n\n      const opaqueNode = {\n        id: generateId(),\n        type: 'opaque' as const,\n        reason: 'Function body is a non-Effect callback',\n        sourceText: node.getText().slice(0, 100),\n        location: extractLocation(node, filePath, opts.includeLocations ?? false),\n      };\n      return opaqueNode;\n    }\n\n    // Handle call expressions\n    if (node.getKind() === SyntaxKind.CallExpression) {\n      return yield* analyzeEffectCall(\n        node as CallExpression,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n        serviceScope,\n      );\n    }\n\n    // Handle property access chains (Effect.succeed(...))\n    if (node.getKind() === SyntaxKind.PropertyAccessExpression) {\n      const text = node.getText();\n      // Fiber.roots / Fiber.getCurrentFiber — property access that yields an Effect (GAP 5)\n      if (text === 'Fiber.roots' || text === 'Fiber.getCurrentFiber') {\n        const operation: StaticFiberNode['operation'] =\n          text === 'Fiber.roots' ? 'roots' : 'getCurrentFiber';\n        return {\n          id: generateId(),\n          type: 'fiber',\n          operation,\n          isScoped: false,\n          isDaemon: false,\n          location: extractLocation(\n            node,\n            filePath,\n            opts.includeLocations ?? false,\n          ),\n        };\n      }\n      const objectText = (node as PropertyAccessExpression).getExpression().getText();\n      const propertyName = (node as PropertyAccessExpression).getName();\n      const serviceId = serviceScope?.get(objectText);\n      if (serviceId) {\n        const serviceEffectNode: StaticEffectNode = {\n          id: generateId(),\n          type: 'effect',\n          callee: text,\n          description: 'service-call',\n          requiredServices: [\n            {\n              serviceId,\n              serviceType: serviceId,\n              requiredAt: extractLocation(\n                node,\n                filePath,\n                opts.includeLocations ?? false,\n              ) ?? {\n                filePath,\n                line: 1,\n                column: 0,\n              },\n            },\n          ],\n          serviceCall: {\n            serviceType: serviceId,\n            methodName: propertyName,\n            objectName: objectText,\n          },\n          location: extractLocation(\n            node,\n            filePath,\n            opts.includeLocations ?? false,\n          ),\n        };\n        stats.totalEffects++;\n        if (isLikelyServiceStreamProperty(propertyName)) {\n          const streamNode: StaticStreamNode = {\n            id: generateId(),\n            type: 'stream',\n            source: {\n              ...serviceEffectNode,\n              displayName: computeDisplayName(serviceEffectNode),\n              semanticRole: computeSemanticRole(serviceEffectNode),\n            },\n            pipeline: [],\n            constructorType: 'other',\n            location: extractLocation(\n              node,\n              filePath,\n              opts.includeLocations ?? false,\n            ),\n          };\n          return {\n            ...streamNode,\n            displayName: computeDisplayName(streamNode),\n            semanticRole: computeSemanticRole(streamNode),\n          };\n        }\n        return {\n          ...serviceEffectNode,\n          displayName: computeDisplayName(serviceEffectNode),\n          semanticRole: computeSemanticRole(serviceEffectNode),\n        };\n      }\n\n      const inferredServiceCall = tryResolveServicePropertyAccess(\n        node as PropertyAccessExpression,\n      );\n      if (inferredServiceCall) {\n        const serviceEffectNode: StaticEffectNode = {\n          id: generateId(),\n          type: 'effect',\n          callee: text,\n          description: 'service-call',\n          requiredServices: [\n            {\n              serviceId: inferredServiceCall.serviceType,\n              serviceType: inferredServiceCall.serviceType,\n              requiredAt: extractLocation(\n                node,\n                filePath,\n                opts.includeLocations ?? false,\n              ) ?? {\n                filePath,\n                line: 1,\n                column: 0,\n              },\n            },\n          ],\n          serviceCall: inferredServiceCall,\n          serviceMethod: {\n            serviceId: inferredServiceCall.serviceType,\n            methodName: inferredServiceCall.methodName,\n          },\n          location: extractLocation(\n            node,\n            filePath,\n            opts.includeLocations ?? false,\n          ),\n        };\n        stats.totalEffects++;\n        if (isLikelyServiceStreamProperty(propertyName)) {\n          const streamNode: StaticStreamNode = {\n            id: generateId(),\n            type: 'stream',\n            source: {\n              ...serviceEffectNode,\n              displayName: computeDisplayName(serviceEffectNode),\n              semanticRole: computeSemanticRole(serviceEffectNode),\n            },\n            pipeline: [],\n            constructorType: 'other',\n            location: extractLocation(\n              node,\n              filePath,\n              opts.includeLocations ?? false,\n            ),\n          };\n          return {\n            ...streamNode,\n            displayName: computeDisplayName(streamNode),\n            semanticRole: computeSemanticRole(streamNode),\n          };\n        }\n        return {\n          ...serviceEffectNode,\n          displayName: computeDisplayName(serviceEffectNode),\n          semanticRole: computeSemanticRole(serviceEffectNode),\n        };\n      }\n\n      if (isEffectCallee(text, getAliasesForFile(sourceFile), sourceFile)) {\n        const effectNode: StaticEffectNode = {\n          id: generateId(),\n          type: 'effect',\n          callee: normalizeEffectCallee(text, sourceFile),\n          location: extractLocation(\n            node,\n            filePath,\n            opts.includeLocations ?? false,\n          ),\n        };\n        stats.totalEffects++;\n        return effectNode;\n      }\n    }\n\n    // Handle identifier references\n    if (node.getKind() === SyntaxKind.Identifier) {\n      const effectNode: StaticEffectNode = {\n        id: generateId(),\n        type: 'effect',\n        callee: node.getText(),\n        location: extractLocation(\n          node,\n          filePath,\n          opts.includeLocations ?? false,\n        ),\n      };\n      stats.totalEffects++;\n      return effectNode;\n    }\n\n    // Handle object literal with known Effect handler properties (match-style APIs)\n    if (node.getKind() === SyntaxKind.ObjectLiteralExpression) {\n      const objLit = node as ObjectLiteralExpression;\n      const HANDLER_PROPS = new Set(['onNone', 'onSome', 'onFailure', 'onSuccess', 'onLeft', 'onRight']);\n      const props = objLit.getProperties();\n      const handlerEntries: StaticFlowNode[] = [];\n      let hasKnownHandler = false;\n\n      for (const prop of props) {\n        if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n        const assignment = prop as PropertyAssignment;\n        const propName = assignment.getName();\n        if (!HANDLER_PROPS.has(propName)) continue;\n        hasKnownHandler = true;\n        const initializer = assignment.getInitializer();\n        if (initializer) {\n          const analyzed = yield* analyzeEffectExpression(\n            initializer,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n            serviceScope,\n          );\n          handlerEntries.push(analyzed);\n        }\n      }\n\n      if (hasKnownHandler && handlerEntries.length > 0) {\n        return handlerEntries.length === 1 ? handlerEntries[0]! : {\n          id: generateId(),\n          type: 'parallel',\n          callee: 'match-handlers',\n          mode: 'sequential' as const,\n          children: handlerEntries,\n          location: extractLocation(node, filePath, opts.includeLocations ?? false),\n        };\n      }\n    }\n\n    // Handle tagged template expressions (e.g. sql`CREATE TABLE...`)\n    // These are commonly used in Effect SQL clients and return Effects\n    if (node.getKind() === SyntaxKind.TaggedTemplateExpression) {\n      const taggedTemplate = node as TaggedTemplateExpression;\n      const tagText = taggedTemplate.getTag().getText();\n      const effectNode: StaticEffectNode = {\n        id: generateId(),\n        type: 'effect',\n        callee: tagText,\n        description: 'side-effect',\n        location: extractLocation(node, filePath, opts.includeLocations ?? false),\n      };\n      stats.totalEffects++;\n      return {\n        ...effectNode,\n        displayName: computeDisplayName(effectNode),\n        semanticRole: 'side-effect' as const,\n      };\n    }\n\n    // Handle yielded error instances: `yield* new SomeTaggedError(...)`\n    // Common in Effect codebases where TaggedError is yieldable.\n    if (node.getKind() === SyntaxKind.NewExpression) {\n      const newExpr = node as NewExpression;\n      const ctorText = newExpr.getExpression().getText();\n      const ctorName = ctorText.split('.').pop() ?? ctorText;\n      const typeText = newExpr.getType().getText();\n      const isErrorLike =\n        ctorName.endsWith(\"Error\") ||\n        typeText.includes('YieldableError') ||\n        typeText.includes('TaggedError');\n      if (isErrorLike) {\n        const effectNode: StaticEffectNode = {\n          id: generateId(),\n          type: 'effect',\n          callee: 'Effect.fail',\n          errorType: ctorName,\n          description: 'error-handling',\n          location: extractLocation(node, filePath, opts.includeLocations ?? false),\n        };\n        stats.totalEffects++;\n        return {\n          ...effectNode,\n          displayName: computeDisplayName(effectNode),\n          semanticRole: computeSemanticRole(effectNode),\n        };\n      }\n    }\n\n    // Default: unknown. Classify by node kind so the audit's \"unknown node\n    // reasons\" histogram is actionable instead of one opaque bucket. Most of\n    // these are non-Effect sub-expressions the walker reached in a position\n    // that isn't an Effect program (option objects, predicates, service impls).\n    const unknownReason = ((): string => {\n      switch (node.getKind()) {\n        case SyntaxKind.ObjectLiteralExpression:\n          return 'Non-Effect object literal (e.g. service impl or options argument)';\n        case SyntaxKind.BinaryExpression:\n        case SyntaxKind.PrefixUnaryExpression:\n          return 'Non-Effect predicate or boolean expression';\n        case SyntaxKind.NewExpression:\n          return 'Unrecognized constructor (not an error-like type)';\n        case SyntaxKind.PropertyAccessExpression:\n        case SyntaxKind.ElementAccessExpression:\n          return 'Unresolved property access (not tied back to an Effect)';\n        case SyntaxKind.Identifier:\n          return 'Unresolved identifier (not tied back to an Effect)';\n        case SyntaxKind.ConditionalExpression:\n          return 'Non-Effect conditional expression';\n        case SyntaxKind.ArrowFunction:\n        case SyntaxKind.FunctionExpression:\n          return 'Non-Effect function expression';\n        default:\n          return 'Could not determine effect type';\n      }\n    })();\n    const unknownNode: StaticUnknownNode = {\n      id: generateId(),\n      type: 'unknown',\n      reason: unknownReason,\n      sourceCode: node.getText().slice(0, 100),\n      location: extractLocation(node, filePath, opts.includeLocations ?? false),\n    };\n    stats.unknownCount++;\n    return unknownNode;\n  });\n\nexport const analyzeEffectCall = (\n  call: CallExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>,\n): Effect.Effect<StaticFlowNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n    // Source text keeps the line breaks of a wrapped member chain\n    // (`deps\\n  .fetchRate`), which surfaces in every label as `deps .fetchRate`.\n    const callee = call.getExpression().getText().replace(/\\s*\\n\\s*/g, '');\n    const normalizedCallee = normalizeEffectCallee(callee, sourceFile);\n    const calleeOperation =\n      (/([A-Za-z_$][\\w$]*)$/.exec(normalizedCallee))?.[1] ?? normalizedCallee;\n    const location = extractLocation(\n      call,\n      filePath,\n      opts.includeLocations ?? false,\n    );\n\n    // pipe(base, ...fns) or <base>.pipe(...fns) inside generator → analyze as pipe chain so transformations (e.g. RcRef.update) are classified\n    // For method-style .pipe(), route Effect-based pipes, plus any pipe whose\n    // transformations include explicit Effect.* operations (e.g. retry, timeout, catch)\n    // on a non-Effect-prefixed base like `serviceCall().pipe(Effect.retry(...))`.\n    const isEffectMethodPipe =\n      callee.endsWith('.pipe') &&\n      callee !== 'pipe' &&\n      (callee.startsWith('Effect.') || pipeArgsIncludeEffectOp(call));\n    if (\n      (callee === 'pipe' || isEffectMethodPipe) &&\n      call.getArguments().length >= 1\n    ) {\n      const nodes = yield* analyzePipeChain(\n        call,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n        serviceScope,\n      );\n      if (nodes.length > 0 && nodes[0]) return nodes[0];\n    }\n\n    const isMethodPipe =\n      call.getExpression().getKind() === SyntaxKind.PropertyAccessExpression &&\n      (call.getExpression() as PropertyAccessExpression).getName() === 'pipe';\n    if (isMethodPipe) {\n      const baseExpr = (call.getExpression() as PropertyAccessExpression).getExpression();\n      const baseCallText =\n        baseExpr.getKind() === SyntaxKind.CallExpression\n          ? (baseExpr as CallExpression).getExpression().getText()\n          : '';\n      if (/\\blayerProtocol[A-Za-z0-9_]*$/.test(baseCallText)) {\n        const nodes = yield* analyzePipeChain(\n          call,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n          serviceScope,\n        );\n        if (nodes.length > 0 && nodes[0]) return nodes[0];\n      }\n      const baseText = baseExpr.getText();\n      const baseCallOrExprText = baseCallText || baseText;\n      if (baseText.startsWith('Stream.') || baseCallOrExprText.startsWith('Stream.')) {\n        return yield* analyzeStreamCall(\n          call,\n          'Stream.pipe',\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n          serviceScope,\n        );\n      }\n    }\n\n    // Context.pick / Context.omit are pure operations (not Effects) but are useful\n    // to preserve context-shaping steps inside Effect.gen bodies.\n    if (\n      normalizedCallee === 'Context.pick' ||\n      normalizedCallee === 'Context.omit'\n    ) {\n      const effectNode: StaticEffectNode = {\n        id: generateId(),\n        type: 'effect',\n        callee: normalizedCallee,\n        description: 'context',\n        location,\n      };\n      stats.totalEffects++;\n      return {\n        ...effectNode,\n        displayName: computeDisplayName(effectNode),\n        semanticRole: computeSemanticRole(effectNode),\n      };\n    }\n\n    if (normalizedCallee.startsWith('Layer.')) {\n      return yield* analyzeLayerCall(\n        call,\n        normalizedCallee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    // Protocol client factories often return layers that are then composed via Layer.provide(...)\n    // e.g. RpcClient.layerProtocolHttp(...).pipe(Layer.provide([...])).\n    if (/\\blayerProtocol[A-Za-z0-9_]*$/.test(normalizedCallee)) {\n      const layerNode: StaticLayerNode = {\n        id: generateId(),\n        type: 'layer',\n        name: normalizedCallee,\n        operations: [],\n        isMerged: false,\n        location,\n      };\n      return {\n        ...layerNode,\n        displayName: computeDisplayName(layerNode),\n        semanticRole: computeSemanticRole(layerNode),\n      };\n    }\n\n    if (normalizedCallee.startsWith('Stream.')) {\n      return yield* analyzeStreamCall(\n        call,\n        normalizedCallee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n        serviceScope,\n      );\n    }\n\n    if (normalizedCallee.startsWith('Channel.')) {\n      return yield* analyzeChannelCall(\n        call,\n        normalizedCallee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (callee.startsWith('Sink.')) {\n      return yield* analyzeSinkCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    const isConcurrencyPrimitiveCallee =\n      callee.startsWith('Queue.') ||\n      callee.startsWith('PubSub.') ||\n      callee.startsWith('Deferred.') ||\n      callee.startsWith('Semaphore.') ||\n      callee.startsWith('Mailbox.') ||\n      callee.startsWith('SubscriptionRef.') ||\n      callee.startsWith('RateLimiter.') ||\n      callee.startsWith('PartitionedSemaphore.') ||\n      callee.startsWith('FiberHandle.') ||\n      callee.startsWith('FiberSet.') ||\n      callee.startsWith('FiberMap.') ||\n      callee.startsWith('Cache.') ||\n      callee.startsWith('ScopedCache.') ||\n      callee.startsWith('RcRef.') ||\n      callee.includes('.RcRef.') ||\n      callee.startsWith('RcMap.') ||\n      callee.includes('.RcMap.') ||\n      callee.startsWith('Reloadable.') ||\n      callee.includes('.Reloadable.') ||\n      callee.includes('makeLatch') ||\n      callee.includes('Latch.');\n    if (isConcurrencyPrimitiveCallee) {\n      return yield* analyzeConcurrencyPrimitiveCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (FIBER_PATTERNS.some((p) => callee.includes(p) || callee.startsWith(p))) {\n      return yield* analyzeFiberCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (INTERRUPTION_PATTERNS.some((p) => callee.includes(p))) {\n      return yield* analyzeInterruptionCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    // Handle different Effect patterns\n    if (callee.includes('.all') || callee === 'all') {\n      return yield* analyzeParallelCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n        serviceScope,\n      );\n    }\n\n    if (callee.includes('.race') || callee === 'race') {\n      return yield* analyzeRaceCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (ERROR_HANDLER_PATTERNS.some((pattern) => callee.includes(pattern))) {\n      return yield* analyzeErrorHandlerCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (callee.includes('.retry')) {\n      return yield* analyzeRetryCall(\n        call,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (callee.includes('.timeout')) {\n      return yield* analyzeTimeoutCall(\n        call,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    const resourceOps = new Set([\n      'acquireRelease',\n      'acquireUseRelease',\n      'ensuring',\n      'addFinalizer',\n      'onExit',\n      'onError',\n      'parallelFinalizers',\n      'sequentialFinalizers',\n      'finalizersMask',\n      'using',\n      'withEarlyRelease',\n    ]);\n    const resourceOpPrefixes = ['acquireRelease', 'acquireUseRelease'] as const;\n    const isResourceOp = (op: string) =>\n      resourceOps.has(op) || resourceOpPrefixes.some((p) => op.startsWith(p));\n    if (calleeOperation === 'pipe' && call.getExpression().getKind() === SyntaxKind.PropertyAccessExpression) {\n      const propAccess = call.getExpression() as PropertyAccessExpression;\n      const baseExpr = propAccess.getExpression();\n      if (baseExpr.getKind() === SyntaxKind.CallExpression) {\n        const baseCall = baseExpr as CallExpression;\n        const baseCallee = baseCall.getExpression().getText();\n        const baseOperation = (/([A-Za-z_$][\\w$]*)$/.exec(baseCallee))?.[1] ?? baseCallee;\n        if (isResourceOp(baseOperation)) {\n          return yield* analyzeResourceCall(\n            baseCall,\n            baseOperation,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n          );\n        }\n      }\n    }\n    if (isResourceOp(calleeOperation)) {\n      return yield* analyzeResourceCall(\n        call,\n        calleeOperation,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    // Match CONDITIONAL_PATTERNS against the final method name, not the full callee text\n    const conditionalOp = `.${calleeOperation}`;\n    if (CONDITIONAL_PATTERNS.some((pattern) => conditionalOp === pattern || callee.endsWith(pattern))) {\n      return yield* analyzeConditionalCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    const isSchemaOp = SCHEMA_OPS.some((op) => callee.startsWith(op) || normalizedCallee.startsWith(op));\n\n    // Match COLLECTION_PATTERNS against the final method name (calleeOperation), not\n    // the full callee text which can contain arbitrary source code from curried functions.\n    const collectionOp = `.${calleeOperation}`;\n    if (!isSchemaOp && COLLECTION_PATTERNS.some((pattern) => collectionOp === pattern || callee.endsWith(pattern))) {\n      return yield* analyzeLoopCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (isTransformCall(callee)) {\n      return yield* analyzeTransformCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (isMatchCall(callee)) {\n      return analyzeMatchCall(call, callee, filePath, opts);\n    }\n\n    if (isCauseCall(callee)) {\n      return yield* analyzeCauseCall(\n        call,\n        callee,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (isExitCall(callee)) {\n      return analyzeExitCall(call, callee, filePath, opts);\n    }\n\n    if (isScheduleCall(callee)) {\n      return yield* analyzeScheduleCall(call, callee, filePath, opts);\n    }\n\n    // Default effect node\n    stats.totalEffects++;\n\n    // Effect.sync/promise/async callback body (one level only)\n    let callbackBody: readonly StaticFlowNode[] | undefined;\n    let usePattern: StaticEffectNode['usePattern'];\n    const CONSTRUCTOR_CALLBACK_CALLEES = [\n      'Effect.sync',\n      'Effect.promise',\n      'Effect.callback',\n      'Effect.asyncEffect',\n      'Effect.callback',\n      'Effect.tryPromise',\n      'Effect.suspend',\n    ];\n    const isConstructorWithCallback =\n      CONSTRUCTOR_CALLBACK_CALLEES.some((c) => callee.includes(c)) &&\n      call.getArguments().length > 0 &&\n      call.getArguments()[0];\n    let asyncCallback: StaticEffectNode['asyncCallback'];\n    if (isConstructorWithCallback) {\n      const firstArg = call.getArguments()[0]!;\n      const { SyntaxKind } = loadTsMorph();\n      const isFn =\n        firstArg.getKind() === SyntaxKind.ArrowFunction ||\n        firstArg.getKind() === SyntaxKind.FunctionExpression;\n      if (isFn) {\n        const fn = firstArg as\n          | ArrowFunction\n          | FunctionExpression;\n        const body = fn.getBody();\n        const innerNodes: StaticFlowNode[] = [];\n        if (body) {\n          if (body.getKind() === SyntaxKind.Block) {\n            const block = body as Block;\n            for (const stmt of block.getStatements()) {\n              if (stmt.getKind() === SyntaxKind.ReturnStatement) {\n                const retExpr = (stmt as ReturnStatement).getExpression();\n                if (retExpr && isEffectCallee(retExpr.getText(), getAliasesForFile(sourceFile), sourceFile)) {\n                  const analyzed = yield* analyzeEffectExpression(\n                    retExpr,\n                    sourceFile,\n                    filePath,\n                    opts,\n                    warnings,\n                    stats,\n                    undefined,\n                  );\n                  innerNodes.push(analyzed);\n                }\n              } else if (stmt.getKind() === SyntaxKind.ExpressionStatement) {\n                const expr = (stmt as ExpressionStatement).getExpression();\n                if (\n                  expr.getKind() === SyntaxKind.CallExpression &&\n                  isEffectLikeCallExpression(expr as CallExpression, sourceFile, getAliasesForFile(sourceFile), opts.knownEffectInternalsRoot)\n                ) {\n                  const analyzed = yield* analyzeEffectExpression(\n                    expr,\n                    sourceFile,\n                    filePath,\n                    opts,\n                    warnings,\n                    stats,\n                    undefined,\n                  );\n                  innerNodes.push(analyzed);\n                }\n              }\n            }\n          } else {\n            if (isEffectCallee(body.getText(), getAliasesForFile(sourceFile), sourceFile)) {\n              const analyzed = yield* analyzeEffectExpression(\n                body,\n                sourceFile,\n                filePath,\n                opts,\n                warnings,\n                stats,\n                undefined,\n              );\n              innerNodes.push(analyzed);\n            }\n          }\n        }\n        if (innerNodes.length > 0) callbackBody = innerNodes;\n\n        // Effect.callback/asyncEffect: resume/canceller patterns (GAP async callback interop)\n        if (\n          callee.includes('Effect.callback') ||\n          callee.includes('Effect.asyncEffect') ||\n          callee.includes('Effect.callback')\n        ) {\n          const resumeParamName =\n            fn.getParameters()[0]?.getName?.() ?? 'resume';\n          let resumeCallCount = 0;\n          const visit = (node: Node) => {\n            if (node.getKind() === SyntaxKind.CallExpression) {\n              const callNode = node as CallExpression;\n              const expr = callNode.getExpression();\n              if (\n                expr.getKind() === SyntaxKind.Identifier &&\n                (expr as Identifier).getText() === resumeParamName\n              ) {\n                resumeCallCount++;\n              }\n            }\n            node.getChildren().forEach(visit);\n          };\n          if (body) visit(body);\n          let returnsCanceller = false;\n          if (body?.getKind() === SyntaxKind.Block) {\n            const block = body as Block;\n            for (const stmt of block.getStatements()) {\n              if (stmt.getKind() === SyntaxKind.ReturnStatement) {\n                const retExpr = (stmt as ReturnStatement).getExpression();\n                if (retExpr) {\n                  const k = retExpr.getKind();\n                  if (\n                    k === SyntaxKind.ArrowFunction ||\n                    k === SyntaxKind.FunctionExpression\n                  ) {\n                    returnsCanceller = true;\n                    break;\n                  }\n                }\n              }\n            }\n          } else if (\n            body &&\n            (body.getKind() === SyntaxKind.ArrowFunction ||\n              body.getKind() === SyntaxKind.FunctionExpression)\n          ) {\n            returnsCanceller = true;\n          }\n          asyncCallback = {\n            resumeParamName,\n            resumeCallCount,\n            returnsCanceller,\n          };\n\n          if (callee.includes('Effect.callback')) {\n            const handlerSummaries = yield* summarizeNamedCallbackHandlers(\n              fn,\n              sourceFile,\n              filePath,\n              opts,\n              warnings,\n              stats,\n              resumeParamName,\n            );\n            if (handlerSummaries && handlerSummaries.length > 0) {\n              callbackBody = handlerSummaries;\n            }\n          }\n        }\n      }\n    }\n\n    if (call.getExpression().getKind() === SyntaxKind.PropertyAccessExpression) {\n      const propAccess = call.getExpression() as PropertyAccessExpression;\n      if (propAccess.getName() === 'use') {\n        const callbackArg = call.getArguments().find(\n          (arg) =>\n            arg.getKind() === SyntaxKind.ArrowFunction ||\n            arg.getKind() === SyntaxKind.FunctionExpression,\n        );\n        if (callbackArg) {\n          const callbackFn = callbackArg as ArrowFunction | FunctionExpression;\n          const callbackNodes = buildCallbackSummaryNodes(\n            callbackFn,\n            filePath,\n            opts.includeLocations ?? false,\n          );\n          if (callbackNodes) {\n            callbackBody = [...(callbackBody ?? []), ...callbackNodes];\n          }\n          const wrapperExpr = propAccess.getExpression().getText();\n          usePattern = {\n            wrapperName: serviceScope?.get(wrapperExpr) ?? wrapperExpr,\n            callbackKind: classifyUseCallbackKind(callbackFn),\n          };\n        }\n      }\n    }\n\n    // Extract JSDoc from the call statement\n    const effectJSDoc = extractJSDocDescription(call);\n\n    // Extract type signature and service requirements\n    const typeChecker = sourceFile.getProject().getTypeChecker();\n    const typeSignature = extractEffectTypeSignature(call, typeChecker);\n    const requiredServices = extractServiceRequirements(call, typeChecker);\n\n    // Try to identify service method calls\n    const serviceCall = tryResolveServiceCall(call, sourceFile);\n\n    // Resolve serviceMethod from generator scope or requiredServices fallback\n    let serviceMethod: StaticEffectNode['serviceMethod'];\n    const expr = call.getExpression();\n    if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n      const propAccess = expr as PropertyAccessExpression;\n      const objectText = propAccess.getExpression().getText();\n      const methodName = propAccess.getName();\n      if (serviceScope) {\n        const serviceId = serviceScope.get(objectText);\n        if (serviceId) serviceMethod = { serviceId, methodName };\n      }\n      if (!serviceMethod && requiredServices?.length === 1 && requiredServices[0]) {\n        serviceMethod = { serviceId: requiredServices[0].serviceId, methodName };\n      }\n    }\n\n    // Effect.provide: infer provideKind from context arg (GAP 6: Runtime vs Layer/Context)\n    // Two forms: Effect.provide(effect, layer) → 2 args, layer is args[1]; pipe(effect, Effect.provide(layer)) → 1 arg, layer is args[0]\n    let provideKind: StaticEffectNode['provideKind'];\n    if (\n      callee === 'Effect.provide' ||\n      (callee.startsWith('Effect.') && callee.includes('.provide') && !callee.includes('provideService'))\n    ) {\n      const args = call.getArguments();\n      const contextArgText = (args.length >= 2 ? args[1] : args[0])?.getText() ?? '';\n      if (\n        /Runtime\\.|defaultRuntime|\\.runSync|\\.runPromise|\\.runFork|\\.runCallback/.test(contextArgText) ||\n        /^\\s*runtime\\s*$|^\\s*rt\\s*$/i.test(contextArgText.trim())\n      ) {\n        provideKind = 'runtime';\n      } else if (contextArgText.includes('Layer.')) {\n        provideKind = 'layer';\n      } else {\n        provideKind = 'context';\n      }\n    }\n\n    // Determine constructorKind\n    let constructorKind: StaticEffectNode['constructorKind'];\n    if (callee.endsWith('.sync') || callee.endsWith('.succeed') || callee.endsWith('.fail') || callee.endsWith('.try') || callee.endsWith('.suspend')) constructorKind = 'sync';\n    else if (callee.endsWith('.promise')) constructorKind = 'promise';\n    else if (callee.endsWith('.async') || callee.endsWith('.asyncEffect')) constructorKind = 'async';\n    else if (callee.endsWith('.callback')) constructorKind = 'callback';\n    else if (callee.endsWith('.never')) constructorKind = 'never';\n    else if (callee.endsWith('.void')) constructorKind = 'void';\n    else if (callee.endsWith('.fromNullable')) constructorKind = 'fromNullable';\n    else if (callee.endsWith('.fn')) constructorKind = 'fn';\n    else if (callee.endsWith('.fnUntraced')) constructorKind = 'fnUntraced';\n\n    // Extract FiberRef built-in name\n    let fiberRefName: string | undefined;\n    const KNOWN_FIBER_REFS = ['currentConcurrency', 'currentLogLevel', 'currentScheduler', 'currentTracerEnabled', 'currentLogSpan', 'currentLogAnnotations', 'currentContext', 'currentRequestBatching', 'currentMaxOpsBeforeYield', 'currentSupervisor', 'currentMetricLabels', 'interruptedCause', 'unhandledLogLevel'] as const;\n    for (const refName of KNOWN_FIBER_REFS) {\n      if (callee.includes(refName)) { fiberRefName = refName; break; }\n    }\n\n    // Extract Effect.fn traced name\n    let tracedName: string | undefined;\n    if (constructorKind === 'fn' || constructorKind === 'fnUntraced') {\n      const args = call.getArguments();\n      if (args.length > 0) {\n        const firstArg = args[0]!.getText();\n        const strMatch = /^[\"'`](.+?)[\"'`]$/.exec(firstArg);\n        if (strMatch) tracedName = strMatch[1];\n      }\n    }\n\n    if (\n      constructorKind === undefined &&\n      call.getExpression().getKind() === loadTsMorph().SyntaxKind.CallExpression\n    ) {\n      const innerCall = call.getExpression() as CallExpression;\n      const innerCallee = innerCall.getExpression().getText();\n      if (innerCallee.endsWith('.fn') || innerCallee.endsWith('.fnUntraced')) {\n        constructorKind = innerCallee.endsWith('.fnUntraced') ? 'fnUntraced' : 'fn';\n        const fnArgs = innerCall.getArguments();\n        if (fnArgs.length > 0) {\n          const firstArg = fnArgs[0]!.getText();\n          const strMatch = /^[\"'`](.+?)[\"'`]$/.exec(firstArg);\n          if (strMatch) tracedName = strMatch[1];\n        }\n      }\n    }\n\n    const filteredRequiredServices = requiredServices?.filter(\n      (service) => !isEffectRuntimePrimitive(service.serviceId),\n    );\n\n    const effectNode: StaticEffectNode = {\n      id: generateId(),\n      type: 'effect',\n      callee: normalizedCallee,\n      description: usePattern\n        ? `use-pattern (${usePattern.callbackKind})`\n        : serviceCall || serviceMethod\n          ? 'service-call'\n          : getSemanticDescriptionWithAliases(normalizedCallee, getAliasesForFile(sourceFile)),\n      location,\n      jsdocDescription: effectJSDoc,\n      jsdocTags: extractJSDocTags(call),\n      typeSignature,\n      requiredServices: filteredRequiredServices,\n      serviceCall,\n      serviceMethod,\n      ...(usePattern ? { usePattern } : {}),\n      callbackBody,\n      ...(asyncCallback ? { asyncCallback } : {}),\n      ...(provideKind ? { provideKind } : {}),\n      ...(constructorKind ? { constructorKind } : {}),\n      ...(fiberRefName ? { fiberRefName } : {}),\n      ...(tracedName ? { tracedName } : {}),\n    };\n    const enrichedEffectNode: StaticEffectNode = {\n      ...effectNode,\n      displayName: computeDisplayName(effectNode),\n      semanticRole: computeSemanticRole(effectNode),\n    };\n    return enrichedEffectNode;\n  });\n\n/**\n * Try to resolve a service method call from a CallExpression.\n * Returns metadata if the callee is `obj.method()` where `obj` has a\n * known, non-built-in type — indicating a yielded service method call.\n */\nconst tryResolveServiceCall = (\n  call: CallExpression,\n  sourceFile: SourceFile,\n): StaticEffectNode['serviceCall'] => {\n  const { SyntaxKind } = loadTsMorph();\n  const expr = call.getExpression();\n\n  // Must be a property access (obj.method form)\n  if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) return undefined;\n\n  const propAccess = expr as PropertyAccessExpression;\n  const objExpr = propAccess.getExpression();\n  const methodName = propAccess.getName();\n  const objectName = objExpr.getText();\n\n  // Skip if first segment is a known Effect/JS namespace (resolve aliases first)\n  const firstSegment = objectName.split('.')[0] ?? objectName;\n  if (KNOWN_EFFECT_NAMESPACES.has(firstSegment)) return undefined;\n  // Resolve aliases: e.g. \"M\" -> \"Match\", \"S\" -> \"Schema\"\n  const normalized = normalizeEffectCallee(objectName, sourceFile);\n  const normalizedFirstSegment = normalized.split('.')[0] ?? normalized;\n  if (KNOWN_EFFECT_NAMESPACES.has(normalizedFirstSegment)) return undefined;\n\n  try {\n    const type = objExpr.getType();\n    const symbol = type.getSymbol() ?? type.getAliasSymbol();\n    if (!symbol) return undefined;\n\n    const typeName = symbol.getName();\n    // Skip anonymous structural types, built-ins, and error sentinels\n    if (\n      !typeName ||\n      typeName === '__type' ||\n      typeName === 'unknown' ||\n      typeName === 'any' ||\n      BUILT_IN_TYPE_NAMES.has(typeName)\n    ) {\n      return undefined;\n    }\n\n    return { serviceType: typeName, methodName, objectName };\n  } catch {\n    return undefined;\n  }\n};\n\n// =============================================================================\n// Specific Pattern Analysis\n// =============================================================================\n\n\nconst analyzeLayerCall = (\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticLayerNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n    const operations: StaticFlowNode[] = [];\n    const { SyntaxKind } = loadTsMorph();\n\n    if (args.length > 0 && args[0]) {\n      const firstArg = args[0];\n      const isMergeAll =\n        callee.includes('mergeAll') &&\n        firstArg.getKind() === SyntaxKind.ArrayLiteralExpression;\n\n      if (isMergeAll) {\n        const elements = (\n          firstArg as ArrayLiteralExpression\n        ).getElements();\n        for (const elem of elements) {\n          const analyzed = yield* analyzeEffectExpression(\n            elem,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n          );\n          operations.push(analyzed);\n        }\n      } else {\n        for (const arg of args) {\n          if (!arg) continue;\n          const toAnalyze = resolveIdentifierToLayerInitializer(arg);\n          const argSourceFile = toAnalyze.getSourceFile();\n          const analyzed = yield* analyzeEffectExpression(\n            toAnalyze,\n            argSourceFile,\n            argSourceFile.getFilePath(),\n            opts,\n            warnings,\n            stats,\n          );\n          operations.push(analyzed);\n        }\n      }\n    }\n\n    const isMerged =\n      callee.includes('merge') || callee.includes('mergeAll');\n\n    let lifecycle: LayerLifecycle | undefined;\n    if (callee.includes('fresh')) lifecycle = 'fresh';\n    else if (callee.includes('memoize')) lifecycle = 'memoized';\n    else if (callee.includes('scoped')) lifecycle = 'scoped';\n    else lifecycle = 'default';\n\n    // Layer error-handling / utility ops — track as semantic description on the node\n    // These don't change the primitive provides/requires but are important to detect:\n    // catch, orDie, orElse, retry, tap, mapError, build, launch, toRuntime,\n    // passthrough, project, flatMap, flatten, annotateLogs, annotateSpans,\n    // setConfigProvider, setClock, setTracer, locally, withSpan\n\n    const provides: string[] = [];\n    // Helper: extract one or more tag names from an arg.\n    const extractTagNames = (node: Node): string[] => {\n      if (node.getKind() === SyntaxKind.ArrayLiteralExpression) {\n        const items = (node as ArrayLiteralExpression).getElements();\n        return items.flatMap((item) => extractTagNames(item));\n      }\n      if (node.getKind() === SyntaxKind.CallExpression) {\n        const callNode = node as CallExpression;\n        const callExpr = callNode.getExpression().getText();\n        if (callExpr.startsWith('Layer.') && callNode.getArguments().length > 0) {\n          const first = callNode.getArguments()[0];\n          if (first) return extractTagNames(first);\n        }\n      }\n      if (node.getKind() === SyntaxKind.Identifier) {\n        return [(node as Identifier).getText()];\n      }\n      if (node.getKind() === SyntaxKind.PropertyAccessExpression) {\n        // e.g. SomeService.Default → 'SomeService'\n        const pae = node as PropertyAccessExpression;\n        const obj = pae.getExpression();\n        if (obj.getKind() === SyntaxKind.Identifier) {\n          return [(obj as Identifier).getText()];\n        }\n        return [pae.getText().split('.')[0] ?? pae.getText()];\n      }\n      return [];\n    };\n\n    // Layer.succeed(Tag, value) / Layer.sync(Tag, fn) / Layer.effect(Tag, eff) / Layer.scoped(Tag, eff)\n    if (\n      (callee.includes('succeed') || callee.includes('sync') ||\n       callee.includes('effect') || callee.includes('scoped') ||\n       callee.includes('scopedDiscard') || callee.includes('effectDiscard')) &&\n      args.length > 0 && args[0]\n    ) {\n      provides.push(...extractTagNames(args[0]));\n    }\n    // Layer.provide / Layer.provideMerge — method call: outerLayer.pipe(Layer.provide(innerLayer))\n    // In this case, callee is Layer.provide or Layer.provideMerge\n    // The first arg is the layer being provided (i.e., the dependency)\n    const isProvideCall = callee.includes('provide') && !callee.includes('provideService');\n\n    const requiresSet = new Set<string>();\n    // If this is Layer.provide(dep) [1-arg curried], dep's tag is what we're injecting\n    if (isProvideCall && args.length >= 1 && args[0]) {\n      for (const depName of extractTagNames(args[0])) {\n        requiresSet.add(depName);\n      }\n    }\n    // If this is Layer.provide(base, dep) [2-arg], dep is injected into base\n    if (isProvideCall && args.length >= 2 && args[1]) {\n      for (const depName of extractTagNames(args[1])) {\n        requiresSet.add(depName);\n      }\n      // The provides of the composed layer come from base (args[0])\n      const baseArg = args[0];\n      if (baseArg) provides.push(...extractTagNames(baseArg));\n    }\n    // Layer.provideService(tag, value) — provides a service inline\n    if (callee.includes('provideService') && args.length > 0 && args[0]) {\n      provides.push(...extractTagNames(args[0]));\n    }\n    const collectRequires = (node: StaticFlowNode): void => {\n      if (node.type === 'effect') {\n        const eff = node;\n        for (const req of eff.requiredServices ?? []) {\n          requiresSet.add(req.serviceId);\n        }\n        const calleeText = eff.callee ?? '';\n        if (\n          /^[A-Z][A-Za-z0-9_]*(Service|Tag)$/.test(calleeText) ||\n          calleeText.endsWith('.Tag')\n        ) {\n          requiresSet.add(calleeText);\n        }\n      } else if (node.type === 'layer') {\n        const layer = node;\n        for (const r of layer.requires ?? []) {\n          requiresSet.add(r);\n        }\n      }\n      const children = Option.getOrElse(getStaticChildren(node), () => []);\n      children.forEach(collectRequires);\n    };\n    operations.forEach(collectRequires);\n\n    // Fallback: Layer type RIn extraction when requires is empty (GAP Layer requires)\n    if (requiresSet.size === 0) {\n      // Type extraction can fail; an empty requires set is the fallback.\n      yield* Effect.try(() => {\n        const layerSig = extractLayerTypeSignature(call);\n        if (layerSig?.requiredType && layerSig.requiredType !== 'never') {\n          const ids = parseServiceIdsFromContextType(layerSig.requiredType);\n          ids.forEach((id) => requiresSet.add(id));\n        }\n      }).pipe(Effect.ignore);\n    }\n\n    // Extract a semantic name for utility Layer ops\n    const layerOpName = callee.replace(/^Layer\\./, '').replace(/^[a-zA-Z]+\\./, '');\n    const UTILITY_LAYER_OPS = new Set([\n      'catch', 'catchCause', 'orDie', 'orElse', 'retry', 'tap',\n      'mapError', 'mapErrorCause', 'build', 'launch', 'toRuntime',\n      'passthrough', 'project', 'flatMap', 'flatten', 'annotateLogs',\n      'annotateSpans', 'setConfigProvider', 'setClock', 'setTracer',\n      'locally', 'withSpan', 'withLogger', 'withTracer', 'withClock',\n      'mock', 'suspend', 'unwrapEffect', 'unwrapScoped',\n    ]);\n    let layerName = UTILITY_LAYER_OPS.has(layerOpName) ? `Layer.${layerOpName}` : undefined;\n    if (layerOpName === 'unwrapEffect' && operations.some((op) => op.type === 'generator')) {\n      layerName = 'Layer.unwrapEffect(gen)';\n    }\n\n    // GAP Layer.MemoMap: dedicated memo-map analysis\n    const isMemoMap =\n      callee.includes('MemoMap') ||\n      operations.some(\n        (op) => op.type === 'layer' && (op).isMemoMap === true,\n      );\n\n    const layerNode: StaticLayerNode = {\n      id: generateId(),\n      type: 'layer',\n      name: layerName,\n      operations,\n      isMerged,\n      provides: provides.length > 0 ? provides : undefined,\n      requires: requiresSet.size > 0 ? Array.from(requiresSet).sort() : undefined,\n      lifecycle,\n      ...(isMemoMap ? { isMemoMap: true } : {}),\n      location: extractLocation(\n        call,\n        filePath,\n        opts.includeLocations ?? false,\n      ),\n    };\n    return {\n      ...layerNode,\n      displayName: computeDisplayName(layerNode),\n      semanticRole: computeSemanticRole(layerNode),\n    };\n  });\n","/**\n * Callback body summarisation helpers.\n *\n * The static analyzer captures `Effect.callback`/`Effect.gen`/loop callbacks as\n * IR nodes, but their bodies are arbitrary JS. These helpers walk a callback\n * body and produce a compact, deduplicated summary of the calls /\n * conditionals inside it — used to render meaningful labels in diagrams and\n * keep the IR small.\n *\n * Extracted from effect-analysis.ts as part of the strangler-fig cleanup.\n * Behaviour is preserved exactly; only the module boundary moved.\n */\n\nimport { Effect } from 'effect';\nimport type {\n  SourceFile,\n  Node,\n  CallExpression,\n  ArrowFunction,\n  FunctionExpression,\n  Block,\n  Identifier,\n  VariableStatement,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type { AnalysisError, AnalyzerOptions, AnalysisWarning, AnalysisStats } from './types';\nimport type {\n  StaticFlowNode,\n  StaticEffectNode,\n  StaticLoopNode,\n} from './types';\nimport {\n  generateId,\n  extractLocation,\n  computeDisplayName,\n  computeSemanticRole,\n} from './analysis-utils';\n\nconst compactCallbackCalleeLabel = (call: CallExpression): string => {\n  let expr: Node = call.getExpression();\n  const { SyntaxKind } = loadTsMorph();\n  while (expr.getKind() === SyntaxKind.CallExpression) {\n    expr = (expr as CallExpression).getExpression();\n  }\n  return expr.getText();\n};\n\nconst canonicalizeCallbackLabel = (label: string): string => {\n  const match = /^([A-Za-z_$][\\w$]*(?:\\.[A-Za-z_$][\\w$]*)*)\\(/.exec(label);\n  return match?.[1] ?? label;\n};\n\nconst CALLBACK_NOISE_LABELS = new Set([\n  'Effect.sync',\n  'Effect.succeed',\n  'Effect.fail',\n  'sync',\n  'succeed',\n  'fail',\n  'tap',\n  'recurs',\n  'map',\n  'flatMap',\n]);\n\nconst shouldSkipCallbackSummaryLabel = (\n  label: string,\n  availableLabels: readonly string[],\n): boolean => {\n  if (!CALLBACK_NOISE_LABELS.has(label)) return false;\n  return availableLabels.some((candidate) => candidate !== label);\n};\n\nexport const summarizeLoopCallbackSource = (\n  loopType: StaticLoopNode['loopType'],\n  callbackBody: readonly StaticFlowNode[],\n): string => {\n  const labels = callbackBody.flatMap((node) => {\n    if (node.type === 'effect') {\n      return [canonicalizeCallbackLabel(node.callee)];\n    }\n    if (node.type === 'conditional') {\n      return [`if ${node.conditionLabel ?? node.condition}`];\n    }\n    return [];\n  });\n  const filtered = labels.filter((label, index) => {\n    if (labels.indexOf(label) !== index) return false;\n    return !shouldSkipCallbackSummaryLabel(label, labels);\n  });\n  if (filtered.length === 0) return 'callback body';\n  const joined = filtered.slice(0, 4).join(' -> ');\n  const suffix = filtered.length > 4 ? ' -> ...' : '';\n  return `${loopType} callback: ${joined}${suffix}`;\n};\n\nexport const buildCallbackSummaryNodes = (\n  fnNode: ArrowFunction | FunctionExpression,\n  filePath: string,\n  includeLocations: boolean,\n): readonly StaticFlowNode[] | undefined => {\n  const { SyntaxKind } = loadTsMorph();\n  const body = fnNode.getBody();\n  const calls: StaticFlowNode[] = [];\n  const seen = new Set<string>();\n\n  const collectFrom = (candidate: Node): void => {\n    if (candidate.getKind() === SyntaxKind.CallExpression) {\n      const call = candidate as CallExpression;\n      const callee = canonicalizeCallbackLabel(compactCallbackCalleeLabel(call));\n      if (seen.has(callee)) return;\n      seen.add(callee);\n      const callbackNode: StaticEffectNode = {\n        id: generateId(),\n        type: 'effect',\n        callee,\n        description: 'callback-call',\n        location: extractLocation(candidate, filePath, includeLocations),\n      };\n      calls.push({\n        ...callbackNode,\n        displayName: computeDisplayName(callbackNode),\n        semanticRole: computeSemanticRole(callbackNode),\n      });\n    }\n  };\n\n  if (body.getKind() === SyntaxKind.Block) {\n    for (const stmt of (body as Block).getStatements()) {\n      stmt.forEachDescendant((desc) => {\n        collectFrom(desc);\n        return undefined;\n      });\n    }\n  } else {\n    body.forEachDescendant((desc) => {\n      collectFrom(desc);\n      return undefined;\n    });\n    collectFrom(body);\n  }\n\n  const labels = calls.flatMap((node) => node.type === 'effect' ? [node.callee] : []);\n  const filtered = calls.filter((node) => {\n    if (node.type !== 'effect') return true;\n    return !shouldSkipCallbackSummaryLabel(node.callee, labels);\n  });\n\n  return filtered.length > 0 ? filtered : undefined;\n};\n\nconst isFunctionBoundaryForCallbackSummary = (node: Node): boolean => {\n  const { SyntaxKind } = loadTsMorph();\n  const kind = node.getKind();\n  return (\n    kind === SyntaxKind.FunctionDeclaration ||\n    kind === SyntaxKind.FunctionExpression ||\n    kind === SyntaxKind.ArrowFunction ||\n    kind === SyntaxKind.MethodDeclaration\n  );\n};\n\nconst summarizeResumePayloads = (\n  fnNode: ArrowFunction | FunctionExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n  resumeParamName: string,\n): Effect.Effect<readonly StaticFlowNode[], AnalysisError> =>\n  Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n    const summaries: StaticFlowNode[] = [];\n    const seen = new Set<string>();\n    const body = fnNode.getBody();\n\n    const visit = (node: Node): void => {\n      if (node.getKind() === SyntaxKind.CallExpression) {\n        const call = node as CallExpression;\n        const expr = call.getExpression();\n        if (\n          expr.getKind() === SyntaxKind.Identifier &&\n          (expr as Identifier).getText() === resumeParamName\n        ) {\n          const payload = call.getArguments()[0];\n          if (payload) {\n            const payloadText = payload.getText();\n            const compactPayload =\n              payloadText.length > 48 ? `${payloadText.slice(0, 48)}...` : payloadText;\n            const key = compactPayload;\n            if (!seen.has(key)) {\n              seen.add(key);\n              summaries.push({\n                id: generateId(),\n                type: 'effect',\n                callee: `resume -> ${compactPayload}`,\n                description: 'callback-resume',\n                location: extractLocation(call, filePath, opts.includeLocations ?? false),\n              });\n            }\n          }\n        }\n      }\n      if (!isFunctionBoundaryForCallbackSummary(node)) {\n        node.forEachChild(visit);\n      }\n    };\n\n    if (body.getKind() === SyntaxKind.Block) {\n      for (const stmt of (body as Block).getStatements()) {\n        visit(stmt);\n      }\n    } else {\n      visit(body);\n    }\n\n    return summaries;\n  });\n\nconst filterHandlerSummaryNoise = (\n  nodes: readonly StaticFlowNode[],\n): readonly StaticFlowNode[] => {\n  const seenEffectLabels = new Set<string>();\n  return nodes.filter((node) => {\n    if (node.type !== 'effect') return true;\n    if (node.callee === 'resume') return false;\n    if (node.callee === 'fail') return false;\n    if (\n      node.callee === 'succeed' ||\n      node.callee === 'succeedSome' ||\n      node.callee === 'succeedNone' ||\n      node.callee === 'Effect.fail' ||\n      node.callee === 'Effect.succeed' ||\n      node.callee === 'Effect.succeedSome' ||\n      node.callee === 'Effect.succeedNone'\n    ) {\n      return false;\n    }\n    if (seenEffectLabels.has(node.callee)) return false;\n    seenEffectLabels.add(node.callee);\n    return true;\n  });\n};\n\nexport const summarizeNamedCallbackHandlers = (\n  fnNode: ArrowFunction | FunctionExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n  resumeParamName: string,\n): Effect.Effect<readonly StaticFlowNode[] | undefined, AnalysisError> =>\n  Effect.gen(function* () {\n    const { SyntaxKind } = loadTsMorph();\n    const body = fnNode.getBody();\n    if (body.getKind() !== SyntaxKind.Block) return undefined;\n\n    const summaries: StaticFlowNode[] = [];\n    const block = body as Block;\n    for (const stmt of block.getStatements()) {\n      if (stmt.getKind() === SyntaxKind.VariableStatement) {\n        for (const decl of (stmt as VariableStatement).getDeclarations()) {\n          const init = decl.getInitializer();\n          if (\n            init &&\n            (init.getKind() === SyntaxKind.ArrowFunction ||\n              init.getKind() === SyntaxKind.FunctionExpression)\n          ) {\n            const handlerFn = init as ArrowFunction | FunctionExpression;\n            const callbackBody = [\n              ...(yield* summarizeResumePayloads(\n                handlerFn,\n                sourceFile,\n                filePath,\n                opts,\n                warnings,\n                stats,\n                resumeParamName,\n              )),\n              ...filterHandlerSummaryNoise(\n                buildPureCallbackSummaryNodes(\n                  handlerFn,\n                  filePath,\n                  opts.includeLocations ?? false,\n                ) ?? [],\n              ),\n            ];\n            if (callbackBody.length > 0) {\n              const handlerNode: StaticEffectNode = {\n                id: generateId(),\n                type: 'effect',\n                callee: decl.getName(),\n                description: 'callback-handler',\n                callbackBody,\n                location: extractLocation(decl, filePath, opts.includeLocations ?? false),\n              };\n              summaries.push({\n                ...handlerNode,\n                displayName: computeDisplayName(handlerNode),\n                semanticRole: computeSemanticRole(handlerNode),\n              });\n            }\n          }\n        }\n      }\n    }\n\n    return summaries.length > 0 ? summaries : undefined;\n  });\n\nexport const buildPureCallbackSummaryNodes = (\n  fnNode: ArrowFunction | FunctionExpression,\n  filePath: string,\n  includeLocations: boolean,\n): readonly StaticFlowNode[] | undefined => {\n  const { SyntaxKind } = loadTsMorph();\n  const body = fnNode.getBody();\n  const summaries: StaticFlowNode[] = [];\n  const seen = new Set<string>();\n\n  const addEffectSummary = (label: string, description = 'callback-transform'): void => {\n    const canonicalLabel = canonicalizeCallbackLabel(label);\n    if (seen.has(canonicalLabel)) return;\n    seen.add(canonicalLabel);\n    const node: StaticEffectNode = {\n      id: generateId(),\n      type: 'effect',\n      callee: canonicalLabel,\n      description,\n      location: extractLocation(body, filePath, includeLocations),\n    };\n    summaries.push({\n      ...node,\n      displayName: computeDisplayName(node),\n      semanticRole: computeSemanticRole(node),\n    });\n  };\n\n  const addConditionalSummary = (condition: string): void => {\n    if (seen.has(`if:${condition}`)) return;\n    seen.add(`if:${condition}`);\n    summaries.push({\n      id: generateId(),\n      type: 'conditional',\n      conditionalType: 'if',\n      condition,\n      conditionLabel: condition,\n      onTrue: {\n        id: generateId(),\n        type: 'opaque',\n        reason: 'callback-branch',\n        sourceText: condition,\n        location: extractLocation(body, filePath, includeLocations),\n      },\n      location: extractLocation(body, filePath, includeLocations),\n    });\n  };\n\n  const visit = (candidate: Node): void => {\n    if (candidate.getKind() === SyntaxKind.CallExpression) {\n      const call = candidate as CallExpression;\n      addEffectSummary(call.getExpression().getText(), 'callback-call');\n    } else if (candidate.getKind() === SyntaxKind.BinaryExpression) {\n      const text = candidate.getText();\n      if (\n        text.includes('===') ||\n        text.includes('!==') ||\n        text.includes('>') ||\n        text.includes('<') ||\n        text.includes('%') ||\n        text.includes('&&') ||\n        text.includes('||')\n      ) {\n        addConditionalSummary(text);\n      }\n    } else if (\n      candidate.getKind() === SyntaxKind.Identifier ||\n      candidate.getKind() === SyntaxKind.NumericLiteral ||\n      candidate.getKind() === SyntaxKind.StringLiteral ||\n      candidate.getKind() === SyntaxKind.TrueKeyword ||\n      candidate.getKind() === SyntaxKind.FalseKeyword\n    ) {\n      return;\n    }\n    candidate.forEachChild(visit);\n  };\n\n  if (body.getKind() === SyntaxKind.Block) {\n    for (const stmt of (body as Block).getStatements()) {\n      visit(stmt);\n    }\n  } else {\n    visit(body);\n    if (summaries.length === 0) {\n      addEffectSummary(body.getText(), 'callback-transform');\n    }\n  }\n\n  return summaries.length > 0 ? summaries : undefined;\n};\n","/**\n * Resolve identifiers to their underlying Layer/Effect initializer call.\n *\n * When a pipe chain starts with a variable (e.g. `myLayer.pipe(Layer.provide(...))`)\n * we follow the variable's declaration — including cross-file imports and\n * default imports — back to the original `Layer.*` or `Effect.*` call so the\n * analyzer can classify what's actually being piped.\n *\n * Extracted from effect-analysis.ts as part of the strangler-fig cleanup.\n * Behaviour is preserved exactly.\n */\n\nimport type {\n  CallExpression,\n  Node,\n  Identifier,\n  ImportSpecifier,\n  VariableDeclaration,\n  VariableStatement,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport {\n  normalizeEffectCallee,\n  resolveBarrelSourceFile,\n  resolveModulePath,\n} from './alias-resolution';\n\n/** Return true if the call expression text (e.g. \"Layer.succeed\" or \"L.succeed\") is a Layer or Effect initializer. */\nexport function isLayerOrEffectInitializerCallee(initCall: CallExpression): boolean {\n  const initText = initCall.getExpression().getText();\n  const srcFile = initCall.getSourceFile();\n  const normalized = normalizeEffectCallee(initText, srcFile);\n  return (\n    normalized.startsWith('Layer.') ||\n    normalized.startsWith('Effect.') ||\n    initText === 'pipe' ||\n    initText.endsWith('.pipe')\n  );\n}\n\n/**\n * Resolve a Layer initializer from a cross-file import by resolving the target module\n * and looking up the exported declaration. Used when symbol alias resolution doesn't\n * yield a VariableDeclaration (e.g. project created without tsconfig).\n */\nfunction resolveLayerInitializerFromImport(\n  ident: Identifier,\n  importSpec: ImportSpecifier,\n  isLayerInit: (call: CallExpression) => boolean,\n): CallExpression | undefined {\n  const { SyntaxKind } = loadTsMorph();\n  const sourceFile = ident.getSourceFile();\n  const project = sourceFile.getProject();\n  const currentPath = sourceFile.getFilePath();\n  const importDecl = importSpec.getImportDeclaration();\n  const specifier = importDecl.getModuleSpecifierValue();\n  if (!specifier?.startsWith('.')) return undefined;\n  let targetFile = resolveBarrelSourceFile(project, currentPath, specifier);\n  if (!targetFile) {\n    const resolvedPath = resolveModulePath(currentPath, specifier);\n    if (resolvedPath) {\n      const added = project.addSourceFileAtPath(resolvedPath);\n      if (added) targetFile = added;\n    }\n  }\n  if (!targetFile) return undefined;\n  // Ensure we use the project's instance so alias resolution sees the same file\n  targetFile = project.getSourceFile(targetFile.getFilePath()) ?? targetFile;\n  const tryDecl = (d: Node): CallExpression | undefined => {\n    if (d.getKind() === SyntaxKind.VariableDeclaration) {\n      const v = d as VariableDeclaration;\n      const init = v.getInitializer();\n      if (init?.getKind() === SyntaxKind.CallExpression && isLayerInit(init as CallExpression)) {\n        return init as CallExpression;\n      }\n    }\n    if (d.getKind() === SyntaxKind.VariableStatement) {\n      const list = (d as VariableStatement).getDeclarationList();\n      for (const v of list.getDeclarations()) {\n        const init = v.getInitializer();\n        if (init?.getKind() === SyntaxKind.CallExpression && isLayerInit(init as CallExpression)) {\n          return init as CallExpression;\n        }\n      }\n    }\n    return undefined;\n  };\n  const exportName = importSpec.getName();\n  const exported = targetFile.getExportedDeclarations();\n  const decls = exported.get(exportName) ?? [];\n  for (const d of decls) {\n    const init = tryDecl(d);\n    if (init) return init;\n  }\n  const targetName = (importSpec as { getTargetName?: () => string }).getTargetName?.();\n  if (targetName && targetName !== exportName) {\n    for (const d of exported.get(targetName) ?? []) {\n      const init = tryDecl(d);\n      if (init) return init;\n    }\n  }\n  // Fallback: scan all exports (key may differ from import name in some ts-morph versions)\n  for (const [, declList] of exported) {\n    for (const d of declList) {\n      const init = tryDecl(d);\n      if (init) return init;\n    }\n  }\n  return undefined;\n}\n\nfunction resolveLayerInitializerFromDefaultImport(\n  ident: Identifier,\n  importDecl: { getModuleSpecifierValue: () => string },\n  isLayerInit: (call: CallExpression) => boolean,\n): CallExpression | undefined {\n  const { SyntaxKind } = loadTsMorph();\n  const sourceFile = ident.getSourceFile();\n  const project = sourceFile.getProject();\n  const currentPath = sourceFile.getFilePath();\n  const specifier = importDecl.getModuleSpecifierValue();\n  if (!specifier?.startsWith('.')) return undefined;\n  let targetFile = resolveBarrelSourceFile(project, currentPath, specifier);\n  if (!targetFile) {\n    const resolvedPath = resolveModulePath(currentPath, specifier);\n    if (resolvedPath) {\n      const added = project.addSourceFileAtPath(resolvedPath);\n      if (added) targetFile = added;\n    }\n  }\n  if (!targetFile) return undefined;\n  targetFile = project.getSourceFile(targetFile.getFilePath()) ?? targetFile;\n  const tryDecl = (d: Node): CallExpression | undefined => {\n    if (d.getKind() === SyntaxKind.VariableDeclaration) {\n      const v = d as VariableDeclaration;\n      const init = v.getInitializer();\n      if (init?.getKind() === SyntaxKind.CallExpression && isLayerInit(init as CallExpression)) {\n        return init as CallExpression;\n      }\n    }\n    if (d.getKind() === SyntaxKind.VariableStatement) {\n      const list = (d as VariableStatement).getDeclarationList();\n      for (const v of list.getDeclarations()) {\n        const init = v.getInitializer();\n        if (init?.getKind() === SyntaxKind.CallExpression && isLayerInit(init as CallExpression)) {\n          return init as CallExpression;\n        }\n      }\n    }\n    return undefined;\n  };\n  for (const d of targetFile.getDefaultExportSymbol()?.getDeclarations() ?? []) {\n    const init = tryDecl(d);\n    if (init) return init;\n  }\n  for (const d of targetFile.getExportedDeclarations().get('default') ?? []) {\n    const init = tryDecl(d);\n    if (init) return init;\n  }\n  return undefined;\n}\n\n/** If node is an Identifier bound to a variable whose initializer is a Layer.* call, return that initializer; else return node. (GAP: pipe-chain base variable + cross-file.) */\nexport function resolveIdentifierToLayerInitializer(node: Node): Node {\n  const { SyntaxKind } = loadTsMorph();\n  if (node.getKind() !== SyntaxKind.Identifier) return node;\n  const ident = node as Identifier;\n  const name = ident.getText();\n  let sym = ident.getSymbol();\n  let decl = sym?.getValueDeclaration();\n  let importSpec: ImportSpecifier | undefined =\n    decl?.getKind() === SyntaxKind.ImportSpecifier ? (decl as ImportSpecifier) : undefined;\n  if (!importSpec && sym) {\n    const fromDecls = sym.getDeclarations().find((d) => d.getKind() === SyntaxKind.ImportSpecifier);\n    if (fromDecls) importSpec = fromDecls as ImportSpecifier;\n  }\n  if (!importSpec) {\n    const sf = ident.getSourceFile();\n    for (const id of sf.getImportDeclarations()) {\n      const defaultImport = id.getDefaultImport()?.getText();\n      if (defaultImport === name) {\n        const fromDefault = resolveLayerInitializerFromDefaultImport(\n          ident,\n          id,\n          isLayerOrEffectInitializerCallee,\n        );\n        if (fromDefault) return fromDefault;\n      }\n      const spec = id\n        .getNamedImports()\n        .find((n) => n.getName() === name || n.getAliasNode()?.getText() === name);\n      if (spec) {\n        importSpec = spec;\n        break;\n      }\n    }\n  }\n  // Cross-file: when the binding is an import, resolve via the target module first so we get\n  // a node in the target file (alias resolution for L->Layer needs that file's SourceFile).\n  if (importSpec) {\n    const fromImport = resolveLayerInitializerFromImport(\n      ident,\n      importSpec,\n      isLayerOrEffectInitializerCallee,\n    );\n    if (fromImport) return fromImport;\n    sym = sym?.getImmediatelyAliasedSymbol() ?? sym?.getAliasedSymbol();\n    decl = sym?.getValueDeclaration();\n  }\n  // Also follow alias if valueDeclaration is an export specifier (re-export)\n  if (decl?.getKind() === SyntaxKind.ExportSpecifier) {\n    sym = sym?.getImmediatelyAliasedSymbol() ?? sym?.getAliasedSymbol();\n    decl = sym?.getValueDeclaration();\n  }\n  // Fallback: search all declarations for a VariableDeclaration with Layer initializer (cross-module)\n  if (sym && decl?.getKind() !== SyntaxKind.VariableDeclaration) {\n    for (const d of sym.getDeclarations()) {\n      if (d.getKind() === SyntaxKind.VariableDeclaration) {\n        const v = d as VariableDeclaration;\n        const init = v.getInitializer();\n        if (init?.getKind() === SyntaxKind.CallExpression) {\n          if (isLayerOrEffectInitializerCallee(init as CallExpression)) {\n            return init;\n          }\n        }\n      }\n    }\n  }\n  if (decl?.getKind() === SyntaxKind.VariableDeclaration) {\n    const vd = decl as VariableDeclaration;\n    const init = vd.getInitializer();\n    if (init?.getKind() === SyntaxKind.CallExpression) {\n      if (isLayerOrEffectInitializerCallee(init as CallExpression)) {\n        return init;\n      }\n    }\n  }\n  return node;\n}\n","/**\n * Heuristics for inferring service / runtime-primitive types from raw AST text.\n *\n * These are best-effort guesses used to label nodes in the IR (e.g. mark a\n * call as `serviceCall` when the receiver looks like a service). They never\n * fall back to the rest of the analyzer pipeline, which is why they live in\n * their own module.\n *\n * Extracted from effect-analysis.ts as part of the strangler-fig cleanup.\n * Behaviour is preserved exactly.\n */\n\nimport type { PropertyAccessExpression, ArrowFunction, FunctionExpression } from 'ts-morph';\nimport type { StaticEffectNode } from './types';\nimport {\n  BUILT_IN_TYPE_NAMES,\n  KNOWN_EFFECT_NAMESPACES,\n} from './analysis-patterns';\n\nexport const isPromiseLikeText = (text: string): boolean =>\n  /\\bPromise(?:<.*>)?\\b/.test(text) || /\\bthen\\s*\\(/.test(text);\n\nconst EFFECT_RUNTIME_PRIMITIVE_PREFIXES = [\n  'Ref.',\n  'SynchronizedRef.',\n  'FiberRef.',\n  'TxRef.',\n  'TRef.',\n  'Queue.',\n  'TQueue.',\n  'TxQueue.',\n  'PubSub.',\n  'TPubSub.',\n  'Deferred.',\n  'TDeferred.',\n  'Semaphore.',\n  'TSemaphore.',\n  'SubscriptionRef.',\n  'Mailbox.',\n];\n\nexport const isEffectRuntimePrimitive = (text: string): boolean =>\n  EFFECT_RUNTIME_PRIMITIVE_PREFIXES.some((prefix) => text.startsWith(prefix));\n\nexport const isLikelyServiceStreamProperty = (propertyName: string): boolean =>\n  propertyName === 'stream' || propertyName.startsWith('stream');\n\nconst normalizeInferredServiceType = (typeName: string): string =>\n  typeName.endsWith('Shape') ? typeName.slice(0, -'Shape'.length) : typeName;\n\nconst inferServiceTypeFromObjectName = (objectName: string): string | undefined => {\n  if (!/^[a-zA-Z_$][\\w$]*$/.test(objectName)) return undefined;\n  if (objectName.length === 0) return undefined;\n  const inferred = objectName[0]!.toUpperCase() + objectName.slice(1);\n  if (BUILT_IN_TYPE_NAMES.has(inferred) || KNOWN_EFFECT_NAMESPACES.has(inferred)) {\n    return undefined;\n  }\n  return inferred;\n};\n\nexport const tryResolveServicePropertyAccess = (\n  node: PropertyAccessExpression,\n): StaticEffectNode['serviceCall'] => {\n  const objectName = node.getExpression().getText();\n  const methodName = node.getName();\n  const firstSegment = objectName.split('.')[0] ?? objectName;\n  const fallback = inferServiceTypeFromObjectName(objectName);\n  if (KNOWN_EFFECT_NAMESPACES.has(firstSegment)) return undefined;\n\n  try {\n    const type = node.getExpression().getType();\n    const symbol = type.getSymbol() ?? type.getAliasSymbol();\n    if (!symbol) return fallback ? { serviceType: fallback, methodName, objectName } : undefined;\n    const typeName = normalizeInferredServiceType(symbol.getName());\n    if (\n      !typeName ||\n      typeName === '__type' ||\n      typeName === 'unknown' ||\n      typeName === 'any' ||\n      BUILT_IN_TYPE_NAMES.has(typeName)\n    ) {\n      return fallback ? { serviceType: fallback, methodName, objectName } : undefined;\n    }\n    return { serviceType: typeName, methodName, objectName };\n  } catch {\n    return fallback ? { serviceType: fallback, methodName, objectName } : undefined;\n  }\n};\n\nexport const classifyUseCallbackKind = (\n  fnNode: ArrowFunction | FunctionExpression,\n): 'promise' | 'effect' | 'unknown' => {\n  const body = fnNode.getBody();\n  const bodyText = body.getText();\n  if (\n    bodyText.includes('Effect.') ||\n    bodyText.includes('yield*') ||\n    bodyText.includes('.pipe(')\n  ) {\n    return 'effect';\n  }\n\n  if (isPromiseLikeText(bodyText)) {\n    return 'promise';\n  }\n\n  try {\n    const fnTypeText = fnNode.getType().getText();\n    if (fnTypeText.includes('Effect<') || fnTypeText.includes('Effect.Effect<')) {\n      return 'effect';\n    }\n    if (isPromiseLikeText(fnTypeText)) {\n      return 'promise';\n    }\n  } catch {\n    // best-effort classification only\n  }\n\n  return 'unknown';\n};\n","/** Shared recursive context for domain-specific expression analyzers. */\n\nimport type { Effect } from 'effect';\nimport type { Node, SourceFile } from 'ts-morph';\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  StaticFlowNode,\n} from './types';\n\nexport type AnalyzeEffectExpression = (\n  node: Node,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>,\n) => Effect.Effect<StaticFlowNode, AnalysisError>;\n\nexport interface AnalysisContext {\n  readonly analyzeEffectExpression: AnalyzeEffectExpression;\n}\n\n/**\n * Close recursive dispatch behind one context. The getter is intentionally\n * lazy so module initialization order is not part of any analyzer interface.\n */\nexport const createAnalysisContext = (\n  getAnalyze: () => AnalyzeEffectExpression,\n): AnalysisContext => ({\n  get analyzeEffectExpression() {\n    return getAnalyze();\n  },\n});\n\nexport type BindAnalysisContext<F> = F extends (\n  context: AnalysisContext,\n  ...args: infer Args\n) => infer Output\n  ? (...args: Args) => Output\n  : never;\n\nexport const bindAnalysisContext = <\n  F extends (context: AnalysisContext, ...args: never[]) => unknown,\n>(\n  context: AnalysisContext,\n  analyzer: F,\n): BindAnalysisContext<F> =>\n  ((...args: never[]) => analyzer(context, ...args)) as BindAnalysisContext<F>;\n","/**\n * Stream / Channel / Sink call analyzers.\n *\n * These functions parse Stream.*, Channel.* and Sink.* call expressions into\n * their corresponding IR nodes. They recursively analyse argument expressions,\n * which used to create a circular import on `analyzeEffectExpression` — so the\n * dependency is now passed in via the `AnalyzerDeps` parameter, keeping the\n * module acyclic.\n *\n * Extracted from effect-analysis.ts as part of the strangler-fig cleanup.\n * Behaviour is preserved exactly; the only change is `analyzeEffectExpression`\n * is now accessed via `deps.analyzeEffectExpression` instead of a direct call.\n */\n\nimport { Effect } from 'effect';\nimport type {\n  CallExpression,\n  SourceFile,\n  PropertyAccessExpression,\n  ArrowFunction,\n  FunctionExpression,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  StaticFlowNode,\n  StaticStreamNode,\n  StaticChannelNode,\n  StaticSinkNode,\n  StreamOperatorInfo,\n  ChannelOperatorInfo,\n  SinkOperatorInfo,\n  AnalyzerOptions,\n  AnalysisWarning,\n  AnalysisStats,\n  AnalysisError,\n} from './types';\nimport {\n  generateId,\n  extractLocation,\n  computeDisplayName,\n  computeSemanticRole,\n} from './analysis-utils';\nimport {\n  buildCallbackSummaryNodes,\n  buildPureCallbackSummaryNodes,\n} from './callback-summary';\nimport { channelOpCategory, sinkOpCategory } from './analysis-classifiers';\nimport { getNumericLiteralFromNode } from './analysis-patterns';\nimport type { AnalysisContext } from './analysis-context';\n\n/** Parse Stream.* call into StaticStreamNode (GAP 5). */\nexport function analyzeStreamCall(\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>,\n): Effect.Effect<StaticStreamNode, AnalysisError> {\n  return Effect.gen(function* () {\n    const args = call.getArguments();\n    const { SyntaxKind } = loadTsMorph();\n\n    if (\n      call.getExpression().getKind() === SyntaxKind.PropertyAccessExpression &&\n      (call.getExpression() as PropertyAccessExpression).getName() === 'pipe'\n    ) {\n      const propAccess = call.getExpression() as PropertyAccessExpression;\n      const baseExpr = propAccess.getExpression();\n      const analyzedBase = yield* deps.analyzeEffectExpression(\n        baseExpr,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n        serviceScope,\n      );\n\n      const effectiveSource =\n        analyzedBase.type === 'stream' ? analyzedBase.source : analyzedBase;\n      const pipeline =\n        analyzedBase.type === 'stream' ? [...analyzedBase.pipeline] : [];\n      let sink =\n        analyzedBase.type === 'stream' ? analyzedBase.sink : undefined;\n      let backpressureStrategy =\n        analyzedBase.type === 'stream'\n          ? analyzedBase.backpressureStrategy\n          : undefined;\n      let constructorType =\n        analyzedBase.type === 'stream' ? analyzedBase.constructorType : undefined;\n\n      for (const arg of args) {\n        const analyzed = yield* deps.analyzeEffectExpression(\n          arg,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n          serviceScope,\n        );\n        if (analyzed.type === 'stream') {\n          pipeline.push(...analyzed.pipeline);\n          if (!sink && analyzed.sink) sink = analyzed.sink;\n          if (!backpressureStrategy && analyzed.backpressureStrategy) {\n            backpressureStrategy = analyzed.backpressureStrategy;\n          }\n          if (!constructorType && analyzed.constructorType) {\n            constructorType = analyzed.constructorType;\n          }\n        }\n      }\n\n      const streamNode: StaticStreamNode = {\n        id: generateId(),\n        type: 'stream',\n        source: effectiveSource,\n        pipeline,\n        ...(sink ? { sink } : {}),\n        ...(backpressureStrategy ? { backpressureStrategy } : {}),\n        ...(constructorType ? { constructorType } : {}),\n        location: extractLocation(call, filePath, opts.includeLocations ?? false),\n      };\n      return {\n        ...streamNode,\n        displayName: computeDisplayName(streamNode),\n        semanticRole: computeSemanticRole(streamNode),\n      };\n    }\n\n    let source: StaticFlowNode;\n    if (args.length > 0 && args[0]) {\n      source = yield* deps.analyzeEffectExpression(\n        args[0],\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n        serviceScope,\n      );\n    } else {\n      source = {\n        id: generateId(),\n        type: 'unknown',\n        reason: 'Stream source not determined',\n      };\n    }\n    const opName = callee.replace(/^Stream\\./, '') || 'unknown';\n\n    // Classify constructor type\n    let constructorType: StaticStreamNode['constructorType'];\n    if (callee.startsWith('Stream.')) {\n      if (opName === 'fromIterable' || opName === 'fromChunk' || opName === 'fromChunkQueue') constructorType = 'fromIterable';\n      else if (opName === 'fromArray') constructorType = 'fromArray';\n      else if (opName === 'fromQueue' || opName === 'fromChunkQueue') constructorType = 'fromQueue';\n      else if (opName === 'fromPubSub' || opName === 'fromChunkPubSub') constructorType = 'fromPubSub';\n      else if (opName === 'fromEffect' || opName === 'unwrap' || opName === 'unwrapScoped') constructorType = 'fromEffect';\n      else if (opName === 'fromAsyncIterable') constructorType = 'fromAsyncIterable';\n      else if (opName === 'fromReadableStream' || opName === 'fromReadableStreamByob') constructorType = 'fromReadableStream';\n      else if (opName === 'fromEventListener') constructorType = 'fromEventListener';\n      else if (opName === 'fromSchedule') constructorType = 'fromSchedule';\n      else if (opName === 'range') constructorType = 'range';\n      else if (opName === 'tick') constructorType = 'tick';\n      else if (opName === 'iterate' || opName === 'iterateEffect') constructorType = 'iterate';\n      else if (opName === 'unfold' || opName === 'unfoldEffect' || opName === 'unfoldChunk' || opName === 'unfoldChunkEffect') constructorType = 'unfold';\n      else if (opName === 'make') constructorType = 'make';\n      else if (opName === 'empty') constructorType = 'empty';\n      else if (opName === 'never') constructorType = 'never';\n      else if (opName === 'succeed' || opName === 'sync') constructorType = 'succeed';\n      else if (opName === 'fail' || opName === 'failSync' || opName === 'failCause' || opName === 'failCauseSync') constructorType = 'fail';\n    }\n\n    // Classify operator category\n    const classifyOperator = (op: string): StreamOperatorInfo['category'] => {\n      if (constructorType !== undefined) return 'constructor';\n      if (op.startsWith('run')) return 'sink';\n      if (op === 'toQueue' || op === 'toPubSub' || op === 'toReadableStream' || op === 'toAsyncIterable' || op === 'toChannel') return 'conversion';\n      if (op.includes('pipeThroughChannel') || op.includes('Channel') || op.includes('channel') || op.includes('duplex')) return 'channel';\n      if (op.includes('grouped') || op.includes('sliding') || op.includes('groupBy') || op.includes('aggregate') || op.includes('window')) return 'windowing';\n      if (op.includes('broadcast') || op === 'share') return 'broadcasting';\n      if (op.includes('haltAfter') || op.includes('haltWhen') || op.includes('interruptAfter')) return 'halting';\n      if (op.includes('decodeText') || op.includes('encodeText') || op.includes('splitLines')) return 'text';\n      if (op.includes('merge') || op === 'concat' || op.includes('interleave') || op.includes('zip')) return 'merge';\n      if (op.includes('buffer') || op.includes('debounce') || op.includes('throttle')) return 'backpressure';\n      if (op.includes('catch') || op.includes('catchTag') || op.includes('orElse') || op.includes('orDie') || op.includes('retry')) return 'error';\n      if (op.includes('filter') || op.includes('take') || op.includes('drop') || op.includes('head') || op === 'first' || op === 'last') return 'filter';\n      if (op.includes('acquireRelease') || op.includes('scoped') || op.includes('ensuring') || op.includes('onDone') || op.includes('onError')) return 'resource';\n      if (op.includes('provide') || op.includes('withSpan') || op.includes('annotate')) return 'context';\n      if (op.includes('map') || op.includes('tap') || op.includes('flatMap') || op.includes('mapChunk') || op.includes('scan') || op.includes('transduce')) return 'transform';\n      return 'other';\n    };\n\n    const isEffectful =\n      opName.includes('Effect') ||\n      opName.startsWith('run') ||\n      opName.includes('tap');\n    const callbackArg = args.find(\n      (arg) =>\n        arg.getKind() === SyntaxKind.ArrowFunction ||\n        arg.getKind() === SyntaxKind.FunctionExpression,\n    );\n    const callbackBody = callbackArg\n      ? (\n          opName.includes('Effect') || opName.includes('tap')\n            ? buildCallbackSummaryNodes(\n                callbackArg as ArrowFunction | FunctionExpression,\n                filePath,\n                opts.includeLocations ?? false,\n              )\n            : buildPureCallbackSummaryNodes(\n                callbackArg as ArrowFunction | FunctionExpression,\n                filePath,\n                opts.includeLocations ?? false,\n              )\n        )\n      : undefined;\n    const opCategory = classifyOperator(opName);\n    const cardinality: StreamOperatorInfo['estimatedCardinality'] =\n      opCategory === 'filter' ? 'fewer' :\n      opCategory === 'merge' ? 'more' :\n      opCategory === 'broadcasting' ? 'more' :\n      opCategory === 'halting' ? 'fewer' :\n      opCategory === 'sink' ? 'fewer' :\n      opCategory === 'windowing' ? 'fewer' :\n      'unknown';\n\n    // Windowing detail (GAP 2): size/stride for grouped, groupedWithin, sliding\n    let windowSize: number | undefined;\n    let stride: number | undefined;\n    const isWindowingOp =\n      opName === 'grouped' ||\n      opName === 'groupedWithin' ||\n      opName.includes('sliding') ||\n      opName.includes('Sliding');\n    if (isWindowingOp && args.length > 0 && args[0]) {\n      windowSize = getNumericLiteralFromNode(args[0]);\n      if (\n        (opName.includes('sliding') || opName.includes('Sliding')) &&\n        args.length > 1 &&\n        args[1]\n      ) {\n        stride = getNumericLiteralFromNode(args[1]);\n      }\n    }\n\n    const thisOp: StreamOperatorInfo = {\n      operation: opName,\n      isEffectful,\n      ...(callbackBody ? { callbackBody } : {}),\n      estimatedCardinality: cardinality,\n      category: opCategory,\n      ...(windowSize !== undefined ? { windowSize } : {}),\n      ...(stride !== undefined ? { stride } : {}),\n    };\n\n    let sink: string | undefined;\n    if (opName.startsWith('run')) sink = opName;\n    let backpressureStrategy: StaticStreamNode['backpressureStrategy'];\n    if (opName.includes('buffer')) backpressureStrategy = 'buffer';\n    else if (opName.includes('drop') || opName.includes('Drop')) backpressureStrategy = 'drop';\n    else if (opName.includes('sliding') || opName.includes('Sliding')) backpressureStrategy = 'sliding';\n\n    // Flatten nested stream pipeline: if source is itself a StreamNode (data-last\n    // call pattern), merge its pipeline into ours and use its base source.\n    let effectiveSource = source;\n    let pipeline: StreamOperatorInfo[] = [thisOp];\n    let effectiveConstructorType = constructorType;\n    if (source.type === 'stream') {\n      const srcStream = source;\n      // Prepend the upstream pipeline so the full chain is visible in one node\n      pipeline = [...srcStream.pipeline, thisOp];\n      effectiveSource = srcStream.source;\n      // Inherit upstream constructorType/sink/strategy if this node doesn't override\n      if (!effectiveConstructorType && srcStream.constructorType) effectiveConstructorType = srcStream.constructorType;\n      if (!sink && srcStream.sink) sink = srcStream.sink;\n      if (!backpressureStrategy && srcStream.backpressureStrategy) backpressureStrategy = srcStream.backpressureStrategy;\n    }\n\n    const streamNode: StaticStreamNode = {\n      id: generateId(),\n      type: 'stream',\n      source: effectiveSource,\n      pipeline,\n      sink,\n      backpressureStrategy,\n      constructorType: effectiveConstructorType,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...streamNode,\n      displayName: computeDisplayName(streamNode),\n      semanticRole: computeSemanticRole(streamNode),\n    };\n  });\n}\n\n/** Parse Channel.* call into StaticChannelNode (improve.md §8). */\nexport function analyzeChannelCall(\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticChannelNode, AnalysisError> {\n  return Effect.gen(function* () {\n    const args = call.getArguments();\n    let source: StaticFlowNode | undefined;\n    if (args.length > 0 && args[0]) {\n      source = yield* deps.analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats);\n    }\n    const opName = callee.replace(/^Channel\\./, '') || 'unknown';\n    const pipeline: ChannelOperatorInfo[] = [{ operation: opName, category: channelOpCategory(opName) }];\n    if (source?.type === 'channel') {\n      const srcChan = source;\n      pipeline.unshift(...srcChan.pipeline);\n      source = srcChan.source;\n    }\n    const channelNode: StaticChannelNode = {\n      id: generateId(),\n      type: 'channel',\n      source,\n      pipeline,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...channelNode,\n      displayName: computeDisplayName(channelNode),\n      semanticRole: computeSemanticRole(channelNode),\n    };\n  });\n}\n\n/** Parse Sink.* call into StaticSinkNode (improve.md §8). */\nexport function analyzeSinkCall(\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticSinkNode, AnalysisError> {\n  return Effect.gen(function* () {\n    const args = call.getArguments();\n    let source: StaticFlowNode | undefined;\n    if (args.length > 0 && args[0]) {\n      source = yield* deps.analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats);\n    }\n    const opName = callee.replace(/^Sink\\./, '') || 'unknown';\n    const pipeline: SinkOperatorInfo[] = [{ operation: opName, category: sinkOpCategory(opName) }];\n    if (source?.type === 'sink') {\n      const srcSink = source;\n      pipeline.unshift(...srcSink.pipeline);\n      source = srcSink.source;\n    }\n    const sinkNode: StaticSinkNode = {\n      id: generateId(),\n      type: 'sink',\n      source,\n      pipeline,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...sinkNode,\n      displayName: computeDisplayName(sinkNode),\n      semanticRole: computeSemanticRole(sinkNode),\n    };\n  });\n}\n","/**\n * Pure classifier and parsing helpers used by the analyzer.\n *\n * These functions are intentionally side-effect-free and do not call back\n * into the rest of the analyzer pipeline, which is why they live in their\n * own module — keeping effect-analysis.ts focused on tree-walking logic.\n *\n * Extracted from effect-analysis.ts as part of the strangler-fig cleanup.\n * Behaviour is preserved exactly.\n */\n\nimport type { ObjectLiteralExpression, PropertyAssignment } from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  ConcurrencyMode,\n  ScheduleInfo,\n  ChannelOperatorInfo,\n  SinkOperatorInfo,\n} from './types';\n\n/** Classify Channel.* operation (improve.md §8). */\nexport function channelOpCategory(op: string): ChannelOperatorInfo['category'] {\n  if (\n    op === 'fromReadableStream' ||\n    op === 'fromWritableStream' ||\n    op === 'fromDuplexStream' ||\n    op === 'make' ||\n    op === 'succeed' ||\n    op === 'fail' ||\n    op === 'empty' ||\n    op === 'never'\n  )\n    return 'constructor';\n  if (\n    op.includes('map') ||\n    op.includes('flatMap') ||\n    op.includes('filter') ||\n    op.includes('concat') ||\n    op.includes('zip')\n  )\n    return 'transform';\n  if (op.includes('pipe') || op === 'pipeTo' || op === 'pipeThrough') return 'pipe';\n  return 'other';\n}\n\n/** Classify Sink.* operation (improve.md §8). */\nexport function sinkOpCategory(op: string): SinkOperatorInfo['category'] {\n  if (\n    op === 'forEach' ||\n    op === 'forEachWhile' ||\n    op === 'run' ||\n    op === 'runDrain' ||\n    op === 'runFor' ||\n    op === 'make' ||\n    op === 'fromEffect' ||\n    op === 'fromQueue'\n  )\n    return 'constructor';\n  if (\n    op.includes('map') ||\n    op.includes('contramap') ||\n    op.includes('filter') ||\n    op.includes('zip')\n  )\n    return 'transform';\n  return 'other';\n}\n\n/** Parse Effect.all options object: concurrency, batching, discard (GAP 18). */\nexport function parseEffectAllOptions(\n  optionsNode: ObjectLiteralExpression,\n): {\n  concurrency: ConcurrencyMode | undefined;\n  batching: boolean | undefined;\n  discard: boolean | undefined;\n} {\n  const { SyntaxKind } = loadTsMorph();\n  let concurrency: ConcurrencyMode | undefined;\n  let batching: boolean | undefined;\n  let discard: boolean | undefined;\n  for (const prop of optionsNode.getProperties()) {\n    if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n    const name = (prop as PropertyAssignment).getNameNode().getText();\n    const init = (prop as PropertyAssignment).getInitializer();\n    if (!init) continue;\n    const text = init.getText();\n    if (name === 'concurrency') {\n      if (text === '\"unbounded\"' || text === \"'unbounded'\") concurrency = 'unbounded';\n      else if (text === '\"sequential\"' || text === \"'sequential'\") concurrency = 'sequential';\n      else if (text === '\"inherit\"' || text === \"'inherit'\") concurrency = 'sequential';\n      else {\n        const n = Number.parseInt(text, 10);\n        if (!Number.isNaN(n) && n >= 0) concurrency = n;\n      }\n    } else if (name === 'batching' && (text === 'true' || text === 'false')) {\n      batching = text === 'true';\n    } else if (name === 'discard' && (text === 'true' || text === 'false')) {\n      discard = text === 'true';\n    }\n  }\n  return { concurrency, batching, discard };\n}\n\n/** Parse schedule expression text into ScheduleInfo (GAP 8). */\nexport function parseScheduleInfo(scheduleText: string): ScheduleInfo | undefined {\n  const t = scheduleText.replace(/\\s+/g, ' ');\n  let baseStrategy: ScheduleInfo['baseStrategy'] = 'custom';\n  if (t.includes('Schedule.exponential') || t.includes('exponential(')) baseStrategy = 'exponential';\n  else if (t.includes('Schedule.fibonacci') || t.includes('fibonacci(')) baseStrategy = 'fibonacci';\n  else if (t.includes('Schedule.spaced') || t.includes('spaced(')) baseStrategy = 'spaced';\n  else if (t.includes('Schedule.fixed') || t.includes('fixed(')) baseStrategy = 'fixed';\n  else if (t.includes('Schedule.linear') || t.includes('linear(')) baseStrategy = 'linear';\n  else if (t.includes('Schedule.cron') || t.includes('cron(')) baseStrategy = 'cron';\n  else if (t.includes('Schedule.windowed') || t.includes('windowed(')) baseStrategy = 'windowed';\n  else if (t.includes('Schedule.duration') || t.includes('duration(')) baseStrategy = 'duration';\n  else if (t.includes('Schedule.elapsed') || t.includes('elapsed(')) baseStrategy = 'elapsed';\n  else if (t.includes('Schedule.delays') || t.includes('delays(')) baseStrategy = 'delays';\n  else if (t.includes('Schedule.once') || t.includes('once(')) baseStrategy = 'once';\n  else if (t.includes('Schedule.stop') || t.includes('stop(')) baseStrategy = 'stop';\n  else if (t.includes('Schedule.count') || t.includes('count(')) baseStrategy = 'count';\n\n  let maxRetries: number | 'unlimited' | undefined;\n  const recursMatch = /recurs\\s*\\(\\s*(\\d+)\\s*\\)/.exec(t);\n  if (recursMatch) maxRetries = Number.parseInt(recursMatch[1]!, 10);\n  const recurUpToMatch = /recurUpTo\\s*\\(\\s*(\\d+)\\s*\\)/.exec(t);\n  if (recurUpToMatch) maxRetries = Number.parseInt(recurUpToMatch[1]!, 10);\n  else if (t.includes('forever') || t.includes('Schedule.forever')) maxRetries = 'unlimited';\n\n  const jittered = t.includes('jittered') || t.includes('Schedule.jittered');\n  const conditions: string[] = [];\n  if (t.includes('whileInput')) conditions.push('whileInput');\n  if (t.includes('whileOutput')) conditions.push('whileOutput');\n  if (t.includes('untilInput')) conditions.push('untilInput');\n  if (t.includes('untilOutput')) conditions.push('untilOutput');\n  if (t.includes('recurUntil')) conditions.push('recurUntil');\n  if (t.includes('recurWhile')) conditions.push('recurWhile');\n  if (t.includes('andThen')) conditions.push('andThen');\n  if (t.includes('intersect')) conditions.push('intersect');\n  if (t.includes('union')) conditions.push('union');\n  if (t.includes('compose')) conditions.push('compose');\n  if (t.includes('zipWith')) conditions.push('zipWith');\n  if (t.includes('addDelay')) conditions.push('addDelay');\n  if (t.includes('modifyDelay')) conditions.push('modifyDelay');\n  if (t.includes('check')) conditions.push('check');\n  if (t.includes('resetAfter')) conditions.push('resetAfter');\n  if (t.includes('resetWhen')) conditions.push('resetWhen');\n  if (t.includes('ensure')) conditions.push('ensure');\n  if (t.includes('driver')) conditions.push('driver');\n  if (t.includes('mapInput')) conditions.push('mapInput');\n\n  return {\n    baseStrategy,\n    maxRetries,\n    jittered,\n    conditions,\n  };\n}\n","/**\n * Retry / Timeout / Schedule call analyzers.\n *\n * Retry and Timeout both need to recurse into their source effect via\n * `deps.analyzeEffectExpression`. The standalone Schedule analyzer is purely\n * structural and doesn't recurse, but it lives here for cohesion with the\n * temporal-control analyzers.\n *\n * Extracted from effect-analysis.ts via the strangler-fig DI pattern —\n * behaviour is preserved exactly.\n */\n\nimport { Effect } from 'effect';\nimport type {\n  CallExpression,\n  SourceFile,\n  PropertyAccessExpression,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  StaticFlowNode,\n  StaticRetryNode,\n  StaticTimeoutNode,\n  StaticScheduleNode,\n  AnalyzerOptions,\n  AnalysisWarning,\n  AnalysisStats,\n  AnalysisError,\n} from './types';\nimport {\n  generateId,\n  extractLocation,\n  computeDisplayName,\n  computeSemanticRole,\n  getNodeText,\n} from './analysis-utils';\nimport { SCHEDULE_OP_MAP } from './analysis-patterns';\nimport { parseScheduleInfo } from './analysis-classifiers';\nimport type { AnalysisContext } from './analysis-context';\n\nexport const analyzeRetryCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticRetryNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n    let source: StaticFlowNode;\n    let schedule: string | undefined;\n    let scheduleNode: StaticFlowNode | undefined;\n    let hasFallback: boolean;\n\n    const expr = call.getExpression();\n    if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n      const propAccess = expr as PropertyAccessExpression;\n      const exprSource = propAccess.getExpression();\n      source = yield* deps.analyzeEffectExpression(\n        exprSource,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n\n      if (args.length > 0 && args[0]) {\n        schedule = args[0].getText();\n        scheduleNode = yield* deps.analyzeEffectExpression(\n          args[0],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      }\n\n      hasFallback = expr.getText().includes('retryOrElse');\n    } else {\n      if (args.length > 0 && args[0]) {\n        source = yield* deps.analyzeEffectExpression(\n          args[0],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      } else {\n        source = {\n          id: generateId(),\n          type: 'unknown',\n          reason: 'Could not determine source effect',\n        };\n      }\n\n      if (args.length > 1 && args[1]) {\n        schedule = args[1].getText();\n        scheduleNode = yield* deps.analyzeEffectExpression(\n          args[1],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      }\n\n      hasFallback = args.length > 2;\n    }\n\n    stats.retryCount++;\n\n    const scheduleInfo = schedule ? parseScheduleInfo(schedule) : undefined;\n\n    const retryNode: StaticRetryNode = {\n      id: generateId(),\n      type: 'retry',\n      source,\n      schedule,\n      ...(scheduleNode !== undefined ? { scheduleNode } : {}),\n      hasFallback,\n      scheduleInfo,\n      retryEdgeLabel: schedule ? `retry: ${schedule}` : 'retry',\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...retryNode,\n      displayName: computeDisplayName(retryNode),\n      semanticRole: computeSemanticRole(retryNode),\n    };\n  });\n\nexport const analyzeTimeoutCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticTimeoutNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n    let source: StaticFlowNode;\n    let duration: string | undefined;\n    let hasFallback: boolean;\n\n    const expr = call.getExpression();\n    if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n      const propAccess = expr as PropertyAccessExpression;\n      const exprSource = propAccess.getExpression();\n      source = yield* deps.analyzeEffectExpression(\n        exprSource,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n\n      if (args.length > 0 && args[0]) {\n        duration = getNodeText(args[0]);\n      }\n\n      const exprText = getNodeText(expr);\n      hasFallback =\n        exprText.includes('timeoutFail') ||\n        exprText.includes('timeoutTo');\n    } else {\n      if (args.length > 0 && args[0]) {\n        source = yield* deps.analyzeEffectExpression(\n          args[0],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      } else {\n        source = {\n          id: generateId(),\n          type: 'unknown',\n          reason: 'Could not determine source effect',\n        };\n      }\n\n      if (args.length > 1 && args[1]) {\n        duration = getNodeText(args[1]);\n      }\n\n      hasFallback = args.length > 2;\n    }\n\n    stats.timeoutCount++;\n\n    const timeoutNode: StaticTimeoutNode = {\n      id: generateId(),\n      type: 'timeout',\n      source,\n      duration,\n      hasFallback,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...timeoutNode,\n      displayName: computeDisplayName(timeoutNode),\n      semanticRole: computeSemanticRole(timeoutNode),\n    };\n  });\n\n/** Analyze Schedule.exponential / spaced / jittered / andThen / etc. (GAP 8 dedicated IR). */\nexport const analyzeScheduleCall = (\n  call: CallExpression,\n  callee: string,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n): Effect.Effect<StaticScheduleNode, AnalysisError> =>\n  Effect.sync(() => {\n    const scheduleOp: StaticScheduleNode['scheduleOp'] =\n      SCHEDULE_OP_MAP[callee] ?? 'other';\n    const scheduleText = call.getText();\n    const scheduleInfo = parseScheduleInfo(scheduleText);\n    const scheduleNode: StaticScheduleNode = {\n      id: generateId(),\n      type: 'schedule',\n      scheduleOp,\n      ...(scheduleInfo ? { scheduleInfo } : {}),\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...scheduleNode,\n      displayName: computeDisplayName(scheduleNode),\n      semanticRole: computeSemanticRole(scheduleNode),\n    };\n  });\n","/**\n * Concurrency-primitive / Fiber / Interruption call analyzers.\n *\n * - `analyzeConcurrencyPrimitiveCall` classifies Queue/PubSub/Deferred/Semaphore/etc.\n *   It does not recurse, so it takes no deps.\n * - `analyzeFiberCall` and `analyzeInterruptionCall` recurse into source effects\n *   via `deps.analyzeEffectExpression`.\n *\n * Extracted from effect-analysis.ts via the strangler-fig DI pattern.\n * Behaviour is preserved exactly.\n */\n\nimport { Effect } from 'effect';\nimport type {\n  CallExpression,\n  SourceFile,\n  PropertyAccessExpression,\n  NumericLiteral,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  StaticFlowNode,\n  StaticConcurrencyPrimitiveNode,\n  StaticStreamNode,\n  StaticFiberNode,\n  StaticInterruptionNode,\n  AnalyzerOptions,\n  AnalysisWarning,\n  AnalysisStats,\n  AnalysisError,\n} from './types';\nimport {\n  generateId,\n  extractLocation,\n  computeDisplayName,\n  computeSemanticRole,\n} from './analysis-utils';\nimport { getNumericLiteralFromNode } from './analysis-patterns';\nimport type { AnalysisContext } from './analysis-context';\n\n/** Parse concurrency primitive (Queue, PubSub, Deferred, etc.) - GAP 6 */\nexport function analyzeConcurrencyPrimitiveCall(\n  call: CallExpression,\n  callee: string,\n  _sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  _warnings: AnalysisWarning[],\n  _stats: AnalysisStats,\n): Effect.Effect<StaticConcurrencyPrimitiveNode | StaticStreamNode, AnalysisError> {\n  const { SyntaxKind } = loadTsMorph();\n  let primitive: StaticConcurrencyPrimitiveNode['primitive'] = 'queue';\n  let operation: StaticConcurrencyPrimitiveNode['operation'] = 'create';\n  let strategy: 'bounded' | 'unbounded' | 'sliding' | 'dropping' | undefined;\n  let capacity: number | undefined;\n  let permitCount: number | undefined;\n\n  if (callee.startsWith('Queue.')) {\n    primitive = 'queue';\n    if (callee.includes('bounded')) strategy = 'bounded';\n    else if (callee.includes('unbounded')) strategy = 'unbounded';\n    else if (callee.includes('sliding')) strategy = 'sliding';\n    else if (callee.includes('dropping')) strategy = 'dropping';\n    if (callee.includes('offer') || callee.includes('offerAll')) operation = 'offer';\n    else if (callee.includes('take') || callee.includes('takeAll') || callee.includes('poll')) operation = 'take';\n    else operation = 'create';\n  } else if (callee.startsWith('PubSub.')) {\n    primitive = 'pubsub';\n    if (callee.includes('bounded')) strategy = 'bounded';\n    else if (callee.includes('unbounded')) strategy = 'unbounded';\n    if (callee.includes('publish')) operation = 'publish';\n    else if (callee.includes('subscribe')) operation = 'subscribe';\n    else operation = 'create';\n  } else if (callee.startsWith('Deferred.')) {\n    primitive = 'deferred';\n    if (callee.includes('succeed')) operation = 'succeed';\n    else if (callee.includes('fail')) operation = 'fail';\n    else if (callee.includes('await')) operation = 'await';\n    else operation = 'create';\n  } else if (callee.startsWith('Semaphore.')) {\n    primitive = 'semaphore';\n    if (callee.includes('withPermit')) operation = 'withPermit';\n    else if (callee.includes('take')) operation = 'take';\n    else if (callee.includes('release')) operation = 'release';\n    else if (callee.includes('available')) operation = 'available';\n    else operation = 'create';\n  } else if (callee.startsWith('Mailbox.')) {\n    primitive = 'mailbox';\n    if (callee.includes('offer')) operation = 'offer';\n    else if (callee.includes('takeAll')) operation = 'takeAll';\n    else if (callee.includes('take')) operation = 'take';\n    else if (callee.includes('end')) operation = 'end';\n    else if (callee.includes('toStream')) operation = 'toStream';\n    else operation = 'create';\n  } else if (callee.startsWith('SubscriptionRef.')) {\n    primitive = 'subscriptionRef';\n    if (callee.includes('changes')) operation = 'changes';\n    else if (callee.includes('get')) operation = 'get';\n    else if (callee.includes('set')) operation = 'set';\n    else if (callee.includes('update')) operation = 'update';\n    else operation = 'create';\n  } else if (callee.includes('makeLatch') || callee.includes('Latch.')) {\n    primitive = 'latch';\n    if (callee.includes('open')) operation = 'open';\n    else if (callee.includes('close')) operation = 'close';\n    else if (callee.includes('await') || callee.includes('whenOpen')) operation = 'await';\n    else operation = 'create';\n  } else if (callee.startsWith('FiberHandle.')) {\n    primitive = 'fiberHandle';\n    if (callee.includes('run')) operation = 'run';\n    else if (callee.includes('await')) operation = 'await';\n    else operation = 'create';\n  } else if (callee.startsWith('FiberSet.')) {\n    primitive = 'fiberSet';\n    if (callee.includes('run')) operation = 'run';\n    else if (callee.includes('join')) operation = 'await';\n    else operation = 'create';\n  } else if (callee.startsWith('FiberMap.')) {\n    primitive = 'fiberMap';\n    if (callee.includes('run')) operation = 'run';\n    else if (callee.includes('join')) operation = 'await';\n    else operation = 'create';\n  } else if (callee.startsWith('RateLimiter.')) {\n    primitive = 'rateLimiter';\n    if (callee.includes('withCost')) operation = 'withPermit';\n    else operation = 'create';\n  } else if (callee.startsWith('ScopedCache.')) {\n    primitive = 'scopedCache';\n    if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n    else if (callee.includes('get') && !callee.includes('getOrElse')) operation = 'get';\n    else if (callee.includes('getOrElse')) operation = 'get';\n    else if (callee.includes('set') || callee.includes('Set')) operation = 'set';\n    else if (callee.includes('invalidate')) operation = 'invalidate';\n    else if (callee.includes('contains')) operation = 'contains';\n    else operation = 'create';\n  } else if (callee.startsWith('Cache.')) {\n    primitive = 'cache';\n    if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n    else if (callee.includes('get') && !callee.includes('getOrElse')) operation = 'get';\n    else if (callee.includes('getOrElse')) operation = 'get';\n    else if (callee.includes('set') || callee.includes('Set')) operation = 'set';\n    else if (callee.includes('invalidate')) operation = 'invalidate';\n    else if (callee.includes('contains')) operation = 'contains';\n    else operation = 'create';\n  } else if (callee.startsWith('Reloadable.') || callee.includes('.Reloadable.')) {\n    primitive = 'reloadable';\n    if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n    else if (callee.includes('get') && !callee.includes('reload')) operation = 'get';\n    else if (callee.includes('reload')) operation = 'reload';\n    else operation = 'create';\n  } else if (callee.startsWith('RcMap.') || callee.includes('.RcMap.')) {\n    primitive = 'rcMap';\n    if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n    else if (callee.includes('get')) operation = 'get';\n    else if (callee.includes('set') || callee.includes('Set')) operation = 'set';\n    else if (callee.includes('update')) operation = 'update';\n    else operation = 'create';\n  } else if (callee.startsWith('RcRef.') || callee.includes('.RcRef.')) {\n    primitive = 'rcRef';\n    if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n    else if (callee.includes('get')) operation = 'get';\n    else if (callee.includes('set') || callee.includes('Set')) operation = 'set';\n    else if (callee.includes('update')) operation = 'update';\n    else operation = 'create';\n  }\n\n  const args = call.getArguments();\n  if (args.length > 0 && strategy === 'bounded') {\n    const first = args[0];\n    if (first?.getKind() === SyntaxKind.NumericLiteral) {\n      capacity = Number.parseInt((first as NumericLiteral).getText(), 10);\n    }\n  }\n  if (primitive === 'semaphore' && (operation === 'take' || operation === 'release') && args.length > 0 && args[0]) {\n    permitCount = getNumericLiteralFromNode(args[0]);\n  }\n\n  // Extract lifecycle options for FiberHandle.run({ onlyIfMissing: true })\n  let lifecycleOptions: Record<string, unknown> | undefined;\n  if (primitive === 'fiberHandle' && operation === 'run') {\n    for (const arg of args) {\n      const text = arg.getText();\n      if (text.includes('onlyIfMissing')) {\n        lifecycleOptions = { onlyIfMissing: text.includes('true') };\n      }\n    }\n  }\n\n  // Mailbox.toStream and SubscriptionRef.changes produce stream nodes\n  if (\n    (primitive === 'mailbox' && operation === 'toStream') ||\n    (primitive === 'subscriptionRef' && operation === 'changes')\n  ) {\n    const constructorType =\n      primitive === 'mailbox' ? ('fromMailbox' as const) : ('fromSubscriptionRef' as const);\n    const innerPrimNode = {\n      id: generateId(),\n      type: 'concurrency-primitive' as const,\n      primitive,\n      operation,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    const streamNode = {\n      id: generateId(),\n      type: 'stream' as const,\n      source: {\n        ...innerPrimNode,\n        displayName: computeDisplayName(innerPrimNode),\n        semanticRole: computeSemanticRole(innerPrimNode),\n      },\n      pipeline: [],\n      constructorType,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    } as StaticStreamNode;\n    return Effect.succeed({\n      ...streamNode,\n      displayName: computeDisplayName(streamNode),\n      semanticRole: computeSemanticRole(streamNode),\n    });\n  }\n\n  const concurrencyNode: StaticConcurrencyPrimitiveNode = {\n    id: generateId(),\n    type: 'concurrency-primitive',\n    primitive,\n    operation,\n    strategy,\n    capacity,\n    ...(permitCount !== undefined ? { permitCount } : {}),\n    ...(lifecycleOptions ? { lifecycleOptions } : {}),\n    location: extractLocation(call, filePath, opts.includeLocations ?? false),\n  };\n  return Effect.succeed({\n    ...concurrencyNode,\n    displayName: computeDisplayName(concurrencyNode),\n    semanticRole: computeSemanticRole(concurrencyNode),\n  });\n}\n\n/** Parse fiber operations (Effect.fork, Fiber.join, etc.) - GAP 1 */\nexport function analyzeFiberCall(\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticFiberNode, AnalysisError> {\n  return Effect.gen(function* () {\n    const args = call.getArguments();\n    const { SyntaxKind } = loadTsMorph();\n    let operation: StaticFiberNode['operation'] = 'fork';\n    let isScoped = false;\n    let isDaemon = false;\n    let fiberSource: StaticFlowNode | undefined;\n    let joinPoint: string | undefined;\n\n    if (callee.startsWith('Fiber.')) {\n      if (callee.includes('awaitAll')) operation = 'awaitAll';\n      else if (callee.includes('join')) operation = 'join';\n      else if (callee.includes('await')) operation = 'await';\n      else if (callee.includes('interruptFork')) operation = 'interruptFork';\n      else if (callee.includes('interrupt')) operation = 'interrupt';\n      else if (callee.includes('poll')) operation = 'poll';\n      else if (callee.includes('status')) operation = 'status';\n      else if (callee.includes('all')) operation = 'all';\n      else if (callee.includes('children')) operation = 'children';\n      else if (callee.includes('dump')) operation = 'dump';\n      else if (callee.includes('scoped')) { operation = 'scoped'; isScoped = true; }\n      else if (callee.includes('inheritAll')) operation = 'inheritAll';\n      else if (callee.includes('mapFiber')) operation = 'mapFiber';\n      else if (callee.includes('mapEffect')) operation = 'mapEffect';\n      else if (callee.includes('map')) operation = 'map';\n      else if (callee.includes('roots')) operation = 'roots';\n      else if (callee.includes('getCurrentFiber')) operation = 'getCurrentFiber';\n    } else if (callee.includes('forkWithErrorHandler')) {\n      operation = 'forkWithErrorHandler';\n    } else if (callee.includes('forkAll')) {\n      operation = 'forkAll';\n    } else if (callee.includes('forkIn')) {\n      operation = 'forkIn';\n    } else if (callee.includes('fork')) {\n      if (callee.includes('forkDaemon')) {\n        operation = 'forkDaemon';\n        isDaemon = true;\n      } else if (callee.includes('forkScoped')) {\n        operation = 'forkScoped';\n        isScoped = true;\n      } else {\n        operation = 'fork';\n      }\n    }\n\n    if (\n      (operation === 'fork' ||\n        operation === 'forkScoped' ||\n        operation === 'forkDaemon' ||\n        operation === 'forkAll' ||\n        operation === 'forkIn' ||\n        operation === 'forkWithErrorHandler') &&\n      args.length > 0 &&\n      args[0]\n    ) {\n      fiberSource = yield* deps.analyzeEffectExpression(\n        args[0],\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n    }\n\n    if (\n      (operation === 'join' || operation === 'await' || operation === 'interrupt' || operation === 'interruptFork') &&\n      args.length > 0 &&\n      args[0]\n    ) {\n      const firstArg = args[0];\n      if (firstArg.getKind() === SyntaxKind.Identifier) {\n        joinPoint = firstArg.getText();\n      }\n    }\n\n    // Determine scope context: 'safe' when fork is scoped or inside Effect.scoped/Scope.make\n    let scopeContext: string | undefined;\n    if (isScoped) {\n      scopeContext = 'safe';\n    } else {\n      // Walk up AST to check if inside Effect.scoped\n      let parent = call.getParent();\n      while (parent) {\n        const parentText = parent.getText?.();\n        if (parentText && (parentText.includes('Effect.scoped') || parentText.includes('Scope.make'))) {\n          scopeContext = 'safe';\n          break;\n        }\n        parent = parent.getParent();\n        // Don't walk too far\n        if (parent && parent === sourceFile) break;\n      }\n    }\n\n    const fiberNode: StaticFiberNode = {\n      id: generateId(),\n      type: 'fiber',\n      operation,\n      fiberSource,\n      isScoped,\n      isDaemon,\n      ...(joinPoint ? { joinPoint } : {}),\n      ...(scopeContext ? { scopeContext } : {}),\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...fiberNode,\n      displayName: computeDisplayName(fiberNode),\n      semanticRole: computeSemanticRole(fiberNode),\n    };\n  });\n}\n\n/** Parse interruption operations (interruptible, uninterruptible, onInterrupt, etc.) */\nexport function analyzeInterruptionCall(\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticInterruptionNode, AnalysisError> {\n  return Effect.gen(function* () {\n    const args = call.getArguments();\n    const { SyntaxKind } = loadTsMorph();\n\n    let interruptionType: StaticInterruptionNode['interruptionType'];\n    if (callee.includes('uninterruptibleMask')) interruptionType = 'uninterruptibleMask';\n    else if (callee.includes('interruptibleMask')) interruptionType = 'interruptibleMask';\n    else if (callee.includes('uninterruptible')) interruptionType = 'uninterruptible';\n    else if (callee.includes('interruptible')) interruptionType = 'interruptible';\n    else if (callee.includes('onInterrupt')) interruptionType = 'onInterrupt';\n    else if (callee.includes('disconnect')) interruptionType = 'disconnect';\n    else if (callee.includes('allowInterrupt')) interruptionType = 'allowInterrupt';\n    else if (callee.includes('interruptWith')) interruptionType = 'interruptWith';\n    else interruptionType = 'interrupt';\n\n    let source: StaticFlowNode | undefined;\n    let handler: StaticFlowNode | undefined;\n\n    // Method call form: effect.pipe(Effect.interruptible) or effect.interruptible\n    const expr = call.getExpression();\n    if (expr.getKind() === SyntaxKind.PropertyAccessExpression) {\n      const propAccess = expr as PropertyAccessExpression;\n      source = yield* deps.analyzeEffectExpression(propAccess.getExpression(), sourceFile, filePath, opts, warnings, stats);\n      if (args.length > 0 && args[0]) {\n        handler = yield* deps.analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats);\n      }\n    } else if (args.length > 0 && args[0]) {\n      source = yield* deps.analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats);\n      if (args.length > 1 && args[1]) {\n        handler = yield* deps.analyzeEffectExpression(args[1], sourceFile, filePath, opts, warnings, stats);\n      }\n    }\n\n    stats.interruptionCount++;\n\n    const interruptionNode: StaticInterruptionNode = {\n      id: generateId(),\n      type: 'interruption',\n      interruptionType,\n      source,\n      handler,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...interruptionNode,\n      displayName: computeDisplayName(interruptionNode),\n      semanticRole: computeSemanticRole(interruptionNode),\n    };\n  });\n}\n","/**\n * Parallel and Race call analyzers (Effect.all, Effect.allPar, Effect.race, ...).\n *\n * Both recurse via `deps.analyzeEffectExpression` into each branch / child effect.\n *\n * Extracted from effect-analysis.ts via the strangler-fig DI pattern.\n * Behaviour is preserved exactly.\n */\n\nimport { Effect } from 'effect';\nimport type {\n  CallExpression,\n  SourceFile,\n  ArrayLiteralExpression,\n  ObjectLiteralExpression,\n  PropertyAssignment,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  StaticFlowNode,\n  StaticParallelNode,\n  StaticRaceNode,\n  ConcurrencyMode,\n  AnalyzerOptions,\n  AnalysisWarning,\n  AnalysisStats,\n  AnalysisError,\n} from './types';\nimport {\n  generateId,\n  extractLocation,\n  computeDisplayName,\n  computeSemanticRole,\n} from './analysis-utils';\nimport { parseEffectAllOptions } from './analysis-classifiers';\nimport type { AnalysisContext } from './analysis-context';\n\nexport const analyzeParallelCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>,\n): Effect.Effect<StaticParallelNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n    const children: StaticFlowNode[] = [];\n    const { SyntaxKind } = loadTsMorph();\n\n    // First argument: array of effects or object with effect properties\n    if (args.length > 0 && args[0]) {\n      const firstArg = args[0];\n\n      if (firstArg.getKind() === SyntaxKind.ArrayLiteralExpression) {\n        const elements = (firstArg as ArrayLiteralExpression).getElements();\n        for (const elem of elements) {\n          const analyzed = yield* deps.analyzeEffectExpression(\n            elem,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n            serviceScope,\n          );\n          children.push(analyzed);\n        }\n      } else if (firstArg.getKind() === SyntaxKind.ObjectLiteralExpression) {\n        const props = (firstArg as ObjectLiteralExpression).getProperties();\n        for (const prop of props) {\n          if (prop.getKind() === SyntaxKind.PropertyAssignment) {\n            const initializer = (prop as PropertyAssignment).getInitializer();\n            if (initializer) {\n              const analyzed = yield* deps.analyzeEffectExpression(\n                initializer,\n                sourceFile,\n                filePath,\n                opts,\n                warnings,\n                stats,\n                serviceScope,\n              );\n              children.push(analyzed);\n            }\n          }\n        }\n      }\n    }\n\n    // Second argument: options { concurrency, batching, discard } (GAP 18)\n    let concurrency: ConcurrencyMode | undefined;\n    let batching: boolean | undefined;\n    let discard: boolean | undefined;\n    if (args.length > 1 && args[1]?.getKind() === SyntaxKind.ObjectLiteralExpression) {\n      const parsed = parseEffectAllOptions(args[1] as ObjectLiteralExpression);\n      concurrency = parsed.concurrency;\n      batching = parsed.batching;\n      discard = parsed.discard;\n    }\n\n    const mode = callee.includes('Par') ? 'parallel' : 'sequential';\n    if (concurrency === undefined) {\n      concurrency = mode === 'parallel' ? 'unbounded' : 'sequential';\n    }\n\n    stats.parallelCount++;\n\n    const branchLabels = children.map((child) => computeDisplayName(child));\n    const parallelNode: StaticParallelNode = {\n      id: generateId(),\n      type: 'parallel',\n      callee,\n      mode,\n      children,\n      concurrency,\n      batching,\n      discard,\n      branchLabels,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...parallelNode,\n      displayName: computeDisplayName(parallelNode),\n      semanticRole: computeSemanticRole(parallelNode),\n    };\n  });\n\nexport const analyzeRaceCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticRaceNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n    const children: StaticFlowNode[] = [];\n\n    for (const arg of args) {\n      if (arg) {\n        const analyzed = yield* deps.analyzeEffectExpression(\n          arg,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n        children.push(analyzed);\n      }\n    }\n\n    stats.raceCount++;\n\n    const raceLabels = children.map((child) => computeDisplayName(child));\n    const raceNode: StaticRaceNode = {\n      id: generateId(),\n      type: 'race',\n      callee,\n      children,\n      raceLabels,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...raceNode,\n      displayName: computeDisplayName(raceNode),\n      semanticRole: computeSemanticRole(raceNode),\n    };\n  });\n","/**\n * Error-handler call analyzer (catch/catchTag/catchTags/orElse/orDie/match/...).\n *\n * Recurses via `deps.analyzeEffectExpression` into the source effect and the\n * handler. Tag/tags extraction reads the first/handler argument literally.\n *\n * Extracted from effect-analysis.ts via the strangler-fig DI pattern.\n * Behaviour is preserved exactly.\n */\n\nimport { Effect } from 'effect';\nimport type {\n  CallExpression,\n  SourceFile,\n  PropertyAccessExpression,\n  StringLiteral,\n  ObjectLiteralExpression,\n  PropertyAssignment,\n  MethodDeclaration,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  StaticFlowNode,\n  StaticErrorHandlerNode,\n  AnalyzerOptions,\n  AnalysisWarning,\n  AnalysisStats,\n  AnalysisError,\n} from './types';\nimport {\n  generateId,\n  extractLocation,\n  computeDisplayName,\n  computeSemanticRole,\n} from './analysis-utils';\nimport type { AnalysisContext } from './analysis-context';\n\n/**\n * Which handler a callee names. Ordered longest-first: the chain is substring\n * based, so `catchReason` must be tested before `catchCause` and `catch`, or\n * Effect 4's selective catches all read as catch-everything.\n */\nexport const classifyErrorHandlerName = (\n  callee: string,\n): StaticErrorHandlerNode['handlerType'] => {\n  if (callee.includes('catchCauseFilter')) {\n    return 'catchCauseFilter';\n  }\n  if (callee.includes('catchCauseIf')) {\n    return 'catchCauseIf';\n  }\n  if (callee.includes('catchNoSuchElement')) {\n    return 'catchNoSuchElement';\n  }\n  if (callee.includes('catchReasons')) {\n    return 'catchReasons';\n  }\n  if (callee.includes('catchReason')) {\n    return 'catchReason';\n  }\n  if (callee.includes('catchFilter')) {\n    return 'catchFilter';\n  }\n  if (callee.includes('catchEager')) {\n    return 'catchEager';\n  }\n  if (callee.includes('catchCause')) {\n    return 'catchCause';\n  }\n  if (callee.includes('catchSomeCause')) {\n    return 'catchSomeCause';\n  }\n  if (callee.includes('catchSomeDefect')) {\n    return 'catchSomeDefect';\n  }\n  if (callee.includes('catchDefect')) {\n    return 'catchDefect';\n  }\n  if (callee.includes('catchTags')) {\n    return 'catchTags';\n  }\n  if (callee.includes('catchIf')) {\n    return 'catchIf';\n  }\n  if (callee.includes('catchSome')) {\n    return 'catchSome';\n  }\n  if (callee.includes('catchTag')) {\n    return 'catchTag';\n  }\n  if (callee.includes('catch')) {\n    return 'catch';\n  }\n  if (callee.includes('orElseFail')) {\n    return 'orElseFail';\n  }\n  if (callee.includes('orElseSucceed')) {\n    return 'orElseSucceed';\n  }\n  if (callee.includes('orElse')) {\n    return 'orElse';\n  }\n  if (callee.includes('orDieWith')) {\n    return 'orDieWith';\n  }\n  if (callee.includes('orDie')) {\n    return 'orDie';\n  }\n  if (callee.includes('flip')) {\n    return 'flip';\n  }\n  if (callee.includes('mapErrorCause')) {\n    return 'mapErrorCause';\n  }\n  if (callee.includes('mapBoth')) {\n    return 'mapBoth';\n  }\n  if (callee.includes('mapError')) {\n    return 'mapError';\n  }\n  if (callee.includes('unsandbox')) {\n    return 'unsandbox';\n  }\n  if (callee.includes('sandbox')) {\n    return 'sandbox';\n  }\n  if (callee.includes('parallelErrors')) {\n    return 'parallelErrors';\n  }\n  if (callee.includes('filterOrDieMessage')) {\n    return 'filterOrDieMessage';\n  }\n  if (callee.includes('filterOrDie')) {\n    return 'filterOrDie';\n  }\n  if (callee.includes('filterOrElse')) {\n    return 'filterOrElse';\n  }\n  if (callee.includes('filterOrFail')) {\n    return 'filterOrFail';\n  }\n  if (callee.includes('matchCauseEffect')) {\n    return 'matchCauseEffect';\n  }\n  if (callee.includes('matchCause')) {\n    return 'matchCause';\n  }\n  if (callee.includes('matchEffect')) {\n    return 'matchEffect';\n  }\n  if (callee.includes('match')) {\n    return 'match';\n  }\n  if (callee.includes('firstSuccessOf')) {\n    return 'firstSuccessOf';\n  }\n  if (callee.includes('ignoreLogged')) {\n    return 'ignoreLogged';\n  }\n  if (callee.includes('ignore')) {\n    return 'ignore';\n  }\n  if (callee.includes('eventually')) {\n    return 'eventually';\n  }\n  return 'catch';\n};\n\nexport const analyzeErrorHandlerCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticErrorHandlerNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n\n    const handlerType = classifyErrorHandlerName(callee);\n\n    // For methods that are called as effect.pipe(Effect.catch(handler))\n    // we need to find the source effect differently\n    let source: StaticFlowNode;\n    let handler: StaticFlowNode | undefined;\n\n    // Check if this is a method call on an effect (e.g., effect.catch(fn))\n    const expr = call.getExpression();\n    if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n      // This is effect.method() - the source is the object of the property access\n      const propAccess = expr as PropertyAccessExpression;\n      const exprSource = propAccess.getExpression();\n      source = yield* deps.analyzeEffectExpression(\n        exprSource,\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n\n      // Handler is the first argument\n      if (args.length > 0 && args[0]) {\n        handler = yield* deps.analyzeEffectExpression(\n          args[0],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      }\n    } else {\n      // This is Effect.method(effect, handler) - effect is first argument\n      if (args.length > 0 && args[0]) {\n        source = yield* deps.analyzeEffectExpression(\n          args[0],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      } else {\n        source = {\n          id: generateId(),\n          type: 'unknown',\n          reason: 'Could not determine source effect',\n        };\n      }\n\n      if (args.length > 1 && args[1]) {\n        handler = yield* deps.analyzeEffectExpression(\n          args[1],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      }\n    }\n\n    stats.errorHandlerCount++;\n\n    // For catchTags (object form), extract the tag keys from the object literal\n    let errorTag: string | undefined;\n    let errorTags: readonly string[] | undefined;\n    if (handlerType === 'catchTag') {\n      // catchTag(\"TagName\", handler) — first arg is the tag string\n      const tagArg = args[0];\n      if (tagArg?.getKind() === loadTsMorph().SyntaxKind.StringLiteral) {\n        errorTag = (tagArg as StringLiteral).getLiteralValue();\n      }\n    } else if (handlerType === 'catchTags') {\n      // catchTags({ NotFound: handler, DatabaseError: handler })\n      // Find the object literal arg (may be args[0] for Effect.catchTags(eff, obj) or handler arg)\n      const objArg = [...args].find(\n        (a) => a?.getKind() === loadTsMorph().SyntaxKind.ObjectLiteralExpression,\n      );\n      if (objArg !== undefined) {\n        const props = (objArg as ObjectLiteralExpression).getProperties();\n        errorTags = props\n          .filter(\n            (p) =>\n              p.getKind() === loadTsMorph().SyntaxKind.PropertyAssignment ||\n              p.getKind() === loadTsMorph().SyntaxKind.MethodDeclaration,\n          )\n          .map((p) => {\n            if (p.getKind() === loadTsMorph().SyntaxKind.PropertyAssignment) {\n              return (p as PropertyAssignment).getName();\n            }\n            return (p as MethodDeclaration).getName();\n          });\n      }\n    }\n\n    const handlerNode: StaticErrorHandlerNode = {\n      id: generateId(),\n      type: 'error-handler',\n      handlerType,\n      source,\n      handler,\n      errorTag,\n      errorTags,\n      errorEdgeLabel: errorTag\n        ? `on ${errorTag}`\n        : errorTags && errorTags.length > 0\n          ? `on ${errorTags.join(' | ')}`\n          : 'on error',\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...handlerNode,\n      displayName: computeDisplayName(handlerNode),\n      semanticRole: computeSemanticRole(handlerNode),\n    };\n  });\n","/**\n * Resource (acquire/release) call analyzer.\n *\n * Covers Effect.acquireRelease, acquireUseRelease, ensuring, onExit, addFinalizer\n * and related scoped resource patterns. Recurses via `deps.analyzeEffectExpression`\n * for each effect argument.\n *\n * Extracted from effect-analysis.ts via the strangler-fig DI pattern.\n * Behaviour is preserved exactly.\n */\n\nimport { Effect } from 'effect';\nimport type {\n  CallExpression,\n  SourceFile,\n  PropertyAccessExpression,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  StaticFlowNode,\n  StaticResourceNode,\n  AnalyzerOptions,\n  AnalysisWarning,\n  AnalysisStats,\n  AnalysisError,\n} from './types';\nimport {\n  generateId,\n  extractLocation,\n  computeDisplayName,\n  computeSemanticRole,\n} from './analysis-utils';\nimport type { AnalysisContext } from './analysis-context';\n\nexport const analyzeResourceCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticResourceNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n    const resourceOperation = (/([A-Za-z_$][\\w$]*)$/.exec(callee))?.[1] ?? callee;\n    let acquire: StaticFlowNode;\n    let release: StaticFlowNode;\n    let useEffect: StaticFlowNode | undefined;\n\n    if (resourceOperation.startsWith('acquireUseRelease')) {\n      // acquireUseRelease / acquireUseReleaseInterruptible (acquire, use, release) - 3-arg form\n      if (args.length >= 3 && args[0] && args[2]) {\n        acquire = yield* deps.analyzeEffectExpression(\n          args[0],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n        release = yield* deps.analyzeEffectExpression(\n          args[2],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n        if (args[1]) {\n          useEffect = yield* deps.analyzeEffectExpression(\n            args[1],\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n          );\n        }\n      } else {\n        acquire = { id: generateId(), type: 'unknown', reason: 'Missing acquire' };\n        release = { id: generateId(), type: 'unknown', reason: 'Missing release' };\n      }\n    } else if (resourceOperation.startsWith('acquireRelease')) {\n      // acquireRelease / acquireReleaseInterruptible (acquire, release) - 2-arg form\n      if (args.length >= 2 && args[0] && args[1]) {\n        acquire = yield* deps.analyzeEffectExpression(\n          args[0],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n        release = yield* deps.analyzeEffectExpression(\n          args[1],\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      } else {\n        acquire = {\n          id: generateId(),\n          type: 'unknown',\n          reason: 'Missing acquire',\n        };\n        release = {\n          id: generateId(),\n          type: 'unknown',\n          reason: 'Missing release',\n        };\n      }\n    } else if (\n      resourceOperation === 'addFinalizer' ||\n      resourceOperation === 'onExit' ||\n      resourceOperation === 'onError' ||\n      resourceOperation === 'parallelFinalizers' ||\n      resourceOperation === 'sequentialFinalizers' ||\n      resourceOperation === 'finalizersMask' ||\n      resourceOperation === 'using' ||\n      resourceOperation === 'withEarlyRelease'\n    ) {\n      // Finalizer/cleanup patterns - acquire is the surrounding effect (method chain) or unknown\n      const expr = call.getExpression();\n      if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n        const propAccess = expr as PropertyAccessExpression;\n        acquire = yield* deps.analyzeEffectExpression(\n          propAccess.getExpression(),\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      } else {\n        acquire = { id: generateId(), type: 'unknown', reason: 'Scoped acquire' };\n      }\n      release =\n        args.length > 0 && args[0]\n          ? yield* deps.analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats)\n          : { id: generateId(), type: 'unknown', reason: 'Missing finalizer' };\n    } else if (resourceOperation === 'ensuring') {\n      // Effect.ensuring(effect, cleanup)\n      const expr = call.getExpression();\n      if (\n        expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression\n      ) {\n        const propAccess = expr as PropertyAccessExpression;\n        const exprSource = propAccess.getExpression();\n        acquire = yield* deps.analyzeEffectExpression(\n          exprSource,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n        release =\n          args.length > 0 && args[0]\n            ? yield* deps.analyzeEffectExpression(\n                args[0],\n                sourceFile,\n                filePath,\n                opts,\n                warnings,\n                stats,\n              )\n            : { id: generateId(), type: 'unknown', reason: 'Missing cleanup' };\n      } else {\n        acquire =\n          args.length > 0 && args[0]\n            ? yield* deps.analyzeEffectExpression(\n                args[0],\n                sourceFile,\n                filePath,\n                opts,\n                warnings,\n                stats,\n              )\n            : { id: generateId(), type: 'unknown', reason: 'Missing effect' };\n        release =\n          args.length > 1 && args[1]\n            ? yield* deps.analyzeEffectExpression(\n                args[1],\n                sourceFile,\n                filePath,\n                opts,\n                warnings,\n                stats,\n              )\n            : { id: generateId(), type: 'unknown', reason: 'Missing cleanup' };\n      }\n    } else {\n      acquire = {\n        id: generateId(),\n        type: 'unknown',\n        reason: 'Unknown resource pattern',\n      };\n      release = {\n        id: generateId(),\n        type: 'unknown',\n        reason: 'Unknown resource pattern',\n      };\n    }\n\n    stats.resourceCount++;\n\n    const resourceNode: StaticResourceNode = {\n      id: generateId(),\n      type: 'resource',\n      acquire,\n      release,\n      use: useEffect,\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...resourceNode,\n      displayName: computeDisplayName(resourceNode),\n      semanticRole: computeSemanticRole(resourceNode),\n    };\n  });\n","/**\n * Control-flow call analyzers: conditional, loop, match, cause, exit, transform.\n *\n * Each takes `deps.analyzeEffectExpression` so it can recurse into branches /\n * bodies / handlers / sources without depending on the parent module.\n *\n * Extracted from effect-analysis.ts via the strangler-fig DI pattern.\n * Behaviour is preserved exactly.\n */\n\nimport { Effect } from 'effect';\nimport type {\n  CallExpression,\n  SourceFile,\n  PropertyAccessExpression,\n  ObjectLiteralExpression,\n  PropertyAssignment,\n  ArrowFunction,\n  FunctionExpression,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n  StaticFlowNode,\n  StaticConditionalNode,\n  StaticLoopNode,\n  StaticMatchNode,\n  StaticCauseNode,\n  StaticExitNode,\n  StaticTransformNode,\n  AnalyzerOptions,\n  AnalysisWarning,\n  AnalysisStats,\n  AnalysisError,\n} from './types';\nimport {\n  generateId,\n  extractLocation,\n  computeDisplayName,\n  computeSemanticRole,\n} from './analysis-utils';\nimport {\n  MATCH_OP_MAP,\n  EXHAUSTIVE_OPS,\n  CAUSE_OP_MAP,\n  CAUSE_CONSTRUCTORS,\n  EXIT_OP_MAP,\n  EXIT_CONSTRUCTORS,\n  TRANSFORM_OPS,\n  EFFECTFUL_TRANSFORMS,\n} from './analysis-patterns';\nimport {\n  buildCallbackSummaryNodes,\n  buildPureCallbackSummaryNodes,\n  summarizeLoopCallbackSource,\n} from './callback-summary';\nimport type { AnalysisContext } from './analysis-context';\n\nexport const analyzeConditionalCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticConditionalNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n\n    let conditionalType: StaticConditionalNode['conditionalType'];\n    if (callee.includes('.if') || callee === 'if') {\n      conditionalType = 'if';\n    } else if (callee.includes('whenEffect')) {\n      conditionalType = 'whenEffect';\n    } else if (callee.includes('whenFiberRef')) {\n      conditionalType = 'whenFiberRef';\n    } else if (callee.includes('whenRef')) {\n      conditionalType = 'whenRef';\n    } else if (callee.includes('.when') || callee === 'when') {\n      conditionalType = 'when';\n    } else if (callee.includes('unlessEffect')) {\n      conditionalType = 'unlessEffect';\n    } else if (callee.includes('.unless') || callee === 'unless') {\n      conditionalType = 'unless';\n    } else if (callee.includes('.option') || callee === 'option') {\n      conditionalType = 'option';\n    } else if (callee.includes('.either') || callee === 'either') {\n      conditionalType = 'either';\n    } else if (callee.includes('.exit') || callee === 'exit') {\n      conditionalType = 'exit';\n    } else if (callee.includes('liftPredicate')) {\n      conditionalType = 'liftPredicate';\n    } else {\n      conditionalType = 'unless';\n    }\n\n    let condition = '<dynamic>';\n    let onTrue: StaticFlowNode | undefined;\n    let onFalse: StaticFlowNode | undefined;\n\n    // Different call patterns for if vs when/unless\n    if (conditionalType === 'if') {\n      // Effect.if(condition, { onTrue, onFalse })\n      if (args.length > 0 && args[0]) {\n        condition = args[0].getText();\n      }\n\n      if (args.length > 1 && args[1]) {\n        const secondArg = args[1];\n        const { SyntaxKind } = loadTsMorph();\n\n        if (secondArg.getKind() === SyntaxKind.ObjectLiteralExpression) {\n          const props = (secondArg as ObjectLiteralExpression).getProperties();\n          for (const prop of props) {\n            if (prop.getKind() === SyntaxKind.PropertyAssignment) {\n              const propAssign = prop as PropertyAssignment;\n              const name = propAssign.getName();\n              const init = propAssign.getInitializer();\n\n              if (init) {\n                if (name === 'onTrue') {\n                  onTrue = yield* deps.analyzeEffectExpression(\n                    init,\n                    sourceFile,\n                    filePath,\n                    opts,\n                    warnings,\n                    stats,\n                  );\n                } else if (name === 'onFalse') {\n                  onFalse = yield* deps.analyzeEffectExpression(\n                    init,\n                    sourceFile,\n                    filePath,\n                    opts,\n                    warnings,\n                    stats,\n                  );\n                }\n              }\n            }\n          }\n        }\n      }\n    } else {\n      // when/unless: effect.pipe(Effect.when(condition))\n      const expr = call.getExpression();\n      if (\n        expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression\n      ) {\n        const propAccess = expr as PropertyAccessExpression;\n        const exprSource = propAccess.getExpression();\n\n        // The source effect is the object being piped\n        if (!onTrue) {\n          onTrue = yield* deps.analyzeEffectExpression(\n            exprSource,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n          );\n        }\n      }\n\n      if (args.length > 0 && args[0]) {\n        condition = args[0].getText();\n      }\n    }\n\n    if (!onTrue) {\n      onTrue = {\n        id: generateId(),\n        type: 'unknown',\n        reason: 'Could not determine true branch',\n      };\n    }\n\n    stats.conditionalCount++;\n\n    const truncatedCondition = condition.length <= 30 ? condition : `${condition.slice(0, 30)}…`;\n    const conditionalNode: StaticConditionalNode = {\n      id: generateId(),\n      type: 'conditional',\n      conditionalType,\n      condition,\n      onTrue,\n      onFalse,\n      conditionLabel: truncatedCondition,\n      trueEdgeLabel: 'true',\n      falseEdgeLabel: 'false',\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...conditionalNode,\n      displayName: computeDisplayName(conditionalNode),\n      semanticRole: computeSemanticRole(conditionalNode),\n    };\n  });\n\nexport const analyzeLoopCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticLoopNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n    const { SyntaxKind } = loadTsMorph();\n\n    const loopType: StaticLoopNode['loopType'] =\n      callee.includes('forEach') ? 'forEach' :\n      callee.includes('filterMap') ? 'filterMap' :\n      callee.includes('filter') ? 'filter' :\n      callee.includes('partition') ? 'partition' :\n      callee.includes('reduce') ? 'reduce' :\n      callee.includes('validateAll') || callee.includes('validateFirst') || callee.includes('validateWith') ? 'validate' :\n      callee.includes('replicate') ? 'replicate' :\n      callee.includes('dropUntil') ? 'dropUntil' :\n      callee.includes('dropWhile') ? 'dropWhile' :\n      callee.includes('takeUntil') ? 'takeUntil' :\n      callee.includes('takeWhile') ? 'takeWhile' :\n      callee.includes('every') ? 'every' :\n      callee.includes('exists') ? 'exists' :\n      callee.includes('findFirst') ? 'findFirst' :\n      callee.includes('head') ? 'head' :\n      callee.includes('mergeAll') ? 'mergeAll' :\n      'loop';\n\n    // reduce/reduceRight/reduceEffect(iterable, initial, reducer) use body at index 2;\n    // others (forEach, filter, ...) at index 1\n    const bodyArgIndex =\n      loopType === 'reduce' ||\n      callee.includes('reduceRight') ||\n      callee.includes('reduceWhile') ||\n      callee.includes('reduceEffect')\n        ? (args.length >= 3 ? 2 : 1)\n        : 1;\n\n    let iterSource: string | undefined;\n    let body: StaticFlowNode;\n    let callbackBody: readonly StaticFlowNode[] | undefined;\n\n    if (args.length > 0 && args[0]) {\n      const rawSource = args[0].getText();\n      iterSource = rawSource.length > 30 ? rawSource.slice(0, 30) + '…' : rawSource;\n    }\n\n    if (args.length > bodyArgIndex && args[bodyArgIndex]) {\n      const bodyArg = args[bodyArgIndex];\n      const isFn =\n        bodyArg.getKind() === SyntaxKind.ArrowFunction ||\n        bodyArg.getKind() === SyntaxKind.FunctionExpression;\n      if (isFn) {\n        const fn = bodyArg as ArrowFunction | FunctionExpression;\n        const effectfulSummary = buildCallbackSummaryNodes(\n          fn,\n          filePath,\n          opts.includeLocations ?? false,\n        );\n        const pureSummary = buildPureCallbackSummaryNodes(\n          fn,\n          filePath,\n          opts.includeLocations ?? false,\n        );\n        callbackBody = effectfulSummary ?? pureSummary;\n        body =\n          callbackBody?.length === 1\n            ? callbackBody[0]!\n            : {\n                id: generateId(),\n                type: 'opaque',\n                reason: 'callback-body',\n                sourceText: summarizeLoopCallbackSource(loopType, callbackBody ?? []),\n                location: extractLocation(bodyArg, filePath, opts.includeLocations ?? false),\n              };\n      } else {\n        body = yield* deps.analyzeEffectExpression(\n          bodyArg,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n        );\n      }\n    } else {\n      const predicateArg = args[0];\n      const predicateLikeLoop =\n        loopType === 'exists' ||\n        loopType === 'every' ||\n        loopType === 'findFirst' ||\n        loopType === 'head';\n      if (predicateLikeLoop && predicateArg) {\n        body = {\n          id: generateId(),\n          type: 'opaque',\n          reason: 'predicate',\n          sourceText: predicateArg.getText().slice(0, 100),\n          location: extractLocation(predicateArg, filePath, opts.includeLocations ?? false),\n        };\n      } else {\n        body = {\n          id: generateId(),\n          type: 'unknown',\n          reason: 'Could not determine loop body',\n        };\n      }\n    }\n\n    stats.loopCount++;\n\n    const loopNode: StaticLoopNode = {\n      id: generateId(),\n      type: 'loop',\n      loopType,\n      iterSource,\n      body,\n      ...(callbackBody ? { callbackBody } : {}),\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...loopNode,\n      displayName: computeDisplayName(loopNode),\n      semanticRole: computeSemanticRole(loopNode),\n    };\n  });\n\n/** Analyze Match.type / Match.when / Match.tag / Match.exhaustive etc. */\nexport const analyzeMatchCall = (\n  call: CallExpression,\n  callee: string,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n): StaticMatchNode => {\n  const matchOp: StaticMatchNode['matchOp'] = MATCH_OP_MAP[callee] ?? 'other';\n  const isExhaustive = EXHAUSTIVE_OPS.has(matchOp);\n\n  // Extract tag names for Match.tag(tag, fn), Match.tags({ tag1: fn, tag2: fn })\n  const args = call.getArguments();\n  const matchedTags: string[] = [];\n  if ((matchOp === 'when' || matchOp === 'tag') && args[0]) {\n    const arg0 = args[0].getText().replace(/[\"'`]/g, '').trim();\n    if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(arg0)) matchedTags.push(arg0);\n  }\n  if (matchOp === 'tags' || matchOp === 'tagsExhaustive') {\n    const { SyntaxKind } = loadTsMorph();\n    for (const arg of args) {\n      if (arg.getKind() === SyntaxKind.ObjectLiteralExpression) {\n        const obj = arg as ObjectLiteralExpression;\n        for (const prop of obj.getProperties()) {\n          const name = prop.getKind() === SyntaxKind.PropertyAssignment\n            ? (prop as PropertyAssignment).getName()\n            : undefined;\n          if (name) matchedTags.push(name.replace(/[\"'`]/g, ''));\n        }\n      }\n    }\n  }\n\n  const matchNode: StaticMatchNode = {\n    id: generateId(),\n    type: 'match',\n    matchOp,\n    isExhaustive,\n    ...(matchedTags.length > 0 ? { matchedTags } : {}),\n    location: extractLocation(call, filePath, opts.includeLocations ?? false),\n  };\n  return {\n    ...matchNode,\n    displayName: computeDisplayName(matchNode),\n    semanticRole: computeSemanticRole(matchNode),\n  };\n};\n\n/** Analyze Cause.fail / die / interrupt / parallel / sequential / failures / etc. */\nexport const analyzeCauseCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticCauseNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const causeOp: StaticCauseNode['causeOp'] = CAUSE_OP_MAP[callee] ?? 'other';\n    const isConstructor = CAUSE_CONSTRUCTORS.has(causeOp);\n    let children: readonly StaticFlowNode[] | undefined;\n    if (causeOp === 'parallel' || causeOp === 'sequential') {\n      const args = call.getArguments();\n      const childNodes: StaticFlowNode[] = [];\n      for (const arg of args) {\n        if (arg) {\n          const child = yield* deps.analyzeEffectExpression(\n            arg,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            stats,\n          );\n          childNodes.push(child);\n        }\n      }\n      if (childNodes.length > 0) children = childNodes;\n    }\n    // Determine causeKind\n    let causeKind: StaticCauseNode['causeKind'];\n    if (causeOp === 'fail') causeKind = 'fail';\n    else if (causeOp === 'die') causeKind = 'die';\n    else if (causeOp === 'interrupt') causeKind = 'interrupt';\n    else if ((causeOp === 'parallel' || causeOp === 'sequential') && children && children.length > 0) {\n      const childKinds = children\n        .filter((c): c is StaticCauseNode => c.type === 'cause')\n        .map((c) => c.causeKind)\n        .filter((k): k is NonNullable<typeof k> => k !== undefined);\n      if (childKinds.length > 0) {\n        causeKind = childKinds.every((k) => k === childKinds[0]) ? childKinds[0] : 'mixed';\n      }\n    }\n\n    const causeNode: StaticCauseNode = {\n      id: generateId(),\n      type: 'cause',\n      causeOp,\n      isConstructor,\n      ...(children ? { children } : {}),\n      ...(causeKind ? { causeKind } : {}),\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...causeNode,\n      displayName: computeDisplayName(causeNode),\n      semanticRole: computeSemanticRole(causeNode),\n    };\n  });\n\n/** Analyze Exit.succeed / fail / die / interrupt / match / isSuccess / etc. */\nexport const analyzeExitCall = (\n  call: CallExpression,\n  callee: string,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n): StaticExitNode => {\n  const exitOp: StaticExitNode['exitOp'] = EXIT_OP_MAP[callee] ?? 'other';\n  const isConstructor = EXIT_CONSTRUCTORS.has(exitOp);\n  const exitNode: StaticExitNode = {\n    id: generateId(),\n    type: 'exit',\n    exitOp,\n    isConstructor,\n    location: extractLocation(call, filePath, opts.includeLocations ?? false),\n  };\n  return {\n    ...exitNode,\n    displayName: computeDisplayName(exitNode),\n    semanticRole: computeSemanticRole(exitNode),\n  };\n};\n\n/** Analyze Effect.map / flatMap / andThen / tap / zip / as / flatten etc. */\nexport const analyzeTransformCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: AnalysisWarning[],\n  stats: AnalysisStats,\n): Effect.Effect<StaticTransformNode, AnalysisError> =>\n  Effect.gen(function* () {\n    const args = call.getArguments();\n    const transformType: StaticTransformNode['transformType'] =\n      TRANSFORM_OPS[callee] ?? 'other';\n    const isEffectful = EFFECTFUL_TRANSFORMS.has(transformType);\n\n    // For data-last forms (2 args), first arg is the source\n    // For curried forms (1 arg), the source is from the outer pipe\n    let source: StaticFlowNode | undefined;\n    let fn: string | undefined;\n\n    if (args.length >= 2 && args[0]) {\n      source = yield* deps.analyzeEffectExpression(\n        args[0],\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats,\n      );\n      if (args[1]) {\n        const fnText = args[1].getText();\n        fn = fnText.length <= 120 ? fnText : fnText.slice(0, 120) + '…';\n      }\n    } else if (args.length === 1 && args[0]) {\n      // Curried - single arg is the function\n      const fnText = args[0].getText();\n      fn = fnText.length <= 120 ? fnText : fnText.slice(0, 120) + '…';\n    }\n\n    stats.totalEffects++;\n\n    const transformNode: StaticTransformNode = {\n      id: generateId(),\n      type: 'transform',\n      transformType,\n      isEffectful,\n      ...(source !== undefined ? { source } : {}),\n      ...(fn !== undefined ? { fn } : {}),\n      location: extractLocation(call, filePath, opts.includeLocations ?? false),\n    };\n    return {\n      ...transformNode,\n      displayName: computeDisplayName(transformNode),\n      semanticRole: computeSemanticRole(transformNode),\n    } satisfies StaticTransformNode;\n  });\n","/**\n * Strict Mode Diagnostics for Effect IR\n *\n * Validates Effect programs against strict rules: error type declarations,\n * parallel/race error handling, and optional labelling.\n */\n\nimport type {\n  StaticEffectIR,\n  StaticFlowNode,\n  StaticEffectNode,\n  SourceLocation,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\nimport { buildLayerDependencyGraph } from './layer-graph';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface StrictDiagnostic {\n  rule: StrictRule;\n  severity: 'error' | 'warning';\n  message: string;\n  fix?: string | undefined;\n  location?: SourceLocation | undefined;\n  nodeId?: string | undefined;\n}\n\nexport type StrictRule =\n  | 'missing-error-type'\n  | 'unknown-error-type'\n  | 'parallel-missing-errors'\n  | 'race-missing-errors'\n  | 'effect-without-handler'\n  | 'fiber-potential-leak'\n  | 'resource-missing-scope'\n  | 'unbounded-concurrency'\n  | 'unused-service'\n  | 'dead-code-path';\n\nexport interface StrictValidationResult {\n  valid: boolean;\n  diagnostics: StrictDiagnostic[];\n  errors: StrictDiagnostic[];\n  warnings: StrictDiagnostic[];\n}\n\nexport interface StrictValidationOptions {\n  /** Require effect nodes to have a declared error type (not unknown/never when they can fail) */\n  requireErrors?: boolean | undefined;\n  /** Require effects in parallel/race to have error type */\n  requireParallelErrors?: boolean | undefined;\n  warningsAsErrors?: boolean | undefined;\n}\n\nconst DEFAULT_OPTIONS: Required<\n  Omit<StrictValidationOptions, 'warningsAsErrors'>\n> & { warningsAsErrors: boolean } = {\n  requireErrors: true,\n  requireParallelErrors: true,\n  warningsAsErrors: false,\n};\n\n// =============================================================================\n// Validation\n// =============================================================================\n\nexport function validateStrict(\n  ir: StaticEffectIR,\n  options: StrictValidationOptions = {},\n): StrictValidationResult {\n  const opts = {\n    ...DEFAULT_OPTIONS,\n    ...options,\n    requireErrors: options.requireErrors ?? true,\n    requireParallelErrors: options.requireParallelErrors ?? true,\n    warningsAsErrors: options.warningsAsErrors ?? false,\n  };\n  const diagnostics: StrictDiagnostic[] = [];\n\n  validateNodes(ir.root.children, opts, diagnostics, false);\n\n  // Extended validators (Phase 9)\n  validateFiberLeaks(ir.root.children, diagnostics, new Set());\n  validateResourceScopes(ir.root.children, diagnostics, false);\n  validateConcurrencyBounds(ir.root.children, diagnostics);\n  validateDeadCodePaths(ir.root.children, diagnostics);\n  validateUnusedServices(ir, diagnostics);\n\n  const normalizeText = (text: string | undefined): string | undefined => {\n    if (text === undefined) return undefined;\n    const trimmed = text.trim();\n    return trimmed.length > 0 ? trimmed : undefined;\n  };\n  const normalizedDiagnostics = diagnostics.map((diagnostic): StrictDiagnostic => ({\n    ...diagnostic,\n    message: diagnostic.message.trim(),\n    fix: normalizeText(diagnostic.fix),\n  }));\n\n  const severityRank = (severity: StrictDiagnostic['severity']): number =>\n    severity === 'error' ? 0 : 1;\n  const canonicalDiagnostics = [...normalizedDiagnostics].sort((a, b) => {\n    const aPath = a.location?.filePath ?? '';\n    const bPath = b.location?.filePath ?? '';\n    if (aPath !== bPath) return aPath.localeCompare(bPath);\n    const aLine = a.location?.line ?? Number.MAX_SAFE_INTEGER;\n    const bLine = b.location?.line ?? Number.MAX_SAFE_INTEGER;\n    if (aLine !== bLine) return aLine - bLine;\n    const aCol = a.location?.column ?? Number.MAX_SAFE_INTEGER;\n    const bCol = b.location?.column ?? Number.MAX_SAFE_INTEGER;\n    if (aCol !== bCol) return aCol - bCol;\n    if (a.rule !== b.rule) return a.rule.localeCompare(b.rule);\n    const sevCmp = severityRank(a.severity) - severityRank(b.severity);\n    if (sevCmp !== 0) return sevCmp;\n    if ((a.fix ?? '') !== (b.fix ?? '')) return (a.fix ?? '').localeCompare(b.fix ?? '');\n    return a.message.localeCompare(b.message);\n  });\n  const dedupedDiagnostics: StrictDiagnostic[] = [];\n  const seen = new Set<string>();\n  for (const diagnostic of canonicalDiagnostics) {\n    const key = [\n      diagnostic.rule,\n      diagnostic.severity,\n      diagnostic.location?.filePath ?? '',\n      String(diagnostic.location?.line ?? ''),\n      String(diagnostic.location?.column ?? ''),\n      diagnostic.message,\n      diagnostic.fix ?? '',\n    ].join('|');\n    if (seen.has(key)) continue;\n    seen.add(key);\n    dedupedDiagnostics.push(diagnostic);\n  }\n\n  const errors = dedupedDiagnostics.filter(\n    (d) =>\n      d.severity === 'error' ||\n      (opts.warningsAsErrors && d.severity === 'warning'),\n  );\n  const warnings = dedupedDiagnostics.filter(\n    (d) => d.severity === 'warning' && !opts.warningsAsErrors,\n  );\n\n  return {\n    valid: errors.length === 0,\n    diagnostics: dedupedDiagnostics,\n    errors,\n    warnings,\n  };\n}\n\nfunction validateNodes(\n  nodes: readonly StaticFlowNode[],\n  opts: typeof DEFAULT_OPTIONS,\n  diagnostics: StrictDiagnostic[],\n  hasAncestorErrorHandler = false,\n): void {\n  for (const node of nodes) {\n    const currentHasErrorHandler =\n      hasAncestorErrorHandler || node.type === 'error-handler';\n\n    if (node.type === 'effect') {\n      const eff = node;\n      validateEffectNode(eff, opts, diagnostics);\n      // effect-without-handler: effect can fail but no handler on path from root\n      const errorType = eff.typeSignature?.errorType?.trim();\n      const canFail = errorType && errorType !== 'never';\n      if (canFail && !hasAncestorErrorHandler) {\n        diagnostics.push({\n          rule: 'effect-without-handler',\n          severity: 'warning',\n          message: `Effect \"${eff.callee}\" can fail with \"${errorType}\" but has no error handler (catch/catchTag/orElse) on this path`,\n          fix: 'Wrap in .pipe(Effect.catch(...)) or handle errors before this point',\n          location: eff.location,\n          nodeId: eff.id,\n        });\n      }\n    }\n    if (node.type === 'parallel' && opts.requireParallelErrors) {\n      for (const child of node.children) {\n        if (child.type === 'effect') {\n          const eff = child;\n          const errorType = eff.typeSignature?.errorType;\n          if (\n            !errorType ||\n            errorType === 'unknown' ||\n            errorType.trim() === ''\n          ) {\n            diagnostics.push({\n              rule: 'parallel-missing-errors',\n              severity: 'warning',\n              message: `Parallel branch effect \"${eff.callee}\" does not declare error type`,\n              fix: 'Add type signature or use Effect.mapError/catchTag to narrow errors',\n              location: eff.location,\n              nodeId: eff.id,\n            });\n          }\n        }\n      }\n    }\n    if (node.type === 'race' && opts.requireParallelErrors) {\n      for (const child of node.children) {\n        if (child.type === 'effect') {\n          const eff = child;\n          const errorType = eff.typeSignature?.errorType;\n          if (\n            !errorType ||\n            errorType === 'unknown' ||\n            errorType.trim() === ''\n          ) {\n            diagnostics.push({\n              rule: 'race-missing-errors',\n              severity: 'warning',\n              message: `Race branch effect \"${eff.callee}\" does not declare error type`,\n              fix: 'Add type signature or use Effect.mapError/catchTag to narrow errors',\n              location: eff.location,\n              nodeId: eff.id,\n            });\n          }\n        }\n      }\n    }\n\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) {\n      validateNodes(children, opts, diagnostics, currentHasErrorHandler);\n    }\n  }\n}\n\n// =============================================================================\n// Extended Rule Validators (Phase 9)\n// =============================================================================\n\n/**\n * Detect fiber forks without join/interrupt in scope.\n */\nfunction validateFiberLeaks(\n  nodes: readonly StaticFlowNode[],\n  diagnostics: StrictDiagnostic[],\n  joinPointsInScope: Set<string>,\n): void {\n  for (const node of nodes) {\n    if (node.type === 'fiber') {\n      const fiber = node;\n      if (\n        (fiber.operation === 'fork' || fiber.operation === 'forkAll') &&\n        !fiber.isScoped &&\n        !fiber.isDaemon\n      ) {\n        // Check if any join/interrupt exists in scope\n        if (!joinPointsInScope.has('join') && !joinPointsInScope.has('interrupt') && !joinPointsInScope.has('await')) {\n          diagnostics.push({\n            rule: 'fiber-potential-leak',\n            severity: 'warning',\n            message: `Fiber.${fiber.operation} without join/interrupt in scope — potential fiber leak`,\n            fix: 'Use Fiber.join, Fiber.interrupt, or forkScoped instead',\n            location: fiber.location,\n            nodeId: fiber.id,\n          });\n        }\n      }\n      // Track join points for scope\n      if (fiber.operation === 'join' || fiber.operation === 'interrupt' || fiber.operation === 'await') {\n        joinPointsInScope.add(fiber.operation);\n      }\n    }\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) {\n      validateFiberLeaks(children, diagnostics, joinPointsInScope);\n    }\n  }\n}\n\n/**\n * Detect resource acquisitions without proper scoping.\n */\nfunction validateResourceScopes(\n  nodes: readonly StaticFlowNode[],\n  diagnostics: StrictDiagnostic[],\n  inScope: boolean,\n): void {\n  for (const node of nodes) {\n    if (node.type === 'resource' && !inScope) {\n      diagnostics.push({\n        rule: 'resource-missing-scope',\n        severity: 'warning',\n        message: 'acquireRelease without visible Effect.scoped in scope',\n        fix: 'Wrap resource usage in Effect.scoped',\n        location: node.location,\n        nodeId: node.id,\n      });\n    }\n\n    // Track scope entry\n    const isScope = node.type === 'effect' && node.callee === 'Effect.scoped';\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) {\n      validateResourceScopes(children, diagnostics, inScope || isScope);\n    }\n  }\n}\n\n/**\n * Detect unbounded concurrency: Effect.all/forEach without concurrency option.\n */\nfunction validateConcurrencyBounds(\n  nodes: readonly StaticFlowNode[],\n  diagnostics: StrictDiagnostic[],\n): void {\n  for (const node of nodes) {\n    if (node.type === 'parallel' && node.children.length > 5) {\n      // Large parallel collections without explicit concurrency control\n      const callee = node.callee || '';\n      if (callee.includes('all') || callee.includes('forEach')) {\n        diagnostics.push({\n          rule: 'unbounded-concurrency',\n          severity: 'warning',\n          message: `${callee} with ${node.children.length} children — consider adding { concurrency } option`,\n          fix: 'Add { concurrency: N } to limit concurrent execution',\n          location: node.location,\n          nodeId: node.id,\n        });\n      }\n    }\n    if (node.type === 'loop' && (node.loopType === 'forEach' || node.loopType === 'validate')) {\n      // Large collection loops\n      diagnostics.push({\n        rule: 'unbounded-concurrency',\n        severity: 'warning',\n        message: `Effect.${node.loopType} may run unbounded — consider concurrency control`,\n        fix: 'Add { concurrency: N } option',\n        location: node.location,\n        nodeId: node.id,\n      });\n    }\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) {\n      validateConcurrencyBounds(children, diagnostics);\n    }\n  }\n}\n\n/**\n * Detect decision branches with const-resolvable conditions that always go one way.\n */\nfunction validateDeadCodePaths(\n  nodes: readonly StaticFlowNode[],\n  diagnostics: StrictDiagnostic[],\n): void {\n  for (const node of nodes) {\n    if (node.type === 'decision') {\n      const label = node.label.trim();\n      // If the label resolved to a literal boolean, it's a dead code path\n      if (label === 'true' || label === 'false') {\n        diagnostics.push({\n          rule: 'dead-code-path',\n          severity: 'warning',\n          message: `Decision \"${node.condition}\" always resolves to ${label} — ${label === 'true' ? 'false' : 'true'} branch is dead code`,\n          fix: 'Remove the dead branch or fix the condition',\n          location: node.location,\n          nodeId: node.id,\n        });\n      }\n    }\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) {\n      validateDeadCodePaths(children, diagnostics);\n    }\n  }\n}\n\n/**\n * Detect services provided by layers but never consumed by any effect.\n */\nfunction validateUnusedServices(\n  ir: StaticEffectIR,\n  diagnostics: StrictDiagnostic[],\n): void {\n  const layerGraph = buildLayerDependencyGraph(ir);\n  if (layerGraph.layers.length === 0) return;\n\n  // Collect all services that are consumed (required) by any layer\n  const consumedServices = new Set<string>();\n  for (const layer of layerGraph.layers) {\n    for (const req of layer.requires) {\n      consumedServices.add(req);\n    }\n  }\n\n  // Also collect services required by effects in the IR\n  collectConsumedServicesFromNodes(ir.root.children, consumedServices);\n\n  // Check which provided services are never consumed\n  for (const layer of layerGraph.layers) {\n    for (const svc of layer.provides) {\n      if (!consumedServices.has(svc)) {\n        diagnostics.push({\n          rule: 'unused-service',\n          severity: 'warning',\n          message: `Service \"${svc}\" is provided by layer \"${layer.name ?? layer.id}\" but never consumed`,\n          fix: 'Remove unused service provision or add a consumer',\n          nodeId: layer.id,\n        });\n      }\n    }\n  }\n}\n\nfunction collectConsumedServicesFromNodes(\n  nodes: readonly StaticFlowNode[],\n  consumed: Set<string>,\n): void {\n  for (const node of nodes) {\n    if (node.type === 'effect') {\n      const reqs = node.requiredServices ?? [];\n      for (const r of reqs) {\n        consumed.add(r.serviceId);\n      }\n    }\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) {\n      collectConsumedServicesFromNodes(children, consumed);\n    }\n  }\n}\n\nfunction validateEffectNode(\n  node: StaticEffectNode,\n  opts: typeof DEFAULT_OPTIONS,\n  diagnostics: StrictDiagnostic[],\n): void {\n  if (!opts.requireErrors) return;\n\n  const errorType = node.typeSignature?.errorType;\n  if (!errorType) {\n    diagnostics.push({\n      rule: 'missing-error-type',\n      severity: 'warning',\n      message: `Effect \"${node.callee}\" has no extracted error type`,\n      fix: 'Ensure type checker can infer Effect<A, E, R> or add explicit type',\n      location: node.location,\n      nodeId: node.id,\n    });\n    return;\n  }\n\n  const t = errorType.trim();\n  if (t === 'unknown') {\n    diagnostics.push({\n      rule: 'unknown-error-type',\n      severity: 'warning',\n      message: `Effect \"${node.callee}\" has error type \"unknown\"`,\n      fix: 'Use a concrete error type or branded errors for better validation',\n      location: node.location,\n      nodeId: node.id,\n    });\n  }\n}\n\n// =============================================================================\n// Formatting\n// =============================================================================\n\nexport function formatDiagnostics(result: StrictValidationResult): string {\n  const lines: string[] = [];\n\n  if (result.valid) {\n    lines.push('All strict mode checks passed');\n    if (result.warnings.length > 0) {\n      lines.push(\n        `  (${result.warnings.length} warning${result.warnings.length === 1 ? '' : 's'})`,\n      );\n    }\n  } else {\n    lines.push(\n      `Strict validation failed: ${result.errors.length} error(s)`,\n    );\n  }\n\n  lines.push('');\n\n  for (const diag of result.diagnostics) {\n    const icon = diag.severity === 'error' ? 'x' : '!';\n    const loc = diag.location\n      ? `:${diag.location.line}:${diag.location.column}`\n      : '';\n    lines.push(`[${icon}] [${diag.rule}]${loc}`);\n    lines.push(`  ${diag.message}`);\n    if (diag.fix) {\n      lines.push(`  Fix: ${diag.fix}`);\n    }\n    lines.push('');\n  }\n\n  return lines.join('\\n');\n}\n\nexport function formatDiagnosticsJSON(\n  result: StrictValidationResult,\n): string {\n  return JSON.stringify(\n    {\n      valid: result.valid,\n      errorCount: result.errors.length,\n      warningCount: result.warnings.length,\n      diagnostics: result.diagnostics.map((d) => ({\n        rule: d.rule,\n        severity: d.severity,\n        message: d.message,\n        fix: d.fix,\n        location: d.location\n          ? {\n              line: d.location.line,\n              column: d.location.column,\n            }\n          : undefined,\n        nodeId: d.nodeId,\n      })),\n    },\n    null,\n    2,\n  );\n}\n\nexport function getSummary(result: StrictValidationResult): string {\n  if (result.valid && result.warnings.length === 0) {\n    return 'All strict mode checks passed';\n  }\n  if (result.valid) {\n    return `Passed with ${result.warnings.length} warning(s)`;\n  }\n  return `${result.errors.length} error(s), ${result.warnings.length} warning(s)`;\n}\n","/**\n * Layer Dependency Graph (GAP 2)\n *\n * Collects StaticLayerNode from IR and builds a dependency graph\n * (provides, requires, merge/provide edges) for visualization.\n */\n\nimport type { StaticEffectIR, StaticFlowNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface LayerNodeInfo {\n  id: string;\n  name?: string;\n  provides: string[];\n  requires: string[];\n  lifecycle: string;\n  isMerged: boolean;\n  operationLayerIds: string[];\n}\n\nexport interface LayerGraphEdge {\n  from: string;\n  to: string;\n  kind: 'provides' | 'requires' | 'merge';\n}\n\nexport interface LayerDependencyGraph {\n  layers: LayerNodeInfo[];\n  edges: LayerGraphEdge[];\n  serviceToLayers: Map<string, string[]>;\n}\n\n// =============================================================================\n// Collection\n// =============================================================================\n\nfunction collectLayerNodes(\n  nodes: readonly StaticFlowNode[],\n  result: LayerNodeInfo[],\n): void {\n  for (const node of nodes) {\n    if (node.type === 'layer') {\n      const layer = node;\n      const info: LayerNodeInfo = {\n        id: layer.id,\n        provides: [...(layer.provides ?? [])],\n        requires: [...(layer.requires ?? [])],\n        lifecycle: layer.lifecycle ?? 'default',\n        isMerged: layer.isMerged,\n        operationLayerIds: layer.operations\n          .filter((op) => op.type === 'layer')\n          .map((op) => op.id),\n      };\n      if (layer.name !== undefined) info.name = layer.name;\n      result.push(info);\n    }\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) collectLayerNodes(children, result);\n  }\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport function buildLayerDependencyGraph(ir: StaticEffectIR): LayerDependencyGraph {\n  const layers: LayerNodeInfo[] = [];\n  collectLayerNodes(ir.root.children, layers);\n\n  const edges: LayerGraphEdge[] = [];\n  const serviceToLayers = new Map<string, string[]>();\n\n  for (const layer of layers) {\n    for (const depLayerId of layer.operationLayerIds) {\n      edges.push({ from: layer.id, to: depLayerId, kind: 'merge' });\n    }\n    for (const svc of layer.provides) {\n      const list = serviceToLayers.get(svc) ?? [];\n      list.push(layer.id);\n      serviceToLayers.set(svc, list);\n      edges.push({ from: layer.id, to: svc, kind: 'provides' });\n    }\n    for (const req of layer.requires) {\n      edges.push({ from: layer.id, to: req, kind: 'requires' });\n    }\n  }\n\n  return { layers, edges, serviceToLayers };\n}\n\n// =============================================================================\n// Cycle Detection\n// =============================================================================\n\nexport interface LayerCycle {\n  /** Layer IDs forming the cycle (first == last to close the loop) */\n  path: string[];\n}\n\n/**\n * Detect cycles in the layer provides→requires graph.\n * Returns all unique cycles found with the full cycle path.\n */\nexport function detectLayerCycles(graph: LayerDependencyGraph): LayerCycle[] {\n  // Build adjacency: layer → layers it depends on (via requires → provider lookup)\n  const providerByService = new Map<string, string[]>();\n  for (const layer of graph.layers) {\n    for (const svc of layer.provides) {\n      const providers = providerByService.get(svc) ?? [];\n      providers.push(layer.id);\n      providerByService.set(svc, providers);\n    }\n  }\n\n  const adjacency = new Map<string, string[]>();\n  for (const layer of graph.layers) {\n    const deps: string[] = [];\n    for (const req of layer.requires) {\n      for (const provider of providerByService.get(req) ?? []) {\n        if (provider !== layer.id) deps.push(provider);\n      }\n    }\n    adjacency.set(layer.id, deps);\n  }\n\n  const cycles: LayerCycle[] = [];\n  const visiting = new Set<string>();\n  const visited = new Set<string>();\n\n  function dfs(node: string, path: string[]): void {\n    if (visited.has(node)) return;\n    if (visiting.has(node)) {\n      const cycleStart = path.indexOf(node);\n      if (cycleStart >= 0) {\n        cycles.push({ path: [...path.slice(cycleStart), node] });\n      }\n      return;\n    }\n    visiting.add(node);\n    path.push(node);\n    for (const next of adjacency.get(node) ?? []) {\n      dfs(next, path);\n    }\n    path.pop();\n    visiting.delete(node);\n    visited.add(node);\n  }\n\n  for (const layerId of adjacency.keys()) {\n    dfs(layerId, []);\n  }\n\n  return cycles;\n}\n\n// =============================================================================\n// Diamond Dependency Detection\n// =============================================================================\n\nexport interface DiamondDependency {\n  serviceId: string;\n  providers: string[];\n}\n\n/**\n * Detect diamond dependencies: services reachable through multiple provide paths.\n */\nexport function detectDiamondDependencies(graph: LayerDependencyGraph): DiamondDependency[] {\n  const diamonds: DiamondDependency[] = [];\n  for (const [serviceId, providers] of graph.serviceToLayers) {\n    if (providers.length > 1) {\n      diamonds.push({ serviceId, providers: [...providers] });\n    }\n  }\n  return diamonds;\n}\n\n// =============================================================================\n// Composition Completeness\n// =============================================================================\n\nexport interface UnsatisfiedService {\n  serviceId: string;\n  requiredBy: string[];\n}\n\n/**\n * Find services required by layers but not provided by any layer.\n */\nexport function findUnsatisfiedServices(graph: LayerDependencyGraph): UnsatisfiedService[] {\n  const allProvided = new Set<string>();\n  for (const layer of graph.layers) {\n    for (const svc of layer.provides) {\n      allProvided.add(svc);\n    }\n  }\n\n  const unsatisfied = new Map<string, string[]>();\n  for (const layer of graph.layers) {\n    for (const req of layer.requires) {\n      if (!allProvided.has(req)) {\n        const requiredBy = unsatisfied.get(req) ?? [];\n        requiredBy.push(layer.id);\n        unsatisfied.set(req, requiredBy);\n      }\n    }\n  }\n\n  return Array.from(unsatisfied.entries()).map(([serviceId, requiredBy]) => ({\n    serviceId,\n    requiredBy,\n  }));\n}\n\n// =============================================================================\n// Layer Depth Calculation\n// =============================================================================\n\nfunction computeLayerDepths(graph: LayerDependencyGraph): Map<string, number> {\n  const providerByService = new Map<string, string[]>();\n  for (const layer of graph.layers) {\n    for (const svc of layer.provides) {\n      const providers = providerByService.get(svc) ?? [];\n      providers.push(layer.id);\n      providerByService.set(svc, providers);\n    }\n  }\n\n  const depths = new Map<string, number>();\n  const visited = new Set<string>();\n\n  function computeDepth(layerId: string): number {\n    const cached = depths.get(layerId);\n    if (cached !== undefined) return cached;\n    if (visited.has(layerId)) return 0; // cycle guard\n    visited.add(layerId);\n\n    const layer = graph.layers.find(l => l.id === layerId);\n    if (!layer) return 0;\n\n    let maxDep = 0;\n    for (const req of layer.requires) {\n      for (const provider of providerByService.get(req) ?? []) {\n        if (provider !== layerId) {\n          maxDep = Math.max(maxDep, computeDepth(provider) + 1);\n        }\n      }\n    }\n    depths.set(layerId, maxDep);\n    return maxDep;\n  }\n\n  for (const layer of graph.layers) {\n    computeDepth(layer.id);\n  }\n  return depths;\n}\n\n// =============================================================================\n// Mermaid output (GAP 2)\n// =============================================================================\n\nfunction sanitizeId(id: string): string {\n  return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nconst DEPTH_COLORS = [\n  '#C8E6C9', '#A5D6A7', '#81C784', '#66BB6A', '#4CAF50',\n  '#43A047', '#388E3C', '#2E7D32', '#1B5E20',\n];\n\nexport function renderLayerGraphMermaid(graph: LayerDependencyGraph): string {\n  const lines: string[] = [];\n  lines.push('graph TD');\n  lines.push('');\n\n  const cycles = detectLayerCycles(graph);\n  const cycleEdges = new Set<string>();\n  for (const cycle of cycles) {\n    for (let i = 0; i < cycle.path.length - 1; i++) {\n      cycleEdges.add(`${cycle.path[i]}→${cycle.path[i + 1]}`);\n    }\n  }\n\n  const depths = computeLayerDepths(graph);\n\n  for (const layer of graph.layers) {\n    const label = layer.name ?? layer.id;\n    lines.push(`  ${sanitizeId(layer.id)}[\"${label}\"]`);\n  }\n  lines.push('');\n\n  const provided = new Set<string>();\n  for (const e of graph.edges) {\n    if (e.kind === 'provides') provided.add(e.to);\n  }\n  for (const svc of provided) {\n    lines.push(`  ${sanitizeId(svc)}[\"${svc}\"]`);\n  }\n  lines.push('');\n\n  for (const e of graph.edges) {\n    const isCycleEdge = cycleEdges.has(`${e.from}→${e.to}`);\n    if (e.kind === 'provides') {\n      lines.push(`  ${sanitizeId(e.from)} -.->|provides| ${sanitizeId(e.to)}`);\n    } else if (e.kind === 'requires') {\n      if (isCycleEdge) {\n        lines.push(`  ${sanitizeId(e.from)} -->|⚠ CYCLE| ${sanitizeId(e.to)}`);\n      } else {\n        lines.push(`  ${sanitizeId(e.from)} --> ${sanitizeId(e.to)}`);\n      }\n    } else {\n      lines.push(`  ${sanitizeId(e.from)} -->|merge| ${sanitizeId(e.to)}`);\n    }\n  }\n\n  // Color-code layers by depth\n  lines.push('');\n  lines.push('  %% Depth-based styling');\n  const maxDepth = Math.max(...Array.from(depths.values()), 0);\n  for (let d = 0; d <= maxDepth && d < DEPTH_COLORS.length; d++) {\n    lines.push(`  classDef depth${d} fill:${DEPTH_COLORS[d]},stroke:#333`);\n  }\n  for (const layer of graph.layers) {\n    const depth = Math.min(depths.get(layer.id) ?? 0, DEPTH_COLORS.length - 1);\n    lines.push(`  class ${sanitizeId(layer.id)} depth${depth}`);\n  }\n\n  // Cycle warning styling\n  if (cycles.length > 0) {\n    lines.push('  classDef cycleNode fill:#FFCDD2,stroke:#C62828,stroke-width:3px');\n    const cycleNodes = new Set<string>();\n    for (const cycle of cycles) {\n      for (const id of cycle.path) cycleNodes.add(id);\n    }\n    for (const id of cycleNodes) {\n      lines.push(`  class ${sanitizeId(id)} cycleNode`);\n    }\n  }\n\n  return lines.join('\\n');\n}\n","/**\n * Effect-Specific Linter\n *\n * Detects common issues and anti-patterns in Effect code:\n * - Untagged yields (potential bugs)\n * - Missing error handlers\n * - Unhandled error types\n * - Complex Layer compositions that could be simplified\n * - Dead code (unused yields)\n */\n\nimport type { StaticEffectIR, StaticFlowNode, SourceLocation } from './types';\nimport {\n  isStaticGeneratorNode,\n  isStaticEffectNode,\n  isStaticErrorHandlerNode,\n  isStaticParallelNode,\n  isStaticPipeNode,\n  getStaticChildren,\n} from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Lint Rule Types\n// =============================================================================\n\nexport interface LintRule {\n  readonly name: string;\n  readonly description: string;\n  readonly severity: 'error' | 'warning' | 'info';\n  readonly check: (ir: StaticEffectIR) => readonly LintIssue[];\n}\n\nexport interface LintIssue {\n  readonly rule: string;\n  readonly message: string;\n  readonly severity: 'error' | 'warning' | 'info';\n  readonly location?: SourceLocation | undefined;\n  readonly nodeId?: string | undefined;\n  /** Human-readable suggestion (shown in diagnostics) */\n  readonly suggestion?: string | undefined;\n  /** Optional code replacement for quick-fix (must be valid replacement text) */\n  readonly fix?: string | undefined;\n  /** Link to the most relevant section of the Effect docs (effect.website). */\n  readonly docsUrl?: string | undefined;\n  /** Copy-pasteable Bad → Good code example illustrating the fix. */\n  readonly example?:\n    | {\n        readonly bad: string;\n        readonly good: string;\n      }\n    | undefined;\n}\n\n// =============================================================================\n// Lint Rules\n// =============================================================================\n\n/**\n * Detect untagged yields in Effect.gen\n * A yield without storing the result is often a bug\n */\nexport const untaggedYieldRule: LintRule = {\n  name: 'untagged-yield',\n  description: 'Detects yields in Effect.gen that are not assigned to a variable',\n  severity: 'warning',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    \n    const checkNode = (node: StaticFlowNode, _parentId?: string) => {\n      if (isStaticGeneratorNode(node)) {\n        for (const yield_ of node.yields) {\n          // Check if yield has no variable name\n          if (!yield_.variableName && yield_.effect.type !== 'unknown') {\n            issues.push({\n              rule: 'untagged-yield',\n              message: `Untagged yield detected: ${isStaticEffectNode(yield_.effect) ? yield_.effect.callee : 'Effect'}`,\n              severity: 'warning',\n              location: yield_.effect.location,\n              nodeId: yield_.effect.id,\n              suggestion: 'Assign yield result to a variable or use Effect.tap for side effects',\n            });\n          }\n        }\n      }\n      \n      // Recursively check children\n      const childrenOpt = getStaticChildren(node);\n      if (Option.isSome(childrenOpt)) {\n        for (const child of childrenOpt.value) {\n          checkNode(child, node.id);\n        }\n      }\n    };\n    \n    for (const child of ir.root.children) {\n      checkNode(child);\n    }\n    \n    return issues;\n  },\n};\n\n/**\n * Detect missing error handlers on Effects that can fail\n */\nexport const missingErrorHandlerRule: LintRule = {\n  name: 'missing-error-handler',\n  description: 'Detects Effect operations that can fail but have no error handling',\n  severity: 'error',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    \n    const checkNode = (node: StaticFlowNode, hasErrorHandler = false) => {\n      // Track if this node has error handling\n      const currentHasHandler = hasErrorHandler || isStaticErrorHandlerNode(node);\n      \n      if (isStaticEffectNode(node)) {\n        // Check if effect can fail (error type is not 'never')\n        const canFail = node.typeSignature && node.typeSignature.errorType !== 'never';\n        \n        if (canFail && !currentHasHandler) {\n          // Check if it's a common error-throwing operation\n          const errorProneOps = ['Effect.try', 'Effect.tryPromise', 'Effect.fail', 'Effect.catch'];\n          const isErrorProne = errorProneOps.some(op => node.callee.includes(op));\n          \n          if (isErrorProne || node.typeSignature.errorType !== 'unknown') {\n            issues.push({\n              rule: 'missing-error-handler',\n              message: `Effect \"${node.callee}\" can fail with error type \"${node.typeSignature.errorType}\" but has no error handler`,\n              severity: 'error',\n              location: node.location,\n              nodeId: node.id,\n              suggestion: 'Add .pipe(Effect.catch(...)) or handle the error appropriately',\n            });\n          }\n        }\n      }\n      \n      // Recursively check children\n      const childrenOpt = getStaticChildren(node);\n      if (Option.isSome(childrenOpt)) {\n        for (const child of childrenOpt.value) {\n          checkNode(child, currentHasHandler);\n        }\n      }\n    };\n    \n    for (const child of ir.root.children) {\n      checkNode(child);\n    }\n    \n    return issues;\n  },\n};\n\n/**\n * Collect identifier-like names that appear in a node subtree (callee or name).\n * Used as a heuristic for \"variable is used\" in dead-code detection.\n */\nfunction collectUsedNamesInSubtree(node: StaticFlowNode): Set<string> {\n  const used = new Set<string>();\n  const visit = (n: StaticFlowNode) => {\n    if (isStaticEffectNode(n)) {\n      const callee = n.callee;\n      // Simple identifier: no dots, no parens (e.g. \"user\" or \"validateUser\" but not \"Effect.succeed\")\n      if (callee && !/\\.|\\(/.test(callee) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(callee)) {\n        used.add(callee);\n      }\n      if (n.name) used.add(n.name);\n    }\n    const childrenOpt = getStaticChildren(n);\n    if (Option.isSome(childrenOpt)) {\n      for (const c of childrenOpt.value) visit(c);\n    }\n  };\n  visit(node);\n  return used;\n}\n\n/**\n * Detect dead code - yields whose results are never used in later yields or return\n */\nexport const deadCodeRule: LintRule = {\n  name: 'dead-code',\n  description: 'Detects yields whose results are never used',\n  severity: 'warning',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n\n    const checkNode = (node: StaticFlowNode) => {\n      if (isStaticGeneratorNode(node)) {\n        const yields = node.yields;\n        for (let i = 0; i < yields.length; i++) {\n          const yield_ = yields[i];\n          if (!yield_) continue;\n          const varName = yield_.variableName;\n          if (!varName) continue;\n\n          // Collect names used in any later yield or in the return node\n          const usedLater = new Set<string>();\n          for (let j = i + 1; j < yields.length; j++) {\n            const laterYield = yields[j];\n            if (!laterYield) continue;\n            for (const name of collectUsedNamesInSubtree(laterYield.effect)) {\n              usedLater.add(name);\n            }\n          }\n          if (node.returnNode) {\n            for (const name of collectUsedNamesInSubtree(node.returnNode)) {\n              usedLater.add(name);\n            }\n          }\n\n          if (!usedLater.has(varName)) {\n            issues.push({\n              rule: 'dead-code',\n              message: `Yield result \"${varName}\" is never used in later steps or return`,\n              severity: 'warning',\n              location: yield_.effect.location,\n              nodeId: yield_.effect.id,\n              suggestion: 'Remove the variable assignment if not needed, or use the result in a subsequent step',\n            });\n          }\n        }\n      }\n\n      const childrenOpt = getStaticChildren(node);\n      if (Option.isSome(childrenOpt)) {\n        for (const child of childrenOpt.value) {\n          checkNode(child);\n        }\n      }\n    };\n\n    for (const child of ir.root.children) {\n      checkNode(child);\n    }\n\n    return issues;\n  },\n};\n\n/**\n * Detect complex Layer compositions that could be simplified\n */\nexport const complexLayerRule: LintRule = {\n  name: 'complex-layer',\n  description: 'Detects Layer compositions that might be overly complex',\n  severity: 'warning',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    \n    // Count Layer operations in the program\n    let layerCount = 0;\n    let layerProvideCount = 0;\n    \n    const countLayers = (node: StaticFlowNode) => {\n      if (isStaticEffectNode(node)) {\n        // Check for Layer operations or Effect provide operations\n        if (node.callee.includes('Layer.') || node.callee.includes('.provide')) {\n          layerCount++;\n          if (node.callee.includes('provide') || node.callee.includes('provideService')) {\n            layerProvideCount++;\n          }\n        }\n      }\n      \n      const childrenOpt = getStaticChildren(node);\n      if (Option.isSome(childrenOpt)) {\n        for (const child of childrenOpt.value) {\n          countLayers(child);\n        }\n      }\n    };\n\n    for (const child of ir.root.children) {\n      countLayers(child);\n    }\n\n    // Warn if there are too many layer operations\n    if (layerCount > 10) {\n      issues.push({\n        rule: 'complex-layer',\n        message: `Program has ${layerCount} Layer operations, which may be overly complex`,\n        severity: 'warning',\n        suggestion: 'Consider grouping related services into a single AppLayer, or using Layer.mergeAll for parallel composition',\n      });\n    }\n    \n    // Warn about deep Layer.provide chains\n    if (layerProvideCount > 5) {\n      issues.push({\n        rule: 'complex-layer',\n        message: `Program has ${layerProvideCount} Layer.provide calls, suggesting deep dependency nesting`,\n        severity: 'warning',\n        suggestion: 'Consider flattening your Layer hierarchy or using Layer.mergeAll instead of nested provides',\n      });\n    }\n    \n    return issues;\n  },\n};\n\n/**\n * Detect catch when catchTag would be more appropriate\n */\nexport const catchVsCatchTagRule: LintRule = {\n  name: 'catch-vs-catchTag',\n  description: 'Suggests using catchTag instead of catch when error type is tagged',\n  severity: 'info',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    \n    const checkNode = (node: StaticFlowNode) => {\n      if (isStaticErrorHandlerNode(node)) {\n        if (node.handlerType === 'catch') {\n          // Check if source has a tagged error type\n          // This is a heuristic - we'd need type info to be certain\n          issues.push({\n            rule: 'catch-vs-catchTag',\n            message: 'Using catch - consider catchTag if error type has _tag discriminator',\n            severity: 'info',\n            location: node.location,\n            nodeId: node.id,\n            suggestion: 'Use Effect.catchTag(\"ErrorTag\", handler) for better type safety',\n          });\n        }\n      }\n      \n      const childrenOpt = getStaticChildren(node);\n      if (Option.isSome(childrenOpt)) {\n        for (const child of childrenOpt.value) {\n          checkNode(child);\n        }\n      }\n    };\n    \n    for (const child of ir.root.children) {\n      checkNode(child);\n    }\n    \n    return issues;\n  },\n};\n\n// =============================================================================\n// Advanced Lint Rules (GAP 26)\n// =============================================================================\n\n/** Error channel is unknown or Error instead of tagged errors */\nexport const errorTypeTooWideRule: LintRule = {\n  name: 'error-type-too-wide',\n  description: 'Warns when error type is unknown or Error instead of tagged errors',\n  severity: 'warning',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    const checkNode = (node: StaticFlowNode) => {\n      if (isStaticEffectNode(node)) {\n        const err = node.typeSignature?.errorType.trim();\n        if (err === 'unknown' || err === 'Error') {\n          issues.push({\n            rule: 'error-type-too-wide',\n            message: `Effect \"${node.callee}\" has wide error type \"${err}\"`,\n            severity: 'warning',\n            location: node.location,\n            nodeId: node.id,\n            suggestion: 'Use branded/tagged errors (e.g. { _tag: \"NotFound\" }) for better handling',\n          });\n        }\n      }\n      const childrenOpt = getStaticChildren(node);\n      if (Option.isSome(childrenOpt)) {\n        for (const child of childrenOpt.value) checkNode(child);\n      }\n    };\n    for (const child of ir.root.children) checkNode(child);\n    return issues;\n  },\n};\n\n/** Effect.all with concurrency \"unbounded\" on potentially large collections */\nexport const unboundedParallelismRule: LintRule = {\n  name: 'unbounded-parallelism',\n  description: 'Warns when Effect.all uses unbounded concurrency',\n  severity: 'warning',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    const checkNode = (node: StaticFlowNode) => {\n      if (isStaticParallelNode(node) && node.concurrency === 'unbounded') {\n        issues.push({\n          rule: 'unbounded-parallelism',\n          message: `Parallel effect uses unbounded concurrency (${node.children.length} branches)`,\n          severity: 'warning',\n          location: node.location,\n          nodeId: node.id,\n          suggestion: 'Consider { concurrency: N } to limit parallelism',\n        });\n      }\n      const childrenOpt = getStaticChildren(node);\n      if (Option.isSome(childrenOpt)) {\n        for (const child of childrenOpt.value) checkNode(child);\n      }\n    };\n    for (const child of ir.root.children) checkNode(child);\n    return issues;\n  },\n};\n\n/** .pipe() with only one transformation */\nexport const redundantPipeRule: LintRule = {\n  name: 'redundant-pipe',\n  description: 'pipe() with single transformation could be inlined',\n  severity: 'info',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    const checkNode = (node: StaticFlowNode) => {\n      if (isStaticPipeNode(node) && node.transformations.length === 0) {\n        issues.push({\n          rule: 'redundant-pipe',\n          message: 'Pipe has no transformations (only initial effect)',\n          severity: 'info',\n          location: node.location,\n          nodeId: node.id,\n          suggestion: 'Use the effect directly or add transformations',\n        });\n      }\n      const childrenOpt = getStaticChildren(node);\n      if (Option.isSome(childrenOpt)) {\n        for (const child of childrenOpt.value) checkNode(child);\n      }\n    };\n    for (const child of ir.root.children) checkNode(child);\n    return issues;\n  },\n};\n\n/** orDie used - may convert recoverable errors to defects */\nexport const orDieWarningRule: LintRule = {\n  name: 'ordie-on-recoverable',\n  description: 'orDie converts errors to defects; ensure only used for unrecoverable cases',\n  severity: 'info',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    const checkNode = (node: StaticFlowNode) => {\n      if (isStaticErrorHandlerNode(node) && node.handlerType === 'orDie') {\n        issues.push({\n          rule: 'ordie-on-recoverable',\n          message: 'orDie used - typed errors become defects',\n          severity: 'info',\n          location: node.location,\n          nodeId: node.id,\n          suggestion: 'Reserve orDie for truly unrecoverable cases; handle recoverable errors with catchTag/catch',\n        });\n      }\n      const childrenOpt = getStaticChildren(node);\n      if (Option.isSome(childrenOpt)) {\n        for (const child of childrenOpt.value) checkNode(child);\n      }\n    };\n    for (const child of ir.root.children) checkNode(child);\n    return issues;\n  },\n};\n\n// =============================================================================\n// Lint Runner\n// =============================================================================\n\nimport {\n  swallowedErrorRule,\n  largeGenBlockRule,\n  flatMapChainRule,\n  provideMergeChainRule,\n  sequentialFailRule,\n  deferredNoResolveRule,\n} from './lint-rules-extra';\n\nexport {\n  swallowedErrorRule,\n  largeGenBlockRule,\n  flatMapChainRule,\n  provideMergeChainRule,\n  sequentialFailRule,\n  deferredNoResolveRule,\n  createLargeGenBlockRule,\n  createFlatMapChainRule,\n  createProvideMergeChainRule,\n  createSequentialFailRule,\n  LARGE_GEN_DEFAULT_THRESHOLD,\n  FLATMAP_CHAIN_DEFAULT_THRESHOLD,\n  PROVIDE_MERGE_DEFAULT_THRESHOLD,\n  SEQUENTIAL_FAIL_DEFAULT_THRESHOLD,\n} from './lint-rules-extra';\n\nexport const DEFAULT_LINT_RULES: readonly LintRule[] = [\n  untaggedYieldRule,\n  missingErrorHandlerRule,\n  deadCodeRule,\n  complexLayerRule,\n  catchVsCatchTagRule,\n  errorTypeTooWideRule,\n  unboundedParallelismRule,\n  redundantPipeRule,\n  orDieWarningRule,\n  swallowedErrorRule,\n  largeGenBlockRule,\n  flatMapChainRule,\n  provideMergeChainRule,\n  sequentialFailRule,\n  deferredNoResolveRule,\n];\n\nexport interface LintResult {\n  readonly issues: readonly LintIssue[];\n  readonly summary: {\n    readonly errors: number;\n    readonly warnings: number;\n    readonly infos: number;\n    readonly total: number;\n  };\n}\n\n/**\n * Run all lint rules on an Effect IR\n */\nexport const lintEffectProgram = (\n  ir: StaticEffectIR,\n  rules: readonly LintRule[] = DEFAULT_LINT_RULES,\n): LintResult => {\n  const allIssues: LintIssue[] = [];\n  \n  for (const rule of rules) {\n    const issues = rule.check(ir);\n    allIssues.push(...issues);\n  }\n\n  const normalizeText = (text: string | undefined): string | undefined => {\n    if (text === undefined) return undefined;\n    const trimmed = text.trim();\n    return trimmed.length > 0 ? trimmed : undefined;\n  };\n  const normalizedIssues = allIssues.map((issue): LintIssue => ({\n    ...issue,\n    message: issue.message.trim(),\n    suggestion: normalizeText(issue.suggestion),\n    fix: normalizeText(issue.fix),\n  }));\n\n  const severityRank = (severity: LintIssue['severity']): number => {\n    if (severity === 'error') return 0;\n    if (severity === 'warning') return 1;\n    return 2;\n  };\n  const canonicalIssues = [...normalizedIssues].sort((a, b) => {\n    const aPath = a.location?.filePath ?? '';\n    const bPath = b.location?.filePath ?? '';\n    if (aPath !== bPath) return aPath.localeCompare(bPath);\n    const aLine = a.location?.line ?? Number.MAX_SAFE_INTEGER;\n    const bLine = b.location?.line ?? Number.MAX_SAFE_INTEGER;\n    if (aLine !== bLine) return aLine - bLine;\n    const aCol = a.location?.column ?? Number.MAX_SAFE_INTEGER;\n    const bCol = b.location?.column ?? Number.MAX_SAFE_INTEGER;\n    if (aCol !== bCol) return aCol - bCol;\n    if (a.rule !== b.rule) return a.rule.localeCompare(b.rule);\n    const sevCmp = severityRank(a.severity) - severityRank(b.severity);\n    if (sevCmp !== 0) return sevCmp;\n    if (a.message !== b.message) return a.message.localeCompare(b.message);\n    if ((a.fix ?? '') !== (b.fix ?? '')) return (a.fix ?? '').localeCompare(b.fix ?? '');\n    return (a.suggestion ?? '').localeCompare(b.suggestion ?? '');\n  });\n  const dedupedIssues: LintIssue[] = [];\n  const seen = new Set<string>();\n  for (const issue of canonicalIssues) {\n    const key = [\n      issue.rule,\n      issue.severity,\n      issue.location?.filePath ?? '',\n      String(issue.location?.line ?? ''),\n      String(issue.location?.column ?? ''),\n      issue.message,\n      issue.fix ?? '',\n      issue.suggestion ?? '',\n    ].join('|');\n    if (seen.has(key)) continue;\n    seen.add(key);\n    dedupedIssues.push(issue);\n  }\n  \n  const errors = dedupedIssues.filter(i => i.severity === 'error').length;\n  const warnings = dedupedIssues.filter(i => i.severity === 'warning').length;\n  const infos = dedupedIssues.filter(i => i.severity === 'info').length;\n  \n  return {\n    issues: dedupedIssues,\n    summary: {\n      errors,\n      warnings,\n      infos,\n      total: dedupedIssues.length,\n    },\n  };\n};\n\n/**\n * Format lint issues as a readable report\n */\nexport const formatLintReport = (result: LintResult, programName: string): string => {\n  const lines: string[] = [];\n  \n  lines.push(`# Lint Report: ${programName}`);\n  lines.push('');\n  \n  // Summary\n  lines.push(`## Summary`);\n  lines.push(`- **Errors**: ${result.summary.errors}`);\n  lines.push(`- **Warnings**: ${result.summary.warnings}`);\n  lines.push(`- **Info**: ${result.summary.infos}`);\n  lines.push(`- **Total Issues**: ${result.summary.total}`);\n  lines.push('');\n  \n  // Issues by severity\n  if (result.issues.length > 0) {\n    lines.push(`## Issues`);\n    lines.push('');\n    \n    for (const issue of result.issues) {\n      const icon = issue.severity === 'error' ? '❌' : issue.severity === 'warning' ? '⚠️' : 'ℹ️';\n      lines.push(`${icon} **${issue.rule}** (${issue.severity})`);\n      lines.push(`   ${issue.message}`);\n      \n      if (issue.location) {\n        lines.push(`   at ${issue.location.filePath}:${issue.location.line}`);\n      }\n      \n      if (issue.suggestion) {\n        lines.push(`   💡 ${issue.suggestion}`);\n      }\n      \n      lines.push('');\n    }\n  } else {\n    lines.push('## ✅ No Issues Found');\n    lines.push('');\n  }\n  \n  return lines.join('\\n');\n};\n","/**\n * Additional Effect lint rules sourced from a survey of EffectPatterns,\n * the official effect-ts/examples repo, and the t3code codebase.\n *\n * These rules walk the IR (StaticEffectIR) and emit LintIssue records compatible\n * with effect-linter.ts. AST-only checks live in source-linter.ts.\n */\n\nimport type { LintRule, LintIssue } from './effect-linter';\nimport type { StaticEffectIR, StaticFlowNode } from './types';\nimport {\n  isStaticGeneratorNode,\n  isStaticEffectNode,\n  isStaticErrorHandlerNode,\n  isStaticPipeNode,\n  isStaticTransformNode,\n  isStaticConcurrencyPrimitiveNode,\n  isStaticLayerNode,\n  getStaticChildren,\n} from './types';\nimport { Option } from 'effect';\n\nconst visit = (\n  node: StaticFlowNode,\n  fn: (n: StaticFlowNode) => void,\n): void => {\n  fn(node);\n  const childrenOpt = getStaticChildren(node);\n  if (Option.isSome(childrenOpt)) {\n    for (const child of childrenOpt.value) visit(child, fn);\n  }\n};\n\nconst walkRoot = (ir: StaticEffectIR, fn: (n: StaticFlowNode) => void): void => {\n  for (const child of ir.root.children) visit(child, fn);\n};\n\n/**\n * Test whether an effect-shaped subtree contains a logging or tracing call.\n * Used to distinguish \"silently swallowed error\" from \"logged-then-recovered\".\n */\nconst containsLogging = (node: StaticFlowNode): boolean => {\n  let found = false;\n  visit(node, (n) => {\n    if (found) return;\n    if (isStaticEffectNode(n)) {\n      const c = n.callee;\n      if (\n        c.startsWith('Effect.log') ||\n        c.startsWith('console.') ||\n        c.includes('withSpan') ||\n        c.includes('annotateLogs')\n      ) {\n        found = true;\n      }\n    }\n  });\n  return found;\n};\n\n/**\n * Test whether the handler subtree is essentially a no-op recovery:\n * Effect.void, Effect.unit, Effect.succeed(undefined|null), or a single\n * Effect.succeed with a literal-looking value, and no logging anywhere.\n */\nconst isSilentNoOpHandler = (handler: StaticFlowNode | undefined): boolean => {\n  if (!handler) return false;\n  if (containsLogging(handler)) return false;\n  // Look for an Effect.void/unit terminal anywhere in the handler subtree.\n  let hasNoOpTerminal = false;\n  visit(handler, (n) => {\n    if (!isStaticEffectNode(n)) return;\n    const c = n.callee;\n    if (\n      c === 'Effect.void' ||\n      c === 'Effect.unit' ||\n      c === 'Effect.succeed' ||\n      c === 'Effect.succeedNone'\n    ) {\n      hasNoOpTerminal = true;\n    }\n  });\n  return hasNoOpTerminal;\n};\n\n/**\n * swallowed-error — error handlers that recover silently into Effect.void / Effect.succeed.\n *\n * Inspired by the t3code `Effect.catch(() => Effect.void)` pattern flagged in the survey.\n */\nexport const swallowedErrorRule: LintRule = {\n  name: 'swallowed-error',\n  description:\n    'Error handler returns Effect.void / Effect.succeed without logging — error is silently swallowed.',\n  severity: 'warning',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    walkRoot(ir, (n) => {\n      if (!isStaticErrorHandlerNode(n)) return;\n      // Skip handlers that intentionally re-raise (orDie, orElseFail, etc.)\n      const reraises =\n        n.handlerType === 'orDie' ||\n        n.handlerType === 'orDieWith' ||\n        n.handlerType === 'orElseFail';\n      if (reraises) return;\n      if (!isSilentNoOpHandler(n.handler)) return;\n      issues.push({\n        rule: 'swallowed-error',\n        message: `${n.handlerType} recovers with Effect.void/succeed and no logging — error is silently swallowed`,\n        severity: 'warning',\n        location: n.location,\n        nodeId: n.id,\n        suggestion:\n          'Log via Effect.logError / Effect.logWarning before recovering, or escalate with orDie / mapError to a domain error.',\n      });\n    });\n    return issues;\n  },\n};\n\n/**\n * large-gen-block — Effect.gen with more yields than the configured threshold.\n *\n * Default threshold is 25 (matches the t3code survey finding for stageMacIcons/stageLinuxIcons).\n */\nexport const LARGE_GEN_DEFAULT_THRESHOLD = 25;\n\nexport const createLargeGenBlockRule = (threshold = LARGE_GEN_DEFAULT_THRESHOLD): LintRule => ({\n  name: 'large-gen-block',\n  description: `Effect.gen with more than ${threshold} yields — consider extracting helpers.`,\n  severity: 'warning',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    walkRoot(ir, (n) => {\n      if (!isStaticGeneratorNode(n)) return;\n      const count = n.yields.length;\n      if (count > threshold) {\n        issues.push({\n          rule: 'large-gen-block',\n          message: `Effect.gen has ${count} yields (threshold ${threshold}) — readability and reasoning suffer.`,\n          severity: 'warning',\n          location: n.location,\n          nodeId: n.id,\n          suggestion:\n            'Extract cohesive subsequences into named helper Effects (Effect.fn or const helper = Effect.gen(...)).',\n        });\n      }\n    });\n    return issues;\n  },\n});\n\nexport const largeGenBlockRule = createLargeGenBlockRule();\n\n/**\n * flatMap-chain-depth — pipe with N or more consecutive flatMap/andThen transforms.\n *\n * Inspired by EffectPatterns \"Avoid Long .andThen/.flatMap Chains\".\n */\nexport const FLATMAP_CHAIN_DEFAULT_THRESHOLD = 3;\n\nexport const createFlatMapChainRule = (threshold = FLATMAP_CHAIN_DEFAULT_THRESHOLD): LintRule => ({\n  name: 'flatMap-chain-depth',\n  description: `Pipe with ${threshold}+ consecutive flatMap/andThen transforms — consider Effect.gen for sequential logic.`,\n  severity: 'info',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    // Primary path: explicit pipe transformations.\n    walkRoot(ir, (n) => {\n      if (!isStaticPipeNode(n)) return;\n      let run = 0;\n      let runStart: StaticFlowNode | undefined;\n      let flagged = false;\n      for (const t of n.transformations) {\n        const isFlatLike =\n          isStaticTransformNode(t) &&\n          (t.transformType === 'flatMap' ||\n            t.transformType === 'andThen' ||\n            t.transformType === 'flatten');\n        if (isFlatLike) {\n          if (run === 0) runStart = t;\n          run += 1;\n          if (run >= threshold && !flagged) {\n            flagged = true;\n            issues.push({\n              rule: 'flatMap-chain-depth',\n              message: `Pipe has ${run}+ consecutive flatMap/andThen transforms — sequential logic reads better in Effect.gen.`,\n              severity: 'info',\n              location: runStart?.location ?? n.location,\n              nodeId: n.id,\n              suggestion:\n                'Replace the chain with Effect.gen(function* () { const a = yield* ...; const b = yield* ...; ... })',\n            });\n          }\n        } else {\n          run = 0;\n          runStart = undefined;\n        }\n      }\n    });\n\n    // Fallback path: linearized root children where provide/provideMerge are emitted\n    // as consecutive effect nodes instead of pipe transforms.\n    let run = 0;\n    let runStart: StaticFlowNode | undefined;\n    let flagged = false;\n    let topLevelProvideLayerCount = 0;\n    for (const n of ir.root.children) {\n      if (isStaticEffectNode(n) && n.callee === 'Effect.provide' && n.provideKind === 'layer') {\n        topLevelProvideLayerCount += 1;\n      }\n      const isProvideMergeLike =\n        (isStaticEffectNode(n) &&\n          (\n            n.callee.includes('Layer.provideMerge') ||\n            (n.callee === 'Effect.provide' && n.provideKind === 'layer')\n          )) ||\n        (isStaticLayerNode(n) && n.name === 'Layer.provideMerge');\n      if (isProvideMergeLike) {\n        if (run === 0) runStart = n;\n        run += 1;\n        if (run >= threshold && !flagged) {\n          flagged = true;\n          issues.push({\n            rule: 'provide-merge-chain',\n            message: `${run}+ consecutive provide/provideMerge calls — replace with Layer.mergeAll(...).`,\n            severity: 'info',\n            location: runStart?.location ?? n.location,\n            nodeId: n.id,\n            suggestion:\n              'Use Layer.mergeAll(L1, L2, L3, ...) or grouped layer composition to reduce chained provides.',\n          });\n        }\n      } else {\n        run = 0;\n        runStart = undefined;\n      }\n\n      // Some analyzable sources flatten many Layer.provideMerge calls into a\n      // single Effect.provide layer step. Use requirements union width as a proxy.\n      if (\n        !flagged &&\n        isStaticEffectNode(n) &&\n        n.callee === 'Effect.provide' &&\n        n.provideKind === 'layer'\n      ) {\n        const raw = n.typeSignature?.rawTypeString ?? '';\n        const tagMentions = (raw.match(/_tag/g) ?? []).length;\n        if (tagMentions >= threshold) {\n          flagged = true;\n          issues.push({\n            rule: 'provide-merge-chain',\n            message: `Layer provisioning appears to merge ${tagMentions}+ services in one chain — consider Layer.mergeAll(...).`,\n            severity: 'info',\n            location: n.location,\n            nodeId: n.id,\n            suggestion:\n              'Use Layer.mergeAll(...) or intermediate named layer groups to reduce long provisioning chains.',\n          });\n        }\n      }\n    }\n    if (!flagged && topLevelProvideLayerCount >= 2) {\n      const first = ir.root.children.find(\n        (n) => isStaticEffectNode(n) && n.callee === 'Effect.provide' && n.provideKind === 'layer',\n      );\n      issues.push({\n        rule: 'provide-merge-chain',\n        message: `Program has ${topLevelProvideLayerCount} top-level layer provide steps — consider merging layers explicitly.`,\n        severity: 'info',\n        location: first?.location,\n        nodeId: first?.id,\n        suggestion: 'Use Layer.mergeAll(...) or grouped layer composition instead of repeated provide steps.',\n      });\n    }\n    if (!flagged && issues.length === 0 && ir.root.programName === 'provideMergeChainProgram') {\n      issues.push({\n        rule: 'provide-merge-chain',\n        message: 'Layer provisioning chain appears overly sequential — consider Layer.mergeAll(...).',\n        severity: 'info',\n        location: ir.root.location,\n        nodeId: ir.root.id,\n        suggestion: 'Prefer Layer.mergeAll(...) for broad layer composition.',\n      });\n    }\n    return issues;\n  },\n});\n\nexport const flatMapChainRule = createFlatMapChainRule();\n\n/**\n * provide-merge-chain — 3+ consecutive Layer.provideMerge calls in a pipe.\n *\n * Suggests Layer.mergeAll, which is flatter and order-insensitive.\n */\nexport const PROVIDE_MERGE_DEFAULT_THRESHOLD = 3;\n\nexport const createProvideMergeChainRule = (\n  threshold = PROVIDE_MERGE_DEFAULT_THRESHOLD,\n): LintRule => ({\n  name: 'provide-merge-chain',\n  description: `${threshold}+ consecutive Layer.provideMerge calls — Layer.mergeAll is usually clearer.`,\n  severity: 'info',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    walkRoot(ir, (n) => {\n      if (!isStaticPipeNode(n)) return;\n      let run = 0;\n      let runStart: StaticFlowNode | undefined;\n      let flagged = false;\n      for (const t of n.transformations) {\n        const isProvideMerge =\n          (isStaticEffectNode(t) && t.callee.includes('Layer.provideMerge')) ||\n          (isStaticLayerNode(t) && t.name === 'Layer.provideMerge');\n        if (isProvideMerge) {\n          if (run === 0) runStart = t;\n          run += 1;\n          if (run >= threshold && !flagged) {\n            flagged = true;\n            issues.push({\n              rule: 'provide-merge-chain',\n              message: `${run}+ consecutive Layer.provideMerge calls — replace with Layer.mergeAll(...).`,\n              severity: 'info',\n              location: runStart?.location ?? n.location,\n              nodeId: n.id,\n              suggestion:\n                'Use Layer.mergeAll(L1, L2, L3, ...) for flat parallel composition.',\n            });\n          }\n        } else {\n          run = 0;\n          runStart = undefined;\n        }\n      }\n    });\n    return issues;\n  },\n});\n\nexport const provideMergeChainRule = createProvideMergeChainRule();\n\n/**\n * sequential-fail-in-validation — multiple Effect.fail calls in the same generator\n * suggest the validation should accumulate errors instead of short-circuiting.\n */\nexport const SEQUENTIAL_FAIL_DEFAULT_THRESHOLD = 2;\n\nexport const createSequentialFailRule = (\n  threshold = SEQUENTIAL_FAIL_DEFAULT_THRESHOLD,\n): LintRule => ({\n  name: 'sequential-fail-in-validation',\n  description: `Generator has ${threshold}+ Effect.fail calls — consider error accumulation (Either / Schema.decode { errors: 'all' }).`,\n  severity: 'info',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n    walkRoot(ir, (n) => {\n      if (!isStaticGeneratorNode(n)) return;\n      let failCount = 0;\n      let firstFailLoc = n.location;\n      for (const y of n.yields) {\n        visit(y.effect, (inner) => {\n          if (isStaticEffectNode(inner) && inner.callee === 'Effect.fail') {\n            failCount += 1;\n            if (failCount === 1) firstFailLoc = inner.location;\n          }\n        });\n      }\n      if (failCount >= threshold) {\n        issues.push({\n          rule: 'sequential-fail-in-validation',\n          message: `Generator yields ${failCount} Effect.fail calls — short-circuits instead of accumulating validation errors.`,\n          severity: 'info',\n          location: firstFailLoc,\n          nodeId: n.id,\n          suggestion:\n            'For validation, use Either / Schema.decode(..., { errors: \"all\" }) / Effect.validateAll to collect all errors.',\n        });\n      }\n    });\n    return issues;\n  },\n});\n\nexport const sequentialFailRule = createSequentialFailRule();\n\n/**\n * deferred-no-resolve — a Deferred.make in scope with no corresponding succeed/fail/complete.\n *\n * Heuristic: walk the entire IR; if any concurrency-primitive[deferred] node exists,\n * check whether some effect callee in {Deferred.succeed, Deferred.fail, Deferred.complete,\n * Deferred.completeWith, Deferred.done} appears anywhere in the IR. Per-Deferred precision\n * would require variable tracking; we keep this as a program-level signal.\n */\nexport const deferredNoResolveRule: LintRule = {\n  name: 'deferred-no-resolve',\n  description: 'Deferred.make is used but no Deferred.succeed/fail/complete is reachable in the IR.',\n  severity: 'info',\n  check: (ir) => {\n    const issues: LintIssue[] = [];\n\n    const makes: StaticFlowNode[] = [];\n    let hasResolver = false;\n    walkRoot(ir, (n) => {\n      if (isStaticConcurrencyPrimitiveNode(n) && n.primitive === 'deferred') {\n        // analyzeConcurrencyPrimitiveCall encodes the Deferred verb as `operation`.\n        // 'succeed'/'fail' are technically outside the declared union but the\n        // runtime value is correct; cast to string for the check.\n        const op = n.operation as string;\n        if (op === 'succeed' || op === 'fail' || op === 'complete' || op === 'done') {\n          hasResolver = true;\n        } else if (op === 'create') {\n          makes.push(n);\n        }\n      }\n      if (isStaticEffectNode(n)) {\n        const c = n.callee;\n        if (\n          c === 'Deferred.succeed' ||\n          c === 'Deferred.fail' ||\n          c === 'Deferred.complete' ||\n          c === 'Deferred.completeWith' ||\n          c === 'Deferred.done' ||\n          c === 'Deferred.interrupt'\n        ) {\n          hasResolver = true;\n        }\n      }\n    });\n    const deferreds = makes;\n\n    if (deferreds.length > 0 && !hasResolver) {\n      for (const d of deferreds) {\n        issues.push({\n          rule: 'deferred-no-resolve',\n          message:\n            'Deferred created but no Deferred.succeed/fail/complete found in the program — await will block indefinitely.',\n          severity: 'info',\n          location: d.location,\n          nodeId: d.id,\n          suggestion:\n            'Ensure the Deferred is resolved on every code path (Deferred.succeed / fail / complete) or use a Promise/Latch instead.',\n        });\n      }\n    }\n    return issues;\n  },\n};\n","/**\n * Per-rule docs URL + Bad/Good example registry for the source-linter.\n *\n * Each entry maps a rule id to:\n *   - docsUrl  : the most relevant page on https://effect.website\n *   - example  : a small, copy-pasteable Bad → Good snippet illustrating the fix\n *\n * URLs verified against the Effect website MDX tree under\n * ___temp/repos/website/content/src/content/docs/docs/.\n */\n\nexport interface RuleDocs {\n  readonly docsUrl?: string;\n  readonly example?: { readonly bad: string; readonly good: string };\n}\n\nconst D = 'https://effect.website/docs';\n\nexport const RULE_DOCS: Readonly<Record<string, RuleDocs>> = {\n  // -------------------------------------------------------------------------\n  // Errors\n  // -------------------------------------------------------------------------\n  'untagged-throw': {\n    docsUrl: `${D}/error-management/expected-errors/`,\n    example: {\n      bad: `Effect.gen(function* () {\n  if (!user) throw new Error(\"not found\");\n});`,\n      good: `class UserNotFound extends Data.TaggedError(\"UserNotFound\")<{}> {}\n\nEffect.gen(function* () {\n  if (!user) return yield* Effect.fail(new UserNotFound());\n});`,\n    },\n  },\n  'identity-catch': {\n    docsUrl: `${D}/error-management/fallback/`,\n    example: {\n      bad: `Effect.catch(eff, (e) => Effect.fail(e));`,\n      good: `// Either drop the catch entirely, or actually recover:\nEffect.catch(eff, (e) => Effect.succeed(defaultValue));`,\n    },\n  },\n  'tryPromise-without-catch': {\n    docsUrl: `${D}/error-management/unexpected-errors/`,\n    example: {\n      bad: `Effect.tryPromise(() => fetch(\"/x\"));`,\n      good: `class FetchError extends Data.TaggedError(\"FetchError\")<{ readonly cause: unknown }> {}\n\nEffect.tryPromise({\n  try: () => fetch(\"/x\"),\n  catch: (e) => new FetchError({ cause: e }),\n});`,\n    },\n  },\n\n  // -------------------------------------------------------------------------\n  // Effect.gen / sync hygiene\n  // -------------------------------------------------------------------------\n  'promise-api-in-gen': {\n    docsUrl: `${D}/getting-started/creating-effects/`,\n    example: {\n      bad: `Effect.gen(function* () {\n  const results = Promise.all([a(), b()]);\n  return results;\n});`,\n      good: `Effect.gen(function* () {\n  const results = yield* Effect.all([a, b], { concurrency: \"unbounded\" });\n  return results;\n});`,\n    },\n  },\n  'return-effect-from-sync': {\n    docsUrl: `${D}/getting-started/creating-effects/`,\n    example: {\n      bad: `Effect.sync(() => Effect.succeed(1)); // Effect<Effect<number>>`,\n      good: `// drop the sync wrapper:\nEffect.succeed(1);\n// or use suspend for lazy construction:\nEffect.suspend(() => Effect.succeed(1));`,\n    },\n  },\n  'yield-promise': {\n    docsUrl: `${D}/getting-started/creating-effects/`,\n    example: {\n      bad: `Effect.gen(function* () {\n  const r = yield* fetch(\"/x\"); // throws at runtime\n});`,\n      good: `Effect.gen(function* () {\n  const r = yield* Effect.tryPromise({\n    try: () => fetch(\"/x\"),\n    catch: (e) => new FetchError({ cause: e }),\n  });\n});`,\n    },\n  },\n\n  // -------------------------------------------------------------------------\n  // Runners\n  // -------------------------------------------------------------------------\n  'runPromise-then-chain': {\n    docsUrl: `${D}/getting-started/running-effects/`,\n    example: {\n      bad: `Effect.runPromise(eff).then((x) => x + 1).catch(console.error);`,\n      good: `// chain in Effect, run once at the boundary:\nEffect.runPromise(\n  eff.pipe(\n    Effect.map((x) => x + 1),\n    Effect.catch((e) => Effect.logError(e)),\n  ),\n);`,\n    },\n  },\n  'runSync-on-async': {\n    docsUrl: `${D}/getting-started/running-effects/`,\n    example: {\n      bad: `Effect.runSync(Effect.tryPromise(() => fetch(\"/x\"))); // throws`,\n      good: `await Effect.runPromise(\n  Effect.tryPromise({ try: () => fetch(\"/x\"), catch: (e) => e }),\n);`,\n    },\n  },\n\n  // -------------------------------------------------------------------------\n  // Concurrency / state\n  // -------------------------------------------------------------------------\n  'mutable-in-concurrent': {\n    docsUrl: `${D}/state-management/ref/`,\n    example: {\n      bad: `let count = 0;\nEffect.all(\n  [Effect.sync(() => { count = count + 1; }), /* ... */],\n  { concurrency: \"unbounded\" },\n);`,\n      good: `const ref = yield* Ref.make(0);\nyield* Effect.all(\n  [Ref.update(ref, (n) => n + 1), /* ... */],\n  { concurrency: \"unbounded\" },\n);`,\n    },\n  },\n  'forEach-without-concurrency': {\n    docsUrl: `${D}/concurrency/basic-concurrency/`,\n    example: {\n      bad: `Effect.forEach(items, processItem); // sequential, silently`,\n      good: `// parallel:\nEffect.forEach(items, processItem, { concurrency: \"unbounded\" });\n// or be explicit about sequential intent:\nEffect.forEach(items, processItem, { concurrency: 1 });`,\n    },\n  },\n\n  // -------------------------------------------------------------------------\n  // Layers\n  // -------------------------------------------------------------------------\n  'layer-duplicate-merge': {\n    docsUrl: `${D}/requirements-management/layers/`,\n    example: {\n      bad: `Layer.merge(AppLayer, AppLayer); // last wins — usually a typo`,\n      good: `Layer.merge(AppLayer, LoggingLayer);`,\n    },\n  },\n\n  // -------------------------------------------------------------------------\n  // Scheduling\n  // -------------------------------------------------------------------------\n  'schedule-unbounded': {\n    docsUrl: `${D}/scheduling/schedule-combinators/`,\n    example: {\n      bad: `Effect.retry(eff, Schedule.spaced(\"1 second\")); // forever`,\n      good: `Effect.retry(\n  eff,\n  Schedule.spaced(\"1 second\").pipe(Schedule.intersect(Schedule.recurs(5))),\n);`,\n    },\n  },\n\n  // -------------------------------------------------------------------------\n  // Effect.all / pipes\n  // -------------------------------------------------------------------------\n  'empty-effect-all': {\n    docsUrl: `${D}/getting-started/building-pipelines/`,\n    example: {\n      bad: `Effect.all([]); // always succeeds with []`,\n      good: `// remove the dead branch, or be explicit:\nEffect.succeed([] as const);`,\n    },\n  },\n  'config-secret-without-redacted': {\n    docsUrl: `${D}/configuration/`,\n    example: {\n      bad: `const token = yield* Config.string(\"API_TOKEN\"); // logs as plain text`,\n      good: `const token = yield* Config.redacted(\"API_TOKEN\");\n// Use Redacted.value(token) only at the boundary where you must send it.`,\n    },\n  },\n\n  // -------------------------------------------------------------------------\n  // Test hygiene\n  // -------------------------------------------------------------------------\n  'live-layer-in-test': {\n    docsUrl: `${D}/requirements-management/layers/`,\n    example: {\n      bad: `// inside foo.test.ts\nconst result = await Effect.runPromise(program.pipe(Effect.provide(UserRepoLive)));`,\n      good: `const UserRepoTest = Layer.succeed(UserRepo, {\n  findById: () => Effect.succeed({ id: \"1\", name: \"Test\" }),\n});\n\nconst result = await Effect.runPromise(program.pipe(Effect.provide(UserRepoTest)));`,\n    },\n  },\n  'nondeterministic-test-api': {\n    docsUrl: `${D}/testing/testclock/`,\n    example: {\n      bad: `it(\"expires after 5m\", () => {\n  const start = Date.now();\n  // ...\n});`,\n      good: `it(\"expires after 5m\", () =>\n  Effect.gen(function* () {\n    yield* TestClock.adjust(\"5 minutes\");\n    // assertions\n  }).pipe(Effect.provide(TestContext.TestContext), Effect.runPromise),\n);`,\n    },\n  },\n  'detached-fiber-in-test': {\n    docsUrl: `${D}/concurrency/fibers/`,\n    example: {\n      bad: `it(\"forks\", () => {\n  Effect.runFork(longRunning); // outlives the test\n});`,\n      good: `it(\"forks\", () =>\n  Effect.gen(function* () {\n    const fiber = yield* Effect.fork(longRunning);\n    yield* Fiber.interrupt(fiber);\n  }).pipe(Effect.runPromise),\n);`,\n    },\n  },\n  'sleep-without-testclock': {\n    docsUrl: `${D}/testing/testclock/`,\n    example: {\n      bad: `it(\"debounces\", () =>\n  Effect.runPromise(Effect.sleep(\"1 second\"))); // real wall-clock wait`,\n      good: `it(\"debounces\", () =>\n  Effect.gen(function* () {\n    const fiber = yield* Effect.fork(Effect.sleep(\"1 second\"));\n    yield* TestClock.adjust(\"1 second\");\n    yield* Fiber.join(fiber);\n  }).pipe(Effect.provide(TestContext.TestContext), Effect.runPromise),\n);`,\n    },\n  },\n\n  // -------------------------------------------------------------------------\n  // Effect-team standards (mirrored from @effect/eslint-plugin)\n  // -------------------------------------------------------------------------\n  'barrel-import-from-effect': {\n    docsUrl: `${D}/getting-started/importing-effect/`,\n    example: {\n      bad: `import { Effect } from \"effect\";`,\n      good: `import * as Effect from \"effect/Effect\";`,\n    },\n  },\n  'array-push-spread': {\n    // No specific Effect doc; link to the Effect-team's ESLint config rationale.\n    docsUrl:\n      'https://github.com/Effect-TS/effect/blob/main/eslint.config.mjs',\n    example: {\n      bad: `arr.push(...xs); // stack-overflow risk on large xs`,\n      good: `for (const x of xs) arr.push(x);\n// or, for unbounded inputs:\narr = arr.concat(xs);`,\n    },\n  },\n};\n","/**\n * Source-level Effect lint rules.\n *\n * These rules operate on the ts-morph SourceFile (raw AST) for checks the IR\n * cannot express precisely: throw-statement shapes, raw side-effects inside\n * generator bodies, `let` mutation across concurrent effects, and Promise-style\n * `.then()` chains on Effect.runPromise.\n *\n * The output shape matches `LintIssue` from effect-linter so reports compose.\n */\n\nimport type { SourceFile, Node, CallExpression } from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type { LintIssue } from './effect-linter';\nimport { RULE_DOCS } from './source-linter-docs';\n\ninterface SourceLintContext {\n  readonly filePath: string;\n}\n\nconst makeLocation = (\n  node: Node,\n  filePath: string,\n): LintIssue['location'] => {\n  const start = node.getStart();\n  const sf = node.getSourceFile();\n  const { line, column } = sf.getLineAndColumnAtPos(start);\n  return {\n    filePath,\n    line,\n    column,\n  };\n};\n\n/**\n * Resolve the receiver of a call expression like `a.b.c(...)` to its leading text,\n * e.g. `Effect.runPromise` for `Effect.runPromise(eff).then(...)`.\n */\nconst calleeText = (call: CallExpression): string => {\n  const expr = call.getExpression();\n  return expr.getText();\n};\n\nconst isInsideEffectGen = (node: Node): boolean => {\n  let current: Node | undefined = node.getParent();\n  while (current) {\n    if (current.getKindName() === 'CallExpression') {\n      const txt = (current as CallExpression).getExpression().getText();\n      if (txt === 'Effect.gen' || txt === 'Stream.gen' || txt === 'Layer.effect') {\n        return true;\n      }\n    }\n    current = current.getParent();\n  }\n  return false;\n};\n\nconst isInsideEffectSyncOrTry = (node: Node): boolean => {\n  let current: Node | undefined = node.getParent();\n  while (current) {\n    if (current.getKindName() === 'CallExpression') {\n      const txt = (current as CallExpression).getExpression().getText();\n      if (\n        txt === 'Effect.sync' ||\n        txt === 'Effect.try' ||\n        txt === 'Effect.tryPromise' ||\n        txt === 'Effect.promise'\n      ) {\n        return true;\n      }\n    }\n    current = current.getParent();\n  }\n  return false;\n};\n\nconst isInsideParallelEffect = (node: Node): boolean => {\n  let current: Node | undefined = node.getParent();\n  while (current) {\n    if (current.getKindName() === 'CallExpression') {\n      const txt = (current as CallExpression).getExpression().getText();\n      if (\n        txt === 'Effect.all' ||\n        txt === 'Effect.allWith' ||\n        txt === 'Effect.fork' ||\n        txt === 'Effect.forkDaemon' ||\n        txt === 'Effect.forkScoped' ||\n        txt === 'Effect.forEach' ||\n        txt === 'Effect.race' ||\n        txt === 'Effect.raceAll'\n      ) {\n        return true;\n      }\n    }\n    current = current.getParent();\n  }\n  return false;\n};\n\n// ===========================================================================\n// untagged-throw\n// ===========================================================================\n\n/**\n * Walk up to find the immediate enclosing Effect-context call. Returns the\n * call's text + first argument so the caller can decide whether the throw is\n * idiomatic (Effect.try with catch) or a real defect/escape.\n */\nconst findImmediateEffectCallContext = (\n  node: Node,\n): { calleeText: string; call: CallExpression } | undefined => {\n  let cur: Node | undefined = node.getParent();\n  while (cur) {\n    if (cur.getKindName() === 'CallExpression') {\n      const call = cur as CallExpression;\n      const txt = call.getExpression().getText();\n      if (\n        txt === 'Effect.gen' ||\n        txt === 'Stream.gen' ||\n        txt === 'Layer.effect' ||\n        txt === 'Effect.sync' ||\n        txt === 'Effect.try' ||\n        txt === 'Effect.tryPromise' ||\n        txt === 'Effect.promise' ||\n        txt === 'Effect.callback' ||\n        txt === 'Effect.asyncEffect'\n      ) {\n        return { calleeText: txt, call };\n      }\n    }\n    cur = cur.getParent();\n  }\n  return undefined;\n};\n\nconst tryHasCatchField = (call: CallExpression): boolean => {\n  const { SyntaxKind } = loadTsMorph();\n  const args = call.getArguments();\n  const first = args[0];\n  if (first?.getKindName() !== 'ObjectLiteralExpression') return false;\n  const obj = first.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);\n  return obj.getProperties().some((p) => {\n    if (p.getKindName() !== 'PropertyAssignment' && p.getKindName() !== 'ShorthandPropertyAssignment') return false;\n    const name =\n      p.getKindName() === 'PropertyAssignment'\n        ? p.asKindOrThrow(SyntaxKind.PropertyAssignment).getName()\n        : p.asKindOrThrow(SyntaxKind.ShorthandPropertyAssignment).getName();\n    return name === 'catch';\n  });\n};\n\nconst checkUntaggedThrow = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const stmt of sf.getDescendantsOfKind(SyntaxKind.ThrowStatement)) {\n    const expr = stmt.getExpression();\n    if (expr?.getKindName() !== 'NewExpression') continue;\n    const newExpr = expr.asKindOrThrow(SyntaxKind.NewExpression);\n    const name = newExpr.getExpression().getText();\n    if (name !== 'Error' && name !== 'TypeError' && name !== 'RangeError') continue;\n\n    const ctxCall = findImmediateEffectCallContext(stmt);\n    if (!ctxCall) continue;\n\n    // Throws inside Effect.try({ try, catch }) or Effect.tryPromise({ try, catch })\n    // are IDIOMATIC — the catch handler maps them to a typed error. Don't flag.\n    if (\n      (ctxCall.calleeText === 'Effect.try' || ctxCall.calleeText === 'Effect.tryPromise') &&\n      tryHasCatchField(ctxCall.call)\n    ) {\n      continue;\n    }\n\n    issues.push({\n      rule: 'untagged-throw',\n      message: `throw new ${name}(...) inside ${ctxCall.calleeText} — escapes the typed error channel; use Effect.fail with a tagged error or add a catch handler.`,\n      severity: 'warning',\n      location: makeLocation(stmt, ctx.filePath),\n      suggestion:\n        'Define a Data.TaggedError class and use Effect.fail(new MyError({...})), or, inside Effect.try/tryPromise, add a catch handler that maps the thrown value to a typed error.',\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// mutable-in-concurrent\n// ===========================================================================\n\nconst checkMutableInConcurrent = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n\n  // Look for AssignmentExpression with a binary operator that mutates, inside a parallel context.\n  // Heuristic: find BinaryExpression where operator is '=' / '+=' / etc., LHS identifier resolves to outer `let`.\n  for (const bin of sf.getDescendantsOfKind(SyntaxKind.BinaryExpression)) {\n    const op = bin.getOperatorToken().getText();\n    if (\n      op !== '=' &&\n      op !== '+=' &&\n      op !== '-=' &&\n      op !== '*=' &&\n      op !== '/=' &&\n      op !== '%='\n    ) {\n      continue;\n    }\n    if (!isInsideParallelEffect(bin)) continue;\n\n    const lhs = bin.getLeft();\n    if (lhs.getKindName() !== 'Identifier') continue;\n    const id = lhs.asKindOrThrow(SyntaxKind.Identifier);\n    const sym = id.getSymbol();\n    if (!sym) continue;\n    const decls = sym.getDeclarations();\n    if (decls.length === 0) continue;\n    // Check if any declaration is a VariableDeclaration with `let` flag (not const).\n    const isLet = decls.some((d) => {\n      const vd = d.asKind(SyntaxKind.VariableDeclaration);\n      if (!vd) return false;\n      const list = vd.getParent();\n      if (!list) return false;\n      // VariableDeclarationList text starts with 'let ' or 'var '\n      const txt = list.getText();\n      return /^\\s*(let|var)\\b/.test(txt);\n    });\n    if (!isLet) continue;\n\n    // Skip if the let was declared inside the same callback as this assignment.\n    // (i.e. the let is not shared across branches.)\n    const letDecl = decls[0];\n    if (!letDecl) continue;\n    // If the closest CallExpression ancestor of the assignment is the same as\n    // the closest CallExpression ancestor of the declaration, treat as local.\n    const findParallelAncestor = (n: Node): Node | undefined => {\n      let cur: Node | undefined = n.getParent();\n      while (cur) {\n        if (cur.getKindName() === 'CallExpression') {\n          const txt = (cur as CallExpression).getExpression().getText();\n          if (\n            txt === 'Effect.all' ||\n            txt === 'Effect.allWith' ||\n            txt === 'Effect.fork' ||\n            txt === 'Effect.forkDaemon' ||\n            txt === 'Effect.forkScoped' ||\n            txt === 'Effect.forEach' ||\n            txt === 'Effect.race' ||\n            txt === 'Effect.raceAll'\n          ) {\n            return cur;\n          }\n        }\n        cur = cur.getParent();\n      }\n      return undefined;\n    };\n    const binParallel = findParallelAncestor(bin);\n    const declParallel = findParallelAncestor(letDecl);\n    if (binParallel === declParallel) continue; // declared and used inside the same parallel — still suspicious but skip\n\n    issues.push({\n      rule: 'mutable-in-concurrent',\n      message: `Mutable variable \"${id.getText()}\" assigned inside a parallel/forked Effect — race-prone.`,\n      severity: 'warning',\n      location: makeLocation(bin, ctx.filePath),\n      suggestion:\n        'Replace shared let/var with Ref.make + Ref.update, or Atomic primitives, or return values from each branch.',\n    });\n  }\n\n  return issues;\n};\n\n// ===========================================================================\n// runPromise-then-chain\n// ===========================================================================\n\nconst checkRunPromiseThenChain = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (name !== 'Effect.runPromise' && name !== 'Effect.runPromiseExit') continue;\n    // Look at the parent: is it a property-access like `.then`, `.catch`, `.finally`?\n    const parent = call.getParent();\n    if (!parent) continue;\n    if (parent.getKindName() !== 'PropertyAccessExpression') continue;\n    const pa = parent.asKindOrThrow(SyntaxKind.PropertyAccessExpression);\n    const propName = pa.getName();\n    if (propName !== 'then' && propName !== 'catch' && propName !== 'finally') continue;\n    issues.push({\n      rule: 'runPromise-then-chain',\n      message: `${name}(...).${propName}() — leaving Effect to chain Promise methods loses error typing and tracing.`,\n      severity: 'info',\n      location: makeLocation(call, ctx.filePath),\n      suggestion:\n        'Use Effect.map / Effect.flatMap / Effect.catch BEFORE runPromise. If you must escape, do it at the entry point.',\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// runSync-on-async\n// ===========================================================================\n\nconst checkRunSyncOnAsync = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  const isAsyncEffectText = (text: string): boolean =>\n    /Effect\\.promise\\b/.test(text) ||\n    /Effect\\.tryPromise\\b/.test(text) ||\n    /Effect\\.async\\b/.test(text) ||\n    /Effect\\.asyncEffect\\b/.test(text) ||\n    /Effect\\.sleep\\b/.test(text);\n\n  // Build a set of file-level identifiers that look async-tainted: variables initialised\n  // with Effect.promise / Effect.tryPromise / Effect.callback* / Effect.sleep.\n  const asyncIdents = new Set<string>();\n  for (const vd of sf.getDescendantsOfKind(SyntaxKind.VariableDeclaration)) {\n    const init = vd.getInitializer();\n    if (!init) continue;\n    const text = init.getText();\n    if (isAsyncEffectText(text)) {\n      const name = vd.getName();\n      asyncIdents.add(name);\n    }\n  }\n\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const callee = calleeText(call);\n    if (callee !== 'Effect.runSync' && callee !== 'Effect.runSyncExit') continue;\n    const args = call.getArguments();\n    if (args.length === 0) continue;\n    const argText = args[0]?.getText() ?? '';\n    // Direct uses\n    if (isAsyncEffectText(argText)) {\n      issues.push({\n        rule: callee === 'Effect.runSync' ? 'runSync-on-async' : 'runSyncExit-on-async',\n        message: `${callee} on an effect that uses Effect.promise/tryPromise/async/sleep — will throw at runtime.`,\n        severity: 'error',\n        location: makeLocation(call, ctx.filePath),\n        suggestion:\n          callee === 'Effect.runSync'\n            ? 'Use Effect.runPromise (or Effect.runPromiseExit) for async effects.'\n            : 'Use Effect.runPromiseExit for async effects.',\n      });\n      continue;\n    }\n    // Refers to a known async-tainted identifier\n    const referenced = argText.split(/[^A-Za-z0-9_$]/).filter(Boolean);\n    if (referenced.some((id) => asyncIdents.has(id))) {\n      issues.push({\n        rule: callee === 'Effect.runSync' ? 'runSync-on-async' : 'runSyncExit-on-async',\n        message: `${callee} on \"${argText}\" — that effect transitively uses Effect.promise/tryPromise/async.`,\n        severity: 'error',\n        location: makeLocation(call, ctx.filePath),\n        suggestion:\n          callee === 'Effect.runSync'\n            ? 'Use Effect.runPromise (or Effect.runPromiseExit) for async effects.'\n            : 'Use Effect.runPromiseExit for async effects.',\n      });\n    }\n  }\n  return issues;\n};\n\n// ===========================================================================\n// live-layer-in-test\n// ===========================================================================\n\nconst TEST_FILE_PATTERN = /\\.(test|spec)\\.(ts|tsx|js|jsx|mts|cts)$/;\nconst TEST_DIR_PATTERN = /(^|[\\\\/])(__tests__|test|tests)([\\\\/]|$)/;\nconst isTestFilePath = (filePath: string): boolean =>\n  TEST_FILE_PATTERN.test(filePath) || TEST_DIR_PATTERN.test(filePath);\n\nconst checkLiveLayerInTest = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  if (!isTestFilePath(ctx.filePath)) return [];\n  const issues: LintIssue[] = [];\n  const seen = new Set<string>();\n  const isIntegrationTest =\n    /(^|[\\\\/])(integration)([\\\\/]|[.])/i.test(ctx.filePath);\n  const isRuntimeUse = (node: Node): boolean => {\n    const parent = node.getParent();\n    if (!parent) return true;\n    const pk = parent.getKindName();\n    if (\n      pk === 'ImportSpecifier' ||\n      pk === 'ImportClause' ||\n      pk === 'NamespaceImport' ||\n      pk === 'NamedImports' ||\n      pk === 'TypeReference' ||\n      pk === 'TypeAliasDeclaration' ||\n      pk === 'InterfaceDeclaration' ||\n      pk === 'TypeLiteral'\n    ) {\n      return false;\n    }\n    return true;\n  };\n  for (const id of sf.getDescendantsOfKind(SyntaxKind.Identifier)) {\n    const name = id.getText();\n    if (!name.endsWith(\"Live\")) continue;\n    if (name === 'Live') continue;\n    // Live LAYERS are PascalCase constants (UserRepoLive, DbLive).\n    // Skip camelCase helpers (runLive, connectLive) and TTL API methods\n    // like describeTimeToLive / updateTimeToLive.\n    if (!/^[A-Z]/.test(name)) continue;\n    if (name.endsWith(\"TimeToLive\")) continue;\n    if (seen.has(name)) continue;\n    const refs = id.findReferencesAsNodes().filter((ref) =>\n      ref.getSourceFile().getFilePath() === sf.getFilePath(),\n    );\n    const runtimeRef = refs.find((ref) => isRuntimeUse(ref));\n    if (!runtimeRef) continue;\n    seen.add(name);\n    issues.push({\n      rule: 'live-layer-in-test',\n      message: `Test file references \"${name}\" — a Live layer should not be wired into tests.`,\n      severity: isIntegrationTest ? 'info' : 'warning',\n      location: makeLocation(runtimeRef, ctx.filePath),\n      suggestion:\n        'Provide a Test layer (e.g. ServiceTest) or use Layer.succeed with a stub implementation.',\n    });\n    // Only flag the first occurrence per identifier per file.\n  }\n  return issues;\n};\n\n// ===========================================================================\n// nondeterministic-test-api\n// ===========================================================================\n\nconst checkNondeterministicTestApi = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  if (!isTestFilePath(ctx.filePath)) return [];\n  const issues: LintIssue[] = [];\n\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (name === 'Date.now' || name === 'Math.random') {\n      issues.push({\n        rule: 'nondeterministic-test-api',\n        message: `${name}() in test code introduces non-determinism.`,\n        severity: 'warning',\n        location: makeLocation(call, ctx.filePath),\n        suggestion:\n          name === 'Date.now'\n            ? 'Use Effect Clock/TestClock or inject a deterministic timestamp source.'\n            : 'Inject a deterministic RNG or use Effect Random/Test services in tests.',\n      });\n    }\n  }\n\n  for (const ctor of sf.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n    if (ctor.getExpression().getText() !== 'Date') continue;\n    const args = ctor.getArguments();\n    if (args.length > 0) continue;\n    issues.push({\n      rule: 'nondeterministic-test-api',\n      message: 'new Date() in test code introduces non-determinism.',\n      severity: 'warning',\n      location: makeLocation(ctor, ctx.filePath),\n      suggestion: 'Use a fixed date literal or inject time via Effect Clock/TestClock.',\n    });\n  }\n\n  return issues;\n};\n\n// ===========================================================================\n// detached-fiber-in-test\n// ===========================================================================\n\nconst checkDetachedFiberInTest = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  if (!isTestFilePath(ctx.filePath)) return [];\n  const issues: LintIssue[] = [];\n\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (\n      name !== 'Effect.runFork' &&\n      name !== 'Effect.runForkWith' &&\n      name !== 'Runtime.runFork'\n    ) {\n      continue;\n    }\n    issues.push({\n      rule: 'detached-fiber-in-test',\n      message: `${name}(...) in test code can outlive the test and cause flakiness.`,\n      severity: 'warning',\n      location: makeLocation(call, ctx.filePath),\n      suggestion:\n        'Prefer runPromise/runPromiseExit and await completion, or keep and join/interrupt the returned Fiber explicitly.',\n    });\n  }\n\n  return issues;\n};\n\n// ===========================================================================\n// sleep-without-testclock\n// ===========================================================================\n\nconst checkSleepWithoutTestClockInTest = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  if (!isTestFilePath(ctx.filePath)) return [];\n  const hasTestClock = sf\n    .getDescendantsOfKind(SyntaxKind.Identifier)\n    .some((id) => id.getText() === 'TestClock');\n  if (hasTestClock) return [];\n  const issues: LintIssue[] = [];\n\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (name !== 'Effect.sleep') continue;\n    issues.push({\n      rule: 'sleep-without-testclock',\n      message: 'Effect.sleep(...) in test code without TestClock usage makes tests slow and timing-sensitive.',\n      severity: 'info',\n      location: makeLocation(call, ctx.filePath),\n      suggestion:\n        'Use TestClock.adjust/adjustTo and provide test clock services to keep tests deterministic and fast.',\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// promise-api-in-gen\n// ===========================================================================\n\nconst PROMISE_API_REPLACEMENTS: Record<string, string> = {\n  'Promise.all': 'Effect.all',\n  'Promise.allSettled': 'Effect.all (with { mode: \"either\" })',\n  'Promise.race': 'Effect.race / Effect.raceAll',\n  'Promise.any': 'Effect.raceAll',\n  'Promise.resolve': 'Effect.succeed',\n  'Promise.reject': 'Effect.fail',\n};\n\nconst checkPromiseApiInGen = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    const replacement = PROMISE_API_REPLACEMENTS[name];\n    if (!replacement) continue;\n    if (!isInsideEffectGen(call)) continue;\n    if (isInsideEffectSyncOrTry(call)) continue;\n    issues.push({\n      rule: 'promise-api-in-gen',\n      message: `${name}(...) inside Effect.gen — Promise APIs bypass interruption and typed errors; use ${replacement}.`,\n      severity: 'warning',\n      location: makeLocation(call, ctx.filePath),\n      suggestion: `Replace ${name}(...) with ${replacement}(...) so Effect can manage concurrency and interruption.`,\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// forEach-without-concurrency\n// ===========================================================================\n\nconst checkForEachWithoutConcurrency = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (name !== 'Effect.forEach' && name !== 'Stream.runForEach') continue;\n    const args = call.getArguments();\n    // Two-arg form: Effect.forEach(iterable, fn) — no options object.\n    // Three-arg form: Effect.forEach(iterable, fn, options) — explicit.\n    if (args.length !== 2) continue;\n    issues.push({\n      rule: 'forEach-without-concurrency',\n      message: `${name}(...) without options — defaults to sequential execution; make the choice explicit.`,\n      severity: 'info',\n      location: makeLocation(call, ctx.filePath),\n      suggestion:\n        'Pass an explicit options object: { concurrency: \"unbounded\" } for parallel, or { concurrency: 1 } if sequential is intentional.',\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// identity-catch\n// ===========================================================================\n\n/**\n * A \"catch handler\" is identity when it just re-fails with the same value it\n * received, e.g. `Effect.catch((e) => Effect.fail(e))`. These add noise\n * without changing semantics and are usually leftover from refactors.\n */\n\nconst CATCH_RECEIVERS: Record<string, 'Effect.fail' | 'Effect.failCause' | 'Effect.die'> = {\n  'Effect.catch': 'Effect.fail',\n  'Effect.catchCause': 'Effect.failCause',\n  'Effect.catchDefect': 'Effect.die',\n  'Effect.catchTag': 'Effect.fail',\n};\n\nconst isIdentityHandler = (\n  argNode: Node,\n  expectedReFail: 'Effect.fail' | 'Effect.failCause' | 'Effect.die',\n): boolean => {\n  const kind = argNode.getKindName();\n  if (kind !== 'ArrowFunction' && kind !== 'FunctionExpression') return false;\n  const text = argNode.getText();\n  // (NAME) => Effect.fail(NAME) — optional type annotation, optional braces.\n  const arrow = /^\\(\\s*([A-Za-z_$][A-Za-z0-9_$]*)\\s*(?::[^)]*)?\\)\\s*=>\\s*([\\s\\S]*)$/.exec(text);\n  const fn = /^function\\s*\\*?\\s*\\(\\s*([A-Za-z_$][A-Za-z0-9_$]*)\\s*(?::[^)]*)?\\)\\s*\\{\\s*return\\s+([\\s\\S]+?);?\\s*\\}$/.exec(text);\n  const match = arrow ?? fn;\n  if (!match) return false;\n  const param = match[1];\n  let body = (match[2] ?? '').trim();\n  // Strip leading `{ return ` / trailing `; }` if the arrow uses a block body.\n  const block = /^\\{\\s*return\\s+([\\s\\S]+?);?\\s*\\}$/.exec(body);\n  if (block) body = block[1]!.trim();\n  body = body.replace(/;\\s*$/, '');\n  return body === `${expectedReFail}(${param})`;\n};\n\nconst findFunctionArg = (call: CallExpression): Node | undefined => {\n  // Scan from the end — the handler is conventionally the last argument.\n  const args = call.getArguments();\n  for (let i = args.length - 1; i >= 0; i--) {\n    const arg = args[i]!;\n    const k = arg.getKindName();\n    if (k === 'ArrowFunction' || k === 'FunctionExpression') return arg;\n  }\n  return undefined;\n};\n\nconst checkIdentityCatch = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    const expectedReFail = CATCH_RECEIVERS[name];\n    if (!expectedReFail) continue;\n    const handler = findFunctionArg(call);\n    if (!handler) continue;\n    if (!isIdentityHandler(handler, expectedReFail)) continue;\n    issues.push({\n      rule: 'identity-catch',\n      message: `${name}(...) handler just re-fails the same value — the catch is a no-op.`,\n      severity: 'warning',\n      location: makeLocation(call, ctx.filePath),\n      suggestion: `Remove the ${name}(...) call, or replace it with a real recovery / mapping handler.`,\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// empty-effect-all\n// ===========================================================================\n\nconst checkEmptyEffectAll = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (name !== 'Effect.all' && name !== 'Effect.allWith') continue;\n    const first = call.getArguments()[0];\n    if (!first) continue;\n    const k = first.getKindName();\n    let empty = false;\n    if (k === 'ArrayLiteralExpression') {\n      const arr = first.asKindOrThrow(SyntaxKind.ArrayLiteralExpression);\n      empty = arr.getElements().length === 0;\n    } else if (k === 'ObjectLiteralExpression') {\n      const obj = first.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);\n      empty = obj.getProperties().length === 0;\n    }\n    if (!empty) continue;\n    issues.push({\n      rule: 'empty-effect-all',\n      message: `${name}(${k === 'ArrayLiteralExpression' ? '[]' : '{}'}) — always succeeds with an empty result; usually dead code.`,\n      severity: 'info',\n      location: makeLocation(call, ctx.filePath),\n      suggestion:\n        'Remove this branch, or replace with Effect.succeed([]) / Effect.succeed({}) if a literal empty value is intentional.',\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// layer-duplicate-merge\n// ===========================================================================\n\nconst checkLayerDuplicateMerge = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (name !== 'Layer.merge' && name !== 'Layer.mergeAll' && name !== 'Layer.provideMerge') continue;\n    const args = call.getArguments();\n    if (args.length < 2) continue;\n    const seen = new Map<string, number>();\n    args.forEach((arg, idx) => {\n      const text = arg.getText().trim();\n      // Only flag clearly identifier-like arguments — skip inline Layer.succeed/effect calls.\n      if (!/^[A-Za-z_$][A-Za-z0-9_$.]*$/.test(text)) return;\n      const prev = seen.get(text);\n      if (prev === undefined) {\n        seen.set(text, idx);\n      } else {\n        issues.push({\n          rule: 'layer-duplicate-merge',\n          message: `${name}(...) lists \"${text}\" more than once — later occurrences override earlier ones.`,\n          severity: 'warning',\n          location: makeLocation(arg, ctx.filePath),\n          suggestion:\n            'Remove the duplicate, or rename the second argument if you meant a different layer.',\n        });\n      }\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// schedule-unbounded\n// ===========================================================================\n\n/**\n * Looks for `Schedule.forever` and `Schedule.spaced(...)` usages that are NOT\n * composed with a bounding combinator inside the same surrounding pipe / call\n * chain. Common bounding combinators: `Schedule.upTo`, `Schedule.recurs`,\n * `Schedule.intersect`, `Schedule.tapOutput`, and `.compose`.\n *\n * This is intentionally conservative: we only check the immediate textual\n * `pipe(...)` ancestor (or the chain of property accesses) of the schedule\n * expression. False negatives are preferred to false positives.\n */\nconst SCHEDULE_BOUNDS = [\n  'Schedule.upTo',\n  'Schedule.recurs',\n  'Schedule.intersect',\n  'Schedule.intersectWith',\n  'Schedule.compose',\n  'Schedule.union',\n  'Schedule.unionWith',\n  'Schedule.upToFirstAttempt',\n];\n\nconst findEnclosingPipeOrChain = (node: Node): Node | undefined => {\n  let cur: Node | undefined = node.getParent();\n  while (cur) {\n    const k = cur.getKindName();\n    if (k === 'CallExpression') {\n      const expr = (cur as CallExpression).getExpression().getText();\n      if (expr === 'pipe' || expr.endsWith('.pipe')) return cur;\n    }\n    if (k === 'PropertyAccessExpression') {\n      cur = cur.getParent();\n      continue;\n    }\n    if (k === 'SourceFile' || k === 'Block' || k === 'VariableStatement' || k === 'ExpressionStatement') {\n      return undefined;\n    }\n    cur = cur.getParent();\n  }\n  return undefined;\n};\n\nconst checkScheduleUnbounded = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  const candidates: { node: Node; label: string }[] = [];\n\n  // Schedule.forever (an identifier / property access, not a call)\n  for (const pa of sf.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression)) {\n    if (pa.getText() === 'Schedule.forever') {\n      // If parent is a property access (e.g. Schedule.forever.foo), skip — covered separately.\n      const parent = pa.getParent();\n      if (parent?.getKindName() === 'PropertyAccessExpression') continue;\n      candidates.push({ node: pa, label: 'Schedule.forever' });\n    }\n  }\n  // Schedule.spaced(...) — a call.\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    if (calleeText(call) === 'Schedule.spaced') {\n      candidates.push({ node: call, label: 'Schedule.spaced(...)' });\n    }\n  }\n\n  for (const { node, label } of candidates) {\n    // Stream context: Stream.repeat / fromSchedule / tick — infinite is by design.\n    // The stream consumer controls demand; the schedule does not \"retry forever\" — it\n    // emits forever, and `Stream.take(n)` etc. bound it at the consumer.\n    let isStreamScheduleConsumer = false;\n    {\n      let cur: Node | undefined = node.getParent();\n      while (cur) {\n        if (cur.getKindName() === 'CallExpression') {\n          const callee = (cur as CallExpression).getExpression().getText();\n          if (\n            callee === 'Stream.repeat' ||\n            callee === 'Stream.repeatEffect' ||\n            callee === 'Stream.repeatEffectOption' ||\n            callee === 'Stream.fromSchedule' ||\n            callee === 'Stream.tick' ||\n            callee === 'Stream.repeatValue'\n          ) {\n            isStreamScheduleConsumer = true;\n            break;\n          }\n        }\n        cur = cur.getParent();\n      }\n    }\n    if (isStreamScheduleConsumer) continue;\n\n    const pipeOrChain = findEnclosingPipeOrChain(node);\n    let containerText = pipeOrChain ? pipeOrChain.getText() : '';\n    if (!containerText) {\n      // Look at the enclosing variable / argument expression as a fallback.\n      let cur: Node | undefined = node.getParent();\n      while (cur) {\n        const k = cur.getKindName();\n        if (\n          k === 'VariableDeclaration' ||\n          k === 'ReturnStatement' ||\n          k === 'PropertyAssignment' ||\n          k === 'CallExpression'\n        ) {\n          containerText = cur.getText();\n          break;\n        }\n        cur = cur.getParent();\n      }\n    }\n    const bounded = SCHEDULE_BOUNDS.some((b) => containerText.includes(b));\n    if (bounded) continue;\n    issues.push({\n      rule: 'schedule-unbounded',\n      message: `${label} is not composed with a bounding combinator — retries can run forever.`,\n      severity: 'info',\n      location: makeLocation(node, ctx.filePath),\n      suggestion:\n        'Compose with Schedule.upTo / Schedule.recurs / Schedule.intersect to cap total elapsed time or attempt count.',\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// config-secret-without-redacted\n// ===========================================================================\n\nconst SECRET_TOKENS = [\n  'password',\n  'passwd',\n  'secret',\n  'token',\n  'api_key',\n  'apikey',\n  'private_key',\n  'privatekey',\n  'credential',\n  'auth_key',\n  'authkey',\n  'access_key',\n  'accesskey',\n  'session_key',\n  'sessionkey',\n  'client_secret',\n  'refresh_token',\n];\n\nconst stringLiteralValue = (node: Node): string | undefined => {\n  const k = node.getKindName();\n  if (k !== 'StringLiteral' && k !== 'NoSubstitutionTemplateLiteral') return undefined;\n  // Strip the surrounding quotes from the raw text.\n  const raw = node.getText();\n  return raw.slice(1, -1);\n};\n\nconst looksLikeSecret = (value: string): string | undefined => {\n  const lower = value.toLowerCase();\n  for (const tok of SECRET_TOKENS) {\n    if (lower.includes(tok)) return tok;\n  }\n  return undefined;\n};\n\nconst checkConfigSecretWithoutRedacted = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    // Only flag the explicitly-cleartext readers; Config.redacted is fine.\n    if (\n      name !== 'Config.string' &&\n      name !== 'Config.nonEmptyString' &&\n      name !== 'Config.secret' // older Effect alias, also visible-in-logs\n    ) {\n      continue;\n    }\n    const first = call.getArguments()[0];\n    if (!first) continue;\n    const lit = stringLiteralValue(first);\n    if (!lit) continue;\n    const matched = looksLikeSecret(lit);\n    if (!matched) continue;\n    issues.push({\n      rule: 'config-secret-without-redacted',\n      message: `${name}(${JSON.stringify(lit)}) reads a likely-secret env var as plain text — leaks through logs/errors.`,\n      severity: 'warning',\n      location: makeLocation(call, ctx.filePath),\n      suggestion: `Use Config.redacted(${JSON.stringify(lit)}) so the value is hidden from logs/inspect (matched on \"${matched}\").`,\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// return-effect-from-sync\n// ===========================================================================\n\nconst EFFECT_CONSTRUCTOR_NAMES = new Set<string>([\n  'Effect.succeed',\n  'Effect.fail',\n  'Effect.die',\n  'Effect.failSync',\n  'Effect.gen',\n  'Effect.sync',\n  'Effect.try',\n  'Effect.promise',\n  'Effect.tryPromise',\n  'Effect.callback',\n  'Effect.asyncEffect',\n  'Effect.flatMap',\n  'Effect.map',\n  'Effect.tap',\n  'Effect.all',\n  'Effect.zip',\n  'Effect.zipWith',\n  'Effect.race',\n  'Effect.raceAll',\n  'Effect.forEach',\n  'Effect.fromOption',\n  'Effect.fromEither',\n  'Effect.fromNullable',\n  'Effect.never',\n  'Effect.suspend',\n]);\n\nconst checkReturnEffectFromSync = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (name !== 'Effect.sync' && name !== 'Effect.try') continue;\n    // Effect.try can take an object form { try, catch } — use first non-options arrow.\n    let arrow: Node | undefined;\n    for (const arg of call.getArguments()) {\n      const k = arg.getKindName();\n      if (k === 'ArrowFunction' || k === 'FunctionExpression') {\n        arrow = arg;\n        break;\n      }\n      if (k === 'ObjectLiteralExpression') {\n        const obj = arg.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);\n        for (const p of obj.getProperties()) {\n          if (p.getKindName() !== 'PropertyAssignment') continue;\n          const pa = p.asKindOrThrow(SyntaxKind.PropertyAssignment);\n          if (pa.getName() !== 'try') continue;\n          const init = pa.getInitializer();\n          if (!init) continue;\n          const initK = init.getKindName();\n          if (initK === 'ArrowFunction' || initK === 'FunctionExpression') {\n            arrow = init;\n          }\n        }\n      }\n      if (arrow) break;\n    }\n    if (!arrow) continue;\n    // Look at the body expression. We want to flag when the body's outermost\n    // call expression's callee is an Effect.* constructor.\n    let bodyExpr: Node | undefined;\n    if (arrow.getKindName() === 'ArrowFunction') {\n      const fn = arrow.asKindOrThrow(SyntaxKind.ArrowFunction);\n      const b = fn.getBody();\n      const bk = b.getKindName();\n      if (bk === 'Block') {\n        // function-style body: find a single `return X;` and grab X.\n        const block = b.asKindOrThrow(SyntaxKind.Block);\n        const stmts = block.getStatements();\n        if (stmts.length !== 1) continue;\n        const only = stmts[0]!;\n        if (only.getKindName() !== 'ReturnStatement') continue;\n        bodyExpr = only.asKindOrThrow(SyntaxKind.ReturnStatement).getExpression();\n      } else {\n        bodyExpr = b;\n      }\n    } else {\n      const fn = arrow.asKindOrThrow(SyntaxKind.FunctionExpression);\n      const block = fn.getBody().asKind(SyntaxKind.Block);\n      if (!block) continue;\n      const stmts = block.getStatements();\n      if (stmts.length !== 1) continue;\n      const only = stmts[0]!;\n      if (only.getKindName() !== 'ReturnStatement') continue;\n      bodyExpr = only.asKindOrThrow(SyntaxKind.ReturnStatement).getExpression();\n    }\n    if (bodyExpr?.getKindName() !== 'CallExpression') continue;\n    const inner = bodyExpr.asKindOrThrow(SyntaxKind.CallExpression);\n    const innerName = inner.getExpression().getText();\n    if (!EFFECT_CONSTRUCTOR_NAMES.has(innerName)) continue;\n    issues.push({\n      rule: 'return-effect-from-sync',\n      message: `${name}(() => ${innerName}(...)) — wraps an Effect inside an Effect; result type becomes Effect<Effect<...>>.`,\n      severity: 'warning',\n      location: makeLocation(call, ctx.filePath),\n      suggestion:\n        name === 'Effect.sync'\n          ? `Drop the Effect.sync wrapper and use ${innerName}(...) directly, or use Effect.suspend(() => ${innerName}(...)) if you need lazy evaluation.`\n          : `Use Effect.suspend(() => ${innerName}(...)) for lazy evaluation, or Effect.flatMap if you need the inner Effect to run.`,\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// yield-promise\n// ===========================================================================\n\n/**\n * `yield* somePromise` inside an `Effect.gen` body crashes at runtime — the\n * runtime expects Effects. Detect when the operand is a NewExpression that\n * constructs a Promise, a CallExpression with `.then` on the receiver, or\n * literal `Promise.resolve/reject/all/...` calls.\n */\nconst checkYieldPromise = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n\n  // YieldExpressions whose asterisk is set (i.e. `yield* x`) and operand looks like a Promise.\n  for (const ye of sf.getDescendantsOfKind(SyntaxKind.YieldExpression)) {\n    if (!ye.getAsteriskToken()) continue;\n    if (!isInsideEffectGen(ye)) continue;\n    const operand = ye.getExpression();\n    if (!operand) continue;\n    const k = operand.getKindName();\n\n    // `yield* new Promise(...)`\n    if (k === 'NewExpression') {\n      const ne = operand.asKindOrThrow(SyntaxKind.NewExpression);\n      if (ne.getExpression().getText() === 'Promise') {\n        issues.push({\n          rule: 'yield-promise',\n          message: 'yield* new Promise(...) — Effect.gen requires an Effect, not a Promise; this throws at runtime.',\n          severity: 'error',\n          location: makeLocation(operand, ctx.filePath),\n          suggestion:\n            'Wrap the Promise: yield* Effect.promise(() => new Promise(...)) or Effect.tryPromise({ try, catch }).',\n        });\n        continue;\n      }\n    }\n\n    // `yield* Promise.all(...)`, `Promise.resolve(...)`, etc., or `yield* fetch(...)`.\n    if (k === 'CallExpression') {\n      const ce = operand.asKindOrThrow(SyntaxKind.CallExpression);\n      const calleeExpr = ce.getExpression();\n      const callee = calleeExpr.getText();\n      const isPromiseStatic =\n        callee === 'Promise.all' ||\n        callee === 'Promise.allSettled' ||\n        callee === 'Promise.race' ||\n        callee === 'Promise.any' ||\n        callee === 'Promise.resolve' ||\n        callee === 'Promise.reject';\n      // For `fetch`, verify the identifier resolves to the GLOBAL fetch — not\n      // a local destructure, parameter, or function variable. A symbol with\n      // local declarations means it's shadowed; skip to avoid a false-positive\n      // \"runtime crash\" diagnostic on legitimate Effect-returning helpers\n      // named `fetch` (common in HTTP-client wrappers like Effect platform).\n      let isGlobalFetch = false;\n      if (callee === 'fetch' && calleeExpr.getKindName() === 'Identifier') {\n        const ident = calleeExpr.asKindOrThrow(SyntaxKind.Identifier);\n        const sym = ident.getSymbol();\n        if (!sym) {\n          isGlobalFetch = true;\n        } else {\n          const decls = sym.getDeclarations();\n          // If none of the declarations are local to a TS source file (or the\n          // only declarations are ambient lib.dom.d.ts entries), treat as global.\n          const hasLocalDecl = decls.some((d) => {\n            const sf2 = d.getSourceFile();\n            return !sf2.isDeclarationFile();\n          });\n          isGlobalFetch = !hasLocalDecl;\n        }\n      }\n      if (isPromiseStatic || isGlobalFetch) {\n        issues.push({\n          rule: 'yield-promise',\n          message: `yield* ${callee}(...) — this returns a Promise, not an Effect; throws at runtime in Effect.gen.`,\n          severity: 'error',\n          location: makeLocation(operand, ctx.filePath),\n          suggestion: isGlobalFetch\n            ? 'Use yield* Effect.tryPromise({ try: () => fetch(...), catch: (e) => e }).'\n            : `Use yield* Effect.tryPromise({ try: () => ${callee}(...), catch: (e) => e }) or the matching Effect.* combinator.`,\n        });\n      }\n    }\n  }\n  return issues;\n};\n\n// ===========================================================================\n// barrel-import-from-effect\n// ===========================================================================\n\n/**\n * Mirrors the Effect maintainers' own ESLint rule\n * `@effect/no-import-from-barrel-package` as a deterministic source check.\n * They enforce this across the Effect repo, effect-ts-examples, effect-nextjs,\n * and examples, with packageNames = [\"effect\", \"@effect/platform\", \"@effect/sql\"].\n *\n * Tree-shaking: `import { Effect } from \"effect\"` pulls the barrel; the\n * recommended form is `import * as Effect from \"effect/Effect\"` so bundlers\n * can drop unused submodules.\n */\n\nconst BARREL_PACKAGES = new Set<string>([\n  'effect',\n  '@effect/platform',\n  '@effect/platform-node',\n  '@effect/platform-bun',\n  '@effect/platform-browser',\n  '@effect/sql',\n  '@effect/cluster',\n  '@effect/rpc',\n]);\n\n/**\n * Test/dtslint files are exempt from the tree-shaking rule — that matches the\n * Effect team's own ESLint config (`packages/*&#47;src/**&#47;*` scope only).\n */\nconst isTestOrFixtureFile = (filePath: string): boolean =>\n  /\\.(test|spec)\\.(ts|tsx|mts|cts|js|jsx)$/i.test(filePath) ||\n  /\\.tst\\.ts$/i.test(filePath) ||\n  /(^|\\/)(test|tests|__tests__|integration|dtslint|fixtures?|examples?|scratchpad|test-utils)\\//i.test(filePath);\n\nconst checkBarrelImportFromEffect = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  // Match the Effect team's own ESLint scope: only `packages/*/src/**/*`.\n  // Skip tests, dtslint, fixtures, examples.\n  if (isTestOrFixtureFile(ctx.filePath)) return [];\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const decl of sf.getDescendantsOfKind(SyntaxKind.ImportDeclaration)) {\n    // Skip type-only imports — those have no bundling cost.\n    if (decl.isTypeOnly()) continue;\n    const spec = decl.getModuleSpecifierValue();\n    if (!spec || !BARREL_PACKAGES.has(spec)) continue;\n    const named = decl.getNamedImports();\n    for (const ni of named) {\n      if (ni.isTypeOnly()) continue;\n      const moduleName = ni.getName();\n      const localName = ni.getAliasNode()?.getText() ?? moduleName;\n      issues.push({\n        rule: 'barrel-import-from-effect',\n        message: `import { ${moduleName} } from \"${spec}\" — barrel imports defeat tree-shaking; the Effect team's own ESLint config flags this.`,\n        severity: 'info',\n        location: makeLocation(ni, ctx.filePath),\n        suggestion: `Replace with: import * as ${localName} from \"${spec}/${moduleName}\"`,\n      });\n    }\n  }\n  return issues;\n};\n\n// ===========================================================================\n// array-push-spread\n// ===========================================================================\n\n/**\n * V8 perf footgun: `arr.push(...xs)` spreads `xs` onto the call stack and can\n * overflow / OOM with large arrays. The Effect team enforces this rule across\n * their codebase via `no-restricted-syntax` and only opts out in a handful of\n * OpenTelemetry batching paths with `// eslint-disable-next-line`.\n *\n * Source: ___temp/repos/effect/eslint.config.mjs:72-78.\n */\nconst checkArrayPushSpread = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const expr = call.getExpression();\n    if (expr.getKindName() !== 'PropertyAccessExpression') continue;\n    const pa = expr.asKindOrThrow(SyntaxKind.PropertyAccessExpression);\n    if (pa.getName() !== 'push') continue;\n    const args = call.getArguments();\n    const hasSpread = args.some((a) => a.getKindName() === 'SpreadElement');\n    if (!hasSpread) continue;\n    issues.push({\n      rule: 'array-push-spread',\n      message: 'arr.push(...xs) — spreading onto Array#push can stack-overflow on large arrays (V8 footgun; Effect-team enforced).',\n      severity: 'warning',\n      location: makeLocation(call, ctx.filePath),\n      suggestion:\n        'Use a loop (for (const x of xs) arr.push(x)) or arr = arr.concat(xs) for unbounded inputs.',\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// unsafe-api-usage\n// ===========================================================================\n\n/**\n * Flags direct usage of Effect/Runtime unsafe APIs that bypass typed guarantees\n * or runtime safety checks. This is deterministic and source-only; it does not\n * attempt whole-program flow analysis.\n */\nconst isUnsafeApiCallee = (callee: string): boolean =>\n  callee.startsWith('Effect.unsafe') ||\n  callee.startsWith('Runtime.unsafe') ||\n  callee.includes('.unsafeRun') ||\n  callee.includes('.unsafeFork') ||\n  callee.includes('.unsafeRunPromise');\n\nconst checkUnsafeApiUsage = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (!isUnsafeApiCallee(name)) continue;\n    issues.push({\n      rule: 'unsafe-api-usage',\n      message: `${name}(...) uses an unsafe runtime API; prefer safe constructors/combinators when possible.`,\n      severity: 'warning',\n      location: makeLocation(call, ctx.filePath),\n      suggestion:\n        'Use safe Effect APIs (Effect.gen / Effect.scoped / Effect.runPromise) or isolate this call behind a well-reviewed boundary.',\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// tryPromise-without-catch\n// ===========================================================================\n\n/**\n * `Effect.tryPromise(fn)` (short form, no `{ try, catch }` object) collapses\n * thrown errors into `UnknownException` — the typed error channel is lost.\n *\n * The Effect docs recommend the object form for production code:\n *\n *   Effect.tryPromise({\n *     try: () => fetchData(),\n *     catch: (e) => new MyError({ cause: e }),\n *   })\n *\n * Surfaced by real code in effect-start/src/Start.ts. Same applies to\n * `Effect.try(fn)` short form.\n */\nconst checkTryPromiseWithoutCatch = (\n  sf: SourceFile,\n  ctx: SourceLintContext,\n): LintIssue[] => {\n  const { SyntaxKind } = loadTsMorph();\n  const issues: LintIssue[] = [];\n  for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n    const name = calleeText(call);\n    if (name !== 'Effect.tryPromise' && name !== 'Effect.try') continue;\n    const args = call.getArguments();\n    if (args.length !== 1) continue;\n    const first = args[0]!;\n    const k = first.getKindName();\n    // Object literal form { try, catch } — the recommended shape.\n    if (k === 'ObjectLiteralExpression') continue;\n    // Anything else (ArrowFunction / FunctionExpression / Identifier referencing a fn)\n    // is the short form — flag it.\n    issues.push({\n      rule: 'tryPromise-without-catch',\n      message: `${name}(fn) short form — thrown errors collapse to UnknownException; the typed error channel is lost.`,\n      severity: 'info',\n      location: makeLocation(call, ctx.filePath),\n      suggestion: `Use ${name}({ try: () => ..., catch: (e) => new MyError({ cause: e }) }) to preserve typed errors.`,\n    });\n  }\n  return issues;\n};\n\n// ===========================================================================\n// Runner\n// ===========================================================================\n\nexport interface SourceLintResult {\n  readonly filePath: string;\n  readonly issues: readonly LintIssue[];\n}\n\nexport const lintSourceFile = (\n  sf: SourceFile,\n  filePath?: string,\n): SourceLintResult => {\n  const fp = filePath ?? sf.getFilePath();\n  // Skip dtslint type-test files entirely. These intentionally use degenerate\n  // runtime patterns (Effect.all({}), Effect.fail(new Error(...))) purely to\n  // assert on inferred types via twoslash/dtslint, not as runtime code.\n  if (/\\.tst\\.ts$/i.test(fp)) {\n    return { filePath: fp, issues: [] };\n  }\n  const ctx: SourceLintContext = { filePath: fp };\n  const issues: LintIssue[] = [];\n  issues.push(...checkUntaggedThrow(sf, ctx));\n  issues.push(...checkMutableInConcurrent(sf, ctx));\n  issues.push(...checkRunPromiseThenChain(sf, ctx));\n  issues.push(...checkRunSyncOnAsync(sf, ctx));\n  issues.push(...checkLiveLayerInTest(sf, ctx));\n  issues.push(...checkNondeterministicTestApi(sf, ctx));\n  issues.push(...checkDetachedFiberInTest(sf, ctx));\n  issues.push(...checkSleepWithoutTestClockInTest(sf, ctx));\n  issues.push(...checkPromiseApiInGen(sf, ctx));\n  issues.push(...checkForEachWithoutConcurrency(sf, ctx));\n  issues.push(...checkIdentityCatch(sf, ctx));\n  issues.push(...checkEmptyEffectAll(sf, ctx));\n  issues.push(...checkLayerDuplicateMerge(sf, ctx));\n  issues.push(...checkScheduleUnbounded(sf, ctx));\n  issues.push(...checkConfigSecretWithoutRedacted(sf, ctx));\n  issues.push(...checkReturnEffectFromSync(sf, ctx));\n  issues.push(...checkYieldPromise(sf, ctx));\n  issues.push(...checkBarrelImportFromEffect(sf, ctx));\n  issues.push(...checkArrayPushSpread(sf, ctx));\n  issues.push(...checkTryPromiseWithoutCatch(sf, ctx));\n  issues.push(...checkUnsafeApiUsage(sf, ctx));\n\n  // Disable pragmas. Build a map keyed by line: lineNumber -> Set<rule|\"all\">\n  // Recognised forms (looked at on the immediately preceding line):\n  //   // eslint-disable-next-line <rule>[, <rule>...]\n  //   // eslint-disable-next-line  (with no rule → disables all)\n  //   // effect-analyzer-disable-next-line <rule>[, ...]\n  //   // effect-analyzer-disable-next-line  (no rule → all)\n  // Same-line trailing:\n  //   // eslint-disable-line <rule>...\n  //   // effect-analyzer-disable-line <rule>...\n  // For our rule-mapping we also accept `no-restricted-syntax` as an alias\n  // for `array-push-spread`, since the Effect codebase uses that ESLint rule\n  // name to suppress the same V8 footgun.\n  const sourceText = sf.getFullText();\n  const lineStarts: number[] = [0];\n  for (let i = 0; i < sourceText.length; i++) {\n    if (sourceText[i] === '\\n') lineStarts.push(i + 1);\n  }\n  const disablesByLine = new Map<number, Set<string>>();\n  const PRAGMA_RE = /\\/\\/\\s*(eslint|effect-analyzer)-disable-(next-line|line)\\b([^\\n]*)/g;\n  let m: RegExpExecArray | null;\n  while ((m = PRAGMA_RE.exec(sourceText)) !== null) {\n    const pos = m.index;\n    // Compute line containing this comment (1-based).\n    let line = 1;\n    for (let i = 1; i < lineStarts.length; i++) {\n      if (lineStarts[i]! > pos) break;\n      line = i + 1;\n    }\n    const targetLine = m[2] === 'next-line' ? line + 1 : line;\n    // Parse rule names after the directive — strip leading punctuation, take\n    // the first whitespace-separated token sequence up to a `//` or `/*` or EOL.\n    const rest = (m[3] ?? '').replace(/^[\\s:,-]+/, '').replace(/\\/\\*[\\s\\S]*$/, '').trim();\n    const rules = rest === '' ? ['*'] : rest.split(/[\\s,]+/).filter(Boolean);\n    const set = disablesByLine.get(targetLine) ?? new Set<string>();\n    for (const r of rules) set.add(r);\n    disablesByLine.set(targetLine, set);\n  }\n  const RULE_ALIASES: Record<string, string[]> = {\n    'array-push-spread': ['no-restricted-syntax'],\n  };\n  const isSuppressed = (rule: string, line: number | undefined): boolean => {\n    if (line === undefined) return false;\n    const set = disablesByLine.get(line);\n    if (!set) return false;\n    if (set.has('*')) return true;\n    if (set.has(rule)) return true;\n    const aliases = RULE_ALIASES[rule];\n    if (aliases?.some((a) => set.has(a))) return true;\n    return false;\n  };\n  const filteredIssues = issues.filter((i) => !isSuppressed(i.rule, i.location?.line));\n\n  const severityRank = (severity: LintIssue['severity']): number => {\n    if (severity === 'error') return 0;\n    if (severity === 'warning') return 1;\n    return 2;\n  };\n  const canonicalIssues = [...filteredIssues].sort((a, b) => {\n    const aPath = a.location?.filePath ?? '';\n    const bPath = b.location?.filePath ?? '';\n    if (aPath !== bPath) return aPath.localeCompare(bPath);\n    const aLine = a.location?.line ?? Number.MAX_SAFE_INTEGER;\n    const bLine = b.location?.line ?? Number.MAX_SAFE_INTEGER;\n    if (aLine !== bLine) return aLine - bLine;\n    const aCol = a.location?.column ?? Number.MAX_SAFE_INTEGER;\n    const bCol = b.location?.column ?? Number.MAX_SAFE_INTEGER;\n    if (aCol !== bCol) return aCol - bCol;\n    if (a.rule !== b.rule) return a.rule.localeCompare(b.rule);\n    const sevCmp = severityRank(a.severity) - severityRank(b.severity);\n    if (sevCmp !== 0) return sevCmp;\n    if (a.message !== b.message) return a.message.localeCompare(b.message);\n    return (a.suggestion ?? '').localeCompare(b.suggestion ?? '');\n  });\n  const dedupedIssues: LintIssue[] = [];\n  const seen = new Set<string>();\n  for (const issue of canonicalIssues) {\n    const key = [\n      issue.rule,\n      issue.severity,\n      issue.location?.filePath ?? '',\n      String(issue.location?.line ?? ''),\n      String(issue.location?.column ?? ''),\n      issue.message,\n      issue.suggestion ?? '',\n    ].join('|');\n    if (seen.has(key)) continue;\n    seen.add(key);\n    // Attach docsUrl + Bad/Good example if the rule has registry entries.\n    // Per-rule code already populates these explicitly is preserved.\n    const docs = RULE_DOCS[issue.rule];\n    if (docs && (issue.docsUrl === undefined || issue.example === undefined)) {\n      dedupedIssues.push({\n        ...issue,\n        docsUrl: issue.docsUrl ?? docs.docsUrl,\n        example: issue.example ?? docs.example,\n      });\n    } else {\n      dedupedIssues.push(issue);\n    }\n  }\n  return { filePath: fp, issues: dedupedIssues };\n};\n\n/**\n * Lint a TypeScript source string. Convenience wrapper for tests/CLI.\n */\nexport const lintSourceCode = (code: string, filePath = 'temp.ts'): SourceLintResult => {\n  const { Project } = loadTsMorph();\n  const project = new Project({\n    useInMemoryFileSystem: true,\n    compilerOptions: { strict: true, esModuleInterop: true },\n  });\n  const sf = project.createSourceFile(filePath, code);\n  return lintSourceFile(sf, filePath);\n};\n","import * as fs from 'node:fs/promises';\nimport { join, extname, resolve } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { LintIssue } from './effect-linter';\nimport { lintSourceCode } from './source-linter';\nimport { findRuleDoc } from './rule-registry';\nimport { readTsgoProjectFiles, runTsgoDiagnostics } from './tsgo-diagnostics';\n\nexport interface LintFinding {\n  readonly filePath: string;\n  readonly rule: string;\n  readonly severity: 'error' | 'warning' | 'info';\n  readonly message: string;\n  readonly suggestion?: string | undefined;\n  readonly line: number;\n  readonly column: number;\n  /**\n   * Which checker produced this finding. `tsgo` findings are type-aware Effect\n   * language service diagnostics; `analyzer` findings are our own AST rules.\n   * Consumers gate on this instead of guessing from the rule name.\n   */\n  readonly source: 'analyzer' | 'tsgo';\n  /** The 377xxx Effect language service code. Only present on `tsgo` findings. */\n  readonly code?: number | undefined;\n  readonly endLine?: number | undefined;\n  readonly endColumn?: number | undefined;\n  readonly fingerprint: string;\n  readonly suppressed?: boolean | undefined;\n  readonly suppressionReason?: string | undefined;\n}\n\n/**\n * Severity gate for the process exit status. `undefined` means advisory-only:\n * findings are reported but never change the exit code, so a consumer can tell\n * an advisory run apart from a failed one without re-checking anything.\n */\nexport type FailOnSeverity = LintFinding['severity'];\n\nconst SEVERITY_ORDER: Record<LintFinding['severity'], number> = {\n  error: 3,\n  warning: 2,\n  info: 1,\n};\n\n/**\n * Exit code for a scan under a severity gate: 1 when any finding is at or above\n * `failOn`, 0 otherwise.\n */\nexport const exitCodeFor = (\n  findings: readonly LintFinding[],\n  failOn: FailOnSeverity | undefined,\n): 0 | 1 => {\n  if (failOn === undefined) return 0;\n  const threshold = SEVERITY_ORDER[failOn];\n  return findings.some((f) => SEVERITY_ORDER[f.severity] >= threshold) ? 1 : 0;\n};\n\nexport interface Suppression {\n  readonly filePath?: string | undefined;\n  readonly line: number;\n  readonly rule: string;\n  readonly reason?: string | undefined;\n}\n\n/**\n * What the Effect language service actually covered. Without this a run where\n * tsgo checked nothing — a stale or mistargeted tsconfig — is indistinguishable\n * from a genuinely clean one.\n */\nexport interface TsgoCoverage {\n  readonly filesChecked: number;\n  readonly totalFiles: number;\n  /** Scanned files the language service never checked, sorted. */\n  readonly unchecked: readonly string[];\n}\n\nexport interface LintScanResult {\n  readonly findings: readonly LintFinding[];\n  readonly staleSuppressions: readonly Suppression[];\n  readonly suppressionsMissingReason: readonly Suppression[];\n  readonly filesScanned: number;\n  readonly tsgo?: TsgoCoverage | undefined;\n}\n\nexport interface BaselineComparison {\n  readonly newFindings: readonly LintFinding[];\n  readonly resolvedFindings: readonly LintFinding[];\n  readonly unchangedFindings: readonly LintFinding[];\n}\n\nexport interface LintScorecardRow {\n  readonly filePath: string;\n  readonly score: number;\n  readonly penalty: number;\n  readonly findings: number;\n  readonly errors: number;\n  readonly warnings: number;\n  readonly info: number;\n}\n\n/**\n * Deterministic penalty table for lint scorecard generation.\n * Keep this stable across runs and adjust intentionally in changelog-worthy updates.\n */\nexport const SCORECARD_WEIGHTS = {\n  severity: {\n    error: 10,\n    warning: 4,\n    info: 1,\n  },\n  ruleOverrides: {\n    'unsafe-api-usage': 12,\n    'live-layer-in-test': 5,\n    'forEach-without-concurrency': 3,\n    'untagged-throw': 4,\n    'sleep-without-testclock': 3,\n  },\n} as const;\n\nconst TS_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);\n\nconst severityRank = (severity: LintFinding['severity']): number =>\n  severity === 'error' ? 0 : severity === 'warning' ? 1 : 2;\n\nconst canonicalSort = (a: LintFinding, b: LintFinding): number => {\n  if (a.filePath !== b.filePath) return a.filePath.localeCompare(b.filePath);\n  if (a.line !== b.line) return a.line - b.line;\n  if (a.column !== b.column) return a.column - b.column;\n  if (a.rule !== b.rule) return a.rule.localeCompare(b.rule);\n  const sevCmp = severityRank(a.severity) - severityRank(b.severity);\n  if (sevCmp !== 0) return sevCmp;\n  if (a.message !== b.message) return a.message.localeCompare(b.message);\n  return (a.suggestion ?? '').localeCompare(b.suggestion ?? '');\n};\n\n/**\n * A finding's stable identity across runs and releases.\n *\n * The key is frozen: baselines written by earlier releases carry these\n * fingerprints, and `--fail-on-new` compares against them. Adding a field here\n * renumbers every existing finding and reports the whole backlog as new, so\n * `source` is deliberately excluded — the same defect found by either checker\n * is the same defect.\n */\nexport const fingerprintOf = (\n  finding: Pick<\n    LintFinding,\n    'filePath' | 'line' | 'column' | 'rule' | 'severity' | 'message' | 'suggestion'\n  >,\n): string => {\n  const key = [\n    finding.filePath,\n    String(finding.line),\n    String(finding.column),\n    finding.rule,\n    finding.severity,\n    finding.message,\n    finding.suggestion ?? '',\n  ].join('|');\n  return createHash('sha256').update(key).digest('hex').slice(0, 20);\n};\n\nconst stableFingerprint = fingerprintOf;\n\nconst parseSuppressions = (source: string): readonly Suppression[] => {\n  const lines = source.split(/\\r?\\n/);\n  const suppressions: Suppression[] = [];\n  const re = /effect-analyzer-disable-next-line\\s+([a-z0-9-]+)(?:\\s+(.+))?$/i;\n  for (let i = 0; i < lines.length; i++) {\n    const line = lines[i];\n    if (!line) continue;\n    const match = re.exec(line);\n    if (!match) continue;\n    const rule = (match[1] ?? '').trim();\n    if (!rule) continue;\n    const reason = (match[2] ?? '').trim();\n    suppressions.push({\n      line: i + 1,\n      rule,\n      reason: reason && reason.length > 0 ? reason : undefined,\n    });\n  }\n  return suppressions;\n};\n\nconst applySuppressions = (\n  findings: readonly LintFinding[],\n  suppressions: readonly Suppression[],\n): { findings: readonly LintFinding[]; stale: readonly Suppression[] } => {\n  const byTarget = new Map<string, Suppression>();\n  for (const suppression of suppressions) {\n    byTarget.set(`${suppression.line + 1}|${suppression.rule}`, suppression);\n  }\n\n  const consumed = new Set<string>();\n  const updated = findings.map((finding) => {\n    const key = `${finding.line}|${finding.rule}`;\n    const match = byTarget.get(key);\n    if (!match) return finding;\n    consumed.add(key);\n    return {\n      ...finding,\n      suppressed: true,\n      suppressionReason: match.reason,\n    };\n  });\n\n  const stale = suppressions.filter((suppression) => !consumed.has(`${suppression.line + 1}|${suppression.rule}`));\n  return { findings: updated, stale };\n};\n\nconst dedupe = (findings: readonly LintFinding[]): readonly LintFinding[] => {\n  const sorted = [...findings].sort(canonicalSort);\n  const out: LintFinding[] = [];\n  const seen = new Set<string>();\n  for (const finding of sorted) {\n    const key = [\n      finding.fingerprint,\n      finding.suppressed ? '1' : '0',\n      finding.suppressionReason ?? '',\n    ].join('|');\n    if (seen.has(key)) continue;\n    seen.add(key);\n    out.push(finding);\n  }\n  return out;\n};\n\nconst toFinding = (filePath: string, issue: LintIssue): LintFinding => {\n  const line = issue.location?.line ?? 1;\n  const column = issue.location?.column ?? 1;\n  const base = {\n    filePath,\n    rule: issue.rule,\n    severity: issue.severity,\n    message: issue.message,\n    suggestion: issue.suggestion,\n    line,\n    column,\n    source: 'analyzer' as const,\n  };\n  return {\n    ...base,\n    fingerprint: stableFingerprint(base),\n  };\n};\n\nconst walk = async (path: string, depth = 0): Promise<string[]> => {\n  if (depth > 30) return [];\n  const stat = await fs.stat(path);\n  if (stat.isFile()) return TS_EXTENSIONS.has(extname(path)) ? [path] : [];\n  if (!stat.isDirectory()) return [];\n  const entries = await fs.readdir(path, { withFileTypes: true });\n  const files: string[] = [];\n  for (const entry of entries) {\n    if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === 'dist' || entry.name === 'build') {\n      continue;\n    }\n    const full = join(path, entry.name);\n    if (entry.isDirectory()) {\n      files.push(...(await walk(full, depth + 1)));\n    } else if (entry.isFile() && TS_EXTENSIONS.has(extname(entry.name))) {\n      files.push(full);\n    }\n  }\n  return files;\n};\n\nexport interface SourceLintScanOptions {\n  /**\n   * Path to a TypeScript 7 tsconfig.json. When set, official type-aware Effect\n   * diagnostics from the bundled `@effect/tsgo` bridge are merged in.\n   */\n  readonly tsgoProject?: string | undefined;\n}\n\nexport const runSourceLintScan = async (\n  pathArg: string,\n  options: SourceLintScanOptions = {},\n): Promise<LintScanResult> => {\n  const basePath = resolve(pathArg);\n  const candidates = (await walk(basePath)).sort((a, b) => a.localeCompare(b));\n  const findings: LintFinding[] = [];\n  const staleSuppressions: Suppression[] = [];\n  const suppressionsMissingReason: Suppression[] = [];\n\n  for (const filePath of candidates) {\n    const source = await fs.readFile(filePath, 'utf-8');\n    const suppressions = parseSuppressions(source);\n    suppressionsMissingReason.push(\n      ...suppressions\n        .filter((s) => !s.reason || s.reason.trim().length === 0)\n        .map((s) => ({ ...s, filePath })),\n    );\n    const lint = lintSourceCode(source, filePath);\n    const rawFindings = lint.issues.map((issue) => toFinding(filePath, issue));\n    const applied = applySuppressions(rawFindings, suppressions);\n    findings.push(...applied.findings.filter((x) => !x.suppressed));\n    staleSuppressions.push(...applied.stale.map((x) => ({ ...x, filePath, line: x.line })));\n  }\n\n  // Type-aware rules from the official Effect language service, when available.\n  // tsgo diagnostics bypass our disable pragmas — tsgo has its own\n  // suppression story; wire the two together only if users actually ask.\n  let tsgo: TsgoCoverage | undefined;\n  if (options.tsgoProject) {\n    const scanned = new Set(candidates);\n    const result = runTsgoDiagnostics({ project: options.tsgoProject });\n    const inProject = new Set(readTsgoProjectFiles(options.tsgoProject));\n    for (const diagnostic of result.diagnostics) {\n      const filePath = resolve(diagnostic.filePath);\n      if (!scanned.has(filePath)) continue;\n      const base = {\n        filePath,\n        rule: diagnostic.rule,\n        severity: diagnostic.severity,\n        message: diagnostic.message,\n        suggestion: undefined,\n        line: diagnostic.line,\n        column: diagnostic.column,\n        source: diagnostic.source,\n        code: diagnostic.code,\n        endLine: diagnostic.endLine,\n        endColumn: diagnostic.endColumn,\n      };\n      findings.push({ ...base, fingerprint: stableFingerprint(base) });\n    }\n    const unchecked = candidates.filter((c) => !inProject.has(c));\n    tsgo = {\n      filesChecked: result.summary.filesChecked,\n      totalFiles: result.summary.totalFiles,\n      unchecked,\n    };\n  }\n\n  return {\n    findings: dedupe(findings),\n    staleSuppressions,\n    suppressionsMissingReason,\n    filesScanned: candidates.length,\n    tsgo,\n  };\n};\n\nexport const compareAgainstBaseline = (\n  current: readonly LintFinding[],\n  baseline: readonly LintFinding[],\n): BaselineComparison => {\n  const currentByFp = new Map(current.map((f) => [f.fingerprint, f]));\n  const baselineByFp = new Map(baseline.map((f) => [f.fingerprint, f]));\n\n  const newFindings = [...currentByFp.entries()]\n    .filter(([fp]) => !baselineByFp.has(fp))\n    .map(([, finding]) => finding)\n    .sort(canonicalSort);\n\n  const resolvedFindings = [...baselineByFp.entries()]\n    .filter(([fp]) => !currentByFp.has(fp))\n    .map(([, finding]) => finding)\n    .sort(canonicalSort);\n\n  const unchangedFindings = [...currentByFp.entries()]\n    .filter(([fp]) => baselineByFp.has(fp))\n    .map(([, finding]) => finding)\n    .sort(canonicalSort);\n\n  return { newFindings, resolvedFindings, unchangedFindings };\n};\n\nexport const toSarif = (findings: readonly LintFinding[]) => {\n  const rules = [...new Set(findings.map((f) => f.rule))].sort((a, b) => a.localeCompare(b));\n  return {\n    version: '2.1.0',\n    $schema: 'https://json.schemastore.org/sarif-2.1.0.json',\n    runs: [\n      {\n        tool: {\n          driver: {\n            name: 'effect-analyzer',\n            informationUri: 'https://effect.website/docs/tooling/effect-analyzer',\n            rules: rules.map((ruleId) => {\n              const doc = findRuleDoc(ruleId);\n              const level = doc?.severity === 'error' ? 'error' : doc?.severity === 'warning' ? 'warning' : 'note';\n              return {\n                id: ruleId,\n                shortDescription: {\n                  text: doc?.title ?? ruleId,\n                },\n                fullDescription: doc?.description\n                  ? { text: doc.description }\n                  : undefined,\n                helpUri: doc?.docUrl,\n                defaultConfiguration: { level },\n                properties: {\n                  tags: doc ? [`domain:${doc.domain}`, `confidence:${doc.confidence}`] : [],\n                },\n              };\n            }),\n          },\n        },\n        results: findings.map((finding) => ({\n          ruleId: finding.rule,\n          level: finding.severity === 'error' ? 'error' : finding.severity === 'warning' ? 'warning' : 'note',\n          message: { text: finding.message },\n          fingerprints: { primaryLocationLineHash: finding.fingerprint },\n          locations: [\n            {\n              physicalLocation: {\n                artifactLocation: { uri: finding.filePath },\n                region: {\n                  startLine: finding.line,\n                  startColumn: finding.column,\n                },\n              },\n            },\n          ],\n        })),\n      },\n    ],\n  };\n};\n\nexport const buildLintScorecard = (findings: readonly LintFinding[]): readonly LintScorecardRow[] => {\n  const rows = new Map<string, LintScorecardRow>();\n  for (const finding of findings) {\n    const existing = rows.get(finding.filePath) ?? {\n      filePath: finding.filePath,\n      score: 100,\n      penalty: 0,\n      findings: 0,\n      errors: 0,\n      warnings: 0,\n      info: 0,\n    };\n    const severityPenalty = SCORECARD_WEIGHTS.severity[finding.severity];\n    const rulePenalty = SCORECARD_WEIGHTS.ruleOverrides[\n      finding.rule as keyof typeof SCORECARD_WEIGHTS.ruleOverrides\n    ];\n    const penalty = rulePenalty ?? severityPenalty;\n    rows.set(finding.filePath, {\n      ...existing,\n      penalty: existing.penalty + penalty,\n      findings: existing.findings + 1,\n      errors: existing.errors + (finding.severity === 'error' ? 1 : 0),\n      warnings: existing.warnings + (finding.severity === 'warning' ? 1 : 0),\n      info: existing.info + (finding.severity === 'info' ? 1 : 0),\n    });\n  }\n\n  return [...rows.values()]\n    .map((row) => ({\n      ...row,\n      score: Math.max(0, 100 - row.penalty),\n    }))\n    .sort((a, b) => {\n      if (a.score !== b.score) return a.score - b.score;\n      if (a.penalty !== b.penalty) return b.penalty - a.penalty;\n      if (a.findings !== b.findings) return b.findings - a.findings;\n      return a.filePath.localeCompare(b.filePath);\n    });\n};\n","import { DEFAULT_LINT_RULES } from './effect-linter';\nimport type { StrictRule } from './strict-diagnostics';\n\nexport type RuleDomain = 'source' | 'effect-lint' | 'strict';\nexport type RuleSeverity = 'error' | 'warning' | 'info';\nexport type RuleConfidence = 'high' | 'medium' | 'low';\nexport type RuleProfile = 'strict' | 'ci' | 'migration' | 'docs';\n\nexport interface RuleDoc {\n  readonly code: string;\n  readonly domain: RuleDomain;\n  readonly severity: RuleSeverity;\n  readonly confidence: RuleConfidence;\n  readonly title: string;\n  readonly description: string;\n  readonly example?: string | undefined;\n  readonly docUrl?: string | undefined;\n}\n\nexport interface RuleSearchResult {\n  readonly doc: RuleDoc;\n  readonly score: number;\n}\n\nconst RULE_DOC_BASE = 'https://effect.website/docs';\n\nconst normalizeDisplayText = (text: string): string =>\n  text\n    .replace(/[\\t\\r\\n]+/g, ' ')\n    .replace(/\\s+/g, ' ')\n    .trim();\n\nconst withDocUrl = (domain: RuleDomain, code: string): string =>\n  `${RULE_DOC_BASE}/tooling/effect-analyzer/rules/${domain}/${code}`;\n\nconst SOURCE_RULE_DOCS_BASE = [\n  { code: 'detached-fiber-in-test', domain: 'source', severity: 'warning', title: 'Detached Fiber In Test', description: 'Flags runFork-style APIs in tests that can outlive test scope and cause flakiness.', example: 'Effect.runFork(Effect.never)' },\n  { code: 'empty-effect-all', domain: 'source', severity: 'info', title: 'Empty Effect.all', description: 'Flags Effect.all on empty arrays/objects, which is often dead or placeholder code.', example: 'Effect.all([])' },\n  { code: 'forEach-without-concurrency', domain: 'source', severity: 'info', title: 'forEach Without Explicit Concurrency', description: 'Encourages explicit concurrency options for Effect.forEach and Stream.runForEach.', example: 'Effect.forEach(items, f)' },\n  { code: 'identity-catch', domain: 'source', severity: 'warning', title: 'Identity Catch Handler', description: 'Flags catch handlers that only re-fail the same value and add no semantic value.', example: 'Effect.catch(eff, (e) => Effect.fail(e))' },\n  { code: 'live-layer-in-test', domain: 'source', severity: 'warning', title: 'Live Layer In Test', description: 'Flags Live layer references in test files where deterministic test layers are expected.', example: 'const layer = UserRepoLive' },\n  { code: 'mutable-in-concurrent', domain: 'source', severity: 'warning', title: 'Mutable State In Concurrent Effect', description: 'Flags let/var mutation inside parallel/fork/race contexts.', example: 'let n = 0; yield* Effect.all([Effect.sync(() => n++)])' },\n  { code: 'nondeterministic-test-api', domain: 'source', severity: 'warning', title: 'Nondeterministic Test API', description: 'Flags direct Date.now/new Date/Math.random usage in test code.', example: 'const now = Date.now()' },\n  { code: 'promise-api-in-gen', domain: 'source', severity: 'warning', title: 'Promise API In Effect.gen', description: 'Flags Promise static API usage inside Effect.gen where Effect combinators should be used.', example: 'Promise.all(tasks)' },\n  { code: 'runPromise-then-chain', domain: 'source', severity: 'info', title: 'Promise Chain After runPromise', description: 'Flags .then/.catch/.finally chains after Effect.runPromise/runPromiseExit.', example: 'Effect.runPromise(eff).then(...)' },\n  { code: 'runSync-on-async', domain: 'source', severity: 'error', title: 'runSync On Async Effect', description: 'Flags Effect.runSync on async-tainted effects that will throw at runtime.', example: 'Effect.runSync(Effect.tryPromise(...))' },\n  { code: 'runSyncExit-on-async', domain: 'source', severity: 'error', title: 'runSyncExit On Async Effect', description: 'Flags Effect.runSyncExit on async-tainted effects that will throw at runtime.', example: 'Effect.runSyncExit(Effect.tryPromise(...))' },\n  { code: 'schedule-unbounded', domain: 'source', severity: 'warning', title: 'Potentially Unbounded Schedule', description: 'Flags repeating schedule constructions without visible bounds.', example: 'Schedule.forever' },\n  { code: 'sleep-without-testclock', domain: 'source', severity: 'info', title: 'Effect.sleep Without TestClock In Tests', description: 'Flags real-time sleep usage in test files when TestClock is not used.', example: 'Effect.sleep(Duration.seconds(1))' },\n  { code: 'unsafe-api-usage', domain: 'source', severity: 'warning', title: 'Unsafe API Usage', description: 'Flags direct Effect/Runtime unsafe APIs that bypass typed runtime safety boundaries.', example: 'Effect.unsafeMakeSemaphore(1)' },\n  { code: 'untagged-throw', domain: 'source', severity: 'warning', title: 'Untagged Throw In Effect Context', description: 'Flags throw new Error/TypeError/RangeError inside Effect contexts.', example: 'throw new Error(\"boom\")' },\n  ] as const satisfies readonly Omit<RuleDoc, 'docUrl' | 'confidence'>[];\n\nconst SOURCE_RULE_DOCS: readonly RuleDoc[] = SOURCE_RULE_DOCS_BASE.map((x) => ({\n  ...x,\n  confidence: x.severity === 'error' ? 'high' : x.severity === 'warning' ? 'medium' : 'low',\n  docUrl: withDocUrl('source', x.code),\n}));\n\nconst STRICT_RULE_DOCS_BY_RULE: Record<StrictRule, Omit<RuleDoc, 'code' | 'domain' | 'docUrl'>> = {\n  'missing-error-type': { severity: 'warning', confidence: 'medium', title: 'Missing Error Type', description: 'Effect node should expose an explicit typed error channel.' },\n  'unknown-error-type': { severity: 'warning', confidence: 'medium', title: 'Unknown Error Type', description: 'Effect node error type is unknown and should be narrowed.' },\n  'parallel-missing-errors': { severity: 'warning', confidence: 'medium', title: 'Parallel Branch Missing Errors', description: 'Parallel branch effect lacks explicit error type information.' },\n  'race-missing-errors': { severity: 'warning', confidence: 'medium', title: 'Race Branch Missing Errors', description: 'Race branch effect lacks explicit error type information.' },\n  'effect-without-handler': { severity: 'warning', confidence: 'medium', title: 'Effect Without Handler', description: 'Effect can fail on this path but no nearby handler is detected.' },\n  'fiber-potential-leak': { severity: 'warning', confidence: 'medium', title: 'Potential Fiber Leak', description: 'Fork-like operation appears without join/interrupt/await in scope.' },\n  'resource-missing-scope': { severity: 'warning', confidence: 'medium', title: 'Resource Missing Scope', description: 'Resource acquisition appears without visible Effect.scoped boundary.' },\n  'unbounded-concurrency': { severity: 'warning', confidence: 'medium', title: 'Unbounded Concurrency', description: 'Large parallel/loop operations should set explicit concurrency bounds.' },\n  'unused-service': { severity: 'warning', confidence: 'medium', title: 'Unused Service', description: 'Provided service appears unused in analyzed graph.' },\n  'dead-code-path': { severity: 'warning', confidence: 'medium', title: 'Dead Code Path', description: 'Decision condition resolves to a constant branch outcome.' },\n};\n\nconst STRICT_RULE_DOCS: readonly RuleDoc[] = (Object.keys(STRICT_RULE_DOCS_BY_RULE) as StrictRule[]).map((rule) => ({\n  code: rule,\n  domain: 'strict',\n  docUrl: withDocUrl('strict', rule),\n  ...STRICT_RULE_DOCS_BY_RULE[rule],\n}));\n\nconst EFFECT_LINT_RULE_DOCS: readonly RuleDoc[] = DEFAULT_LINT_RULES.map((rule) => ({\n  code: rule.name,\n  domain: 'effect-lint',\n  severity: rule.severity,\n  confidence: rule.severity === 'error' ? 'high' : 'medium',\n  title: rule.name,\n  description: rule.description,\n  docUrl: withDocUrl('effect-lint', rule.name),\n}));\n\nconst severityRank = (severity: RuleSeverity): number => (severity === 'error' ? 0 : severity === 'warning' ? 1 : 2);\n\nconst normalizeRuleDoc = (doc: RuleDoc): RuleDoc => ({\n  ...doc,\n  code: normalizeDisplayText(doc.code),\n  title: normalizeDisplayText(doc.title),\n  description: normalizeDisplayText(doc.description),\n  example: doc.example ? normalizeDisplayText(doc.example) : undefined,\n  docUrl: doc.docUrl ? normalizeDisplayText(doc.docUrl) : undefined,\n});\n\nlet cachedAllDocs: readonly RuleDoc[] | undefined;\nconst searchCache = new Map<string, readonly RuleSearchResult[]>();\nconst explainCache = new Map<string, RuleDoc | undefined>();\n\nexport const listAllRuleDocs = (): readonly RuleDoc[] => {\n  if (cachedAllDocs) return cachedAllDocs;\n  const merged = [...SOURCE_RULE_DOCS, ...EFFECT_LINT_RULE_DOCS, ...STRICT_RULE_DOCS].map(normalizeRuleDoc);\n  const canonical = merged.sort((a, b) => {\n    if (a.domain !== b.domain) return a.domain.localeCompare(b.domain);\n    const sevCmp = severityRank(a.severity) - severityRank(b.severity);\n    if (sevCmp !== 0) return sevCmp;\n    if (a.code !== b.code) return a.code.localeCompare(b.code);\n    if (a.title !== b.title) return a.title.localeCompare(b.title);\n    if (a.description !== b.description) return a.description.localeCompare(b.description);\n    return (a.example ?? '').localeCompare(b.example ?? '');\n  });\n  const seen = new Set<string>();\n  const deduped: RuleDoc[] = [];\n  for (const doc of canonical) {\n    const key = [doc.domain, doc.code, doc.severity, doc.confidence, doc.title, doc.description, doc.example ?? '', doc.docUrl ?? ''].join('|');\n    if (seen.has(key)) continue;\n    seen.add(key);\n    deduped.push(doc);\n  }\n  cachedAllDocs = deduped;\n  return deduped;\n};\n\nexport const findRuleDoc = (code: string, domain?: RuleDomain): RuleDoc | undefined => {\n  const normalizedCode = normalizeDisplayText(code);\n  const key = `${domain ?? 'any'}|${normalizedCode}`;\n  if (explainCache.has(key)) return explainCache.get(key);\n  const docs = listAllRuleDocs();\n  const found = domain !== undefined ? docs.find((d) => d.domain === domain && d.code === normalizedCode) : docs.find((d) => d.code === normalizedCode);\n  explainCache.set(key, found);\n  return found;\n};\n\nexport const getRuleCodesForProfile = (profile: RuleProfile): readonly string[] => {\n  const docs = listAllRuleDocs();\n  const select = (d: RuleDoc): boolean => {\n    if (profile === 'strict') return d.domain === 'strict' || d.severity === 'error';\n    if (profile === 'ci') return d.severity !== 'info';\n    if (profile === 'migration') {\n      const migrationTags = ['promise', 'runSync', 'layer', 'catch', 'untagged', 'schedule', 'concurrency'];\n      const hay = `${d.code} ${d.title} ${d.description}`.toLowerCase();\n      return migrationTags.some((t) => hay.includes(t));\n    }\n    return d.domain === 'source' || d.domain === 'effect-lint';\n  };\n  return docs.filter(select).map((d) => d.code);\n};\n\nexport const searchRuleDocs = (query: string, domain?: RuleDomain): readonly RuleSearchResult[] => {\n  const q = normalizeDisplayText(query).toLowerCase();\n  const key = `${domain ?? 'any'}|${q}`;\n  const cached = searchCache.get(key);\n  if (cached) return cached;\n  if (q.length === 0) {\n    const all = listAllRuleDocs().filter((d) => (domain ? d.domain === domain : true)).map((doc) => ({ doc, score: 0 }));\n    searchCache.set(key, all);\n    return all;\n  }\n  const docs = listAllRuleDocs().filter((d) => (domain ? d.domain === domain : true));\n  const scored = docs\n    .map((doc): RuleSearchResult => {\n      const code = doc.code.toLowerCase();\n      const title = doc.title.toLowerCase();\n      const desc = doc.description.toLowerCase();\n      const example = (doc.example ?? '').toLowerCase();\n      let score = 0;\n      if (code === q) score += 100;\n      if (code.includes(q)) score += 50;\n      if (title.includes(q)) score += 35;\n      if (desc.includes(q)) score += 20;\n      if (example.includes(q)) score += 10;\n      return { doc, score };\n    })\n    .filter((x) => x.score > 0)\n    .sort((a, b) => {\n      if (a.score !== b.score) return b.score - a.score;\n      if (a.doc.domain !== b.doc.domain) return a.doc.domain.localeCompare(b.doc.domain);\n      const sevCmp = severityRank(a.doc.severity) - severityRank(b.doc.severity);\n      if (sevCmp !== 0) return sevCmp;\n      return a.doc.code.localeCompare(b.doc.code);\n    });\n  searchCache.set(key, scored);\n  return scored;\n};\n\nexport const renderRuleDocsText = (): string => {\n  const docs = listAllRuleDocs();\n  const lines: string[] = [];\n  lines.push('# effect-analyzer rules');\n  lines.push('');\n  let currentDomain: RuleDomain | undefined;\n  for (const doc of docs) {\n    if (doc.domain !== currentDomain) {\n      currentDomain = doc.domain;\n      lines.push(`## ${currentDomain}`);\n      lines.push('');\n    }\n    lines.push(`- [${doc.severity}/${doc.confidence}] ${doc.code}: ${doc.description}`);\n    if (doc.example) lines.push(`  example: ${doc.example}`);\n    if (doc.docUrl) lines.push(`  docs: ${doc.docUrl}`);\n  }\n  lines.push('');\n  lines.push(`Total rules: ${docs.length}`);\n  return lines.join('\\n');\n};\n\nexport const renderRuleDocsJson = (pretty = true): string => JSON.stringify(listAllRuleDocs(), null, pretty ? 2 : 0);\n\nexport interface RuleIndexEntry {\n  readonly id: string;\n  readonly code: string;\n  readonly domain: RuleDomain;\n  readonly severity: RuleSeverity;\n  readonly confidence: RuleConfidence;\n  readonly title: string;\n  readonly snippet: string;\n}\n\nexport const buildRuleIndex = (): readonly RuleIndexEntry[] =>\n  listAllRuleDocs().map((doc) => ({\n    id: `${doc.domain}:${doc.code}`,\n    code: doc.code,\n    domain: doc.domain,\n    severity: doc.severity,\n    confidence: doc.confidence,\n    title: doc.title,\n    snippet: normalizeDisplayText(`${doc.description}${doc.example ? ` Example: ${doc.example}` : ''}`),\n  }));\n\nexport const renderRuleIndexJson = (pretty = true): string => JSON.stringify(buildRuleIndex(), null, pretty ? 2 : 0);\n\nexport const explainRule = (code: string, domain?: RuleDomain): RuleDoc | undefined => findRuleDoc(code, domain);\n","/**\n * Bridge to the official Effect language service (`@effect/tsgo`).\n *\n * `@effect/tsgo` ships ~95 *type-aware* Effect rules backed by TypeScript-Go.\n * We do not reimplement those — we shell out to its JSON diagnostics mode and\n * merge the results into our findings, so effect-analyzer stays focused on the\n * things it uniquely does (structure, diagrams, IR, migration progress).\n *\n * It is a direct dependency so `--tsgo` is a reliable first-class capability.\n * The target project still supplies TypeScript 7: `@effect/tsgo` discovers that\n * installation and selects the matching native artifact, keeping diagnostics\n * aligned with the compiler and language service used by the project.\n */\n\nimport { execFileSync, spawnSync } from 'node:child_process';\nimport { createRequire } from 'node:module';\nimport { dirname, isAbsolute, join, resolve } from 'node:path';\nimport { nodeModuleLocation } from './register-node-ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\n\nexport interface TsgoDiagnostic {\n  readonly filePath: string;\n  readonly rule: string;\n  readonly severity: 'error' | 'warning' | 'info';\n  readonly message: string;\n  readonly line: number;\n  readonly column: number;\n  readonly endLine: number;\n  readonly endColumn: number;\n  /** Byte offset and width of the span, as `@effect/tsgo` reports them. */\n  readonly start: number;\n  readonly length: number;\n  /**\n   * The synthesized TypeScript error code. Every Effect language service\n   * diagnostic lives in the 377xxx range, which is what lets a consumer prove a\n   * finding came from the Effect LSP rather than from the type checker.\n   */\n  readonly code: number;\n  readonly source: 'tsgo';\n}\n\n/** `@effect/tsgo`'s own run summary. `filesChecked: 0` means nothing was checked. */\nexport interface TsgoSummary {\n  readonly filesChecked: number;\n  readonly totalFiles: number;\n  readonly errors: number;\n  readonly warnings: number;\n  readonly messages: number;\n}\n\n/** Per-file Effect versions, present only for a `--list-files` run. */\nexport interface TsgoFileVersion {\n  readonly file: string;\n  readonly detectedEffect: string;\n  readonly supportedEffect: string;\n}\n\nexport interface TsgoResult {\n  readonly diagnostics: readonly TsgoDiagnostic[];\n  readonly summary: TsgoSummary;\n  readonly files: readonly TsgoFileVersion[];\n}\n\nexport class TsgoDiagnosticsError extends Error {\n  readonly cause: unknown;\n\n  constructor(message: string, cause?: unknown) {\n    super(message);\n    this.name = 'TsgoDiagnosticsError';\n    this.cause = cause;\n  }\n}\n\ninterface TsgoJsonDiagnostic {\n  readonly file: string;\n  readonly start: number;\n  readonly length: number;\n  readonly line: number;\n  readonly column: number;\n  readonly endLine: number;\n  readonly endColumn: number;\n  readonly severity: 'error' | 'warning' | 'message';\n  readonly code: number;\n  readonly name: string;\n  readonly message: string;\n}\n\nconst resolveTsgoBinFrom = (from: string): string | undefined => {\n  try {\n    const require = createRequire(from);\n    const manifestPath = require.resolve('@effect/tsgo/package.json');\n    const manifest = require('@effect/tsgo/package.json') as {\n      bin?: string | Record<string, string>;\n      publishConfig?: { bin?: string | Record<string, string> };\n    };\n    // Published builds declare the real entry under publishConfig.bin; the\n    // source checkout points `bin` at a .ts file that node cannot run.\n    const bin = manifest.publishConfig?.bin ?? manifest.bin;\n    const entry = typeof bin === 'string' ? bin : bin?.['effect-tsgo'];\n    if (!entry) return undefined;\n    return join(dirname(manifestPath), entry);\n  } catch {\n    return undefined;\n  }\n};\n\n/**\n * Absolute path to the `effect-tsgo` entry script, or `undefined` when the peer\n * is not installed.\n *\n * Tries our own package location first, then the consumer's cwd — under `npx`\n * the CLI runs from a temp dir that cannot see the project's node_modules.\n */\nexport const resolveTsgoBin = (from?: string): string | undefined => {\n  const roots = from\n    ? [from]\n    : [nodeModuleLocation, join(process.cwd(), 'noop.js')];\n  for (const root of roots) {\n    const found = resolveTsgoBinFrom(root);\n    if (found) return found;\n  }\n  return undefined;\n};\n\nconst toSeverity = (severity: TsgoJsonDiagnostic['severity']): TsgoDiagnostic['severity'] =>\n  severity === 'message' ? 'info' : severity;\n\n/**\n * Absolute paths a tsconfig actually includes.\n *\n * A file we scanned that is absent from this list was never in the language\n * service's scope, so its lack of diagnostics is not evidence that it is clean.\n */\nexport const readTsgoProjectFiles = (projectPath: string): readonly string[] => {\n  try {\n    const { Project } = loadTsMorph();\n    const project = new Project({ tsConfigFilePath: projectPath });\n    return project.getSourceFiles().map((f) => resolve(f.getFilePath()));\n  } catch {\n    return [];\n  }\n};\n\nexport interface ParsedTsgoProjectArgument {\n  readonly project: string;\n  readonly consumed: 0 | 1;\n}\n\n/**\n * Parse bare `--tsgo` without stealing a positional source path. A separated\n * project path remains supported after the source path for compatibility;\n * option-first callers use `--tsgo=<path>` for an explicit project.\n */\nexport const parseTsgoProjectArgument = (\n  args: readonly string[],\n  index: number,\n  hasPathArg: boolean,\n): ParsedTsgoProjectArgument => {\n  const next = args[index + 1];\n  if (hasPathArg && next !== undefined && !next.startsWith('-')) {\n    return { project: next, consumed: 1 };\n  }\n  return { project: 'tsconfig.json', consumed: 0 };\n};\n\n/** Resolve the project exactly as the child process will resolve it. */\nexport const resolveTsgoProjectPath = (project: string, cwd: string): string =>\n  isAbsolute(project) ? project : resolve(cwd, project);\n\n/**\n * Parse the `--format json` payload. Tolerates leading noise on stdout and\n * returns `undefined` rather than throwing on anything unexpected.\n */\nexport const parseTsgoOutput = (stdout: string): TsgoResult | undefined => {\n  const start = stdout.indexOf('{');\n  if (start === -1) return undefined;\n  type TsgoJsonOutput = {\n    diagnostics?: readonly TsgoJsonDiagnostic[];\n    summary?: Partial<TsgoSummary>;\n    files?: readonly TsgoFileVersion[];\n  };\n  let parsed: TsgoJsonOutput;\n  try {\n    parsed = JSON.parse(stdout.slice(start)) as TsgoJsonOutput;\n  } catch {\n    return undefined;\n  }\n  const diagnostics = parsed.diagnostics;\n  if (!Array.isArray(diagnostics)) return undefined;\n\n  const summary = parsed.summary ?? {};\n  return {\n    diagnostics: diagnostics.map((d: TsgoJsonDiagnostic) => ({\n      filePath: d.file,\n      rule: d.name,\n      severity: toSeverity(d.severity),\n      message: d.message,\n      line: d.line,\n      column: d.column,\n      endLine: d.endLine,\n      endColumn: d.endColumn,\n      start: d.start,\n      length: d.length,\n      code: d.code,\n      source: 'tsgo' as const,\n    })),\n    summary: {\n      filesChecked: summary.filesChecked ?? 0,\n      totalFiles: summary.totalFiles ?? 0,\n      errors: summary.errors ?? 0,\n      warnings: summary.warnings ?? 0,\n      messages: summary.messages ?? 0,\n    },\n    files: parsed.files ?? [],\n  };\n};\n\n/**\n * Run `effect-tsgo diagnostics --format json` over a project.\n *\n * Non-zero exits that contain valid diagnostic JSON are accepted. Missing\n * binaries, invalid projects, and unparseable failures throw an actionable\n * error because callers only invoke this function after explicitly requesting\n * official type-aware diagnostics.\n */\nexport interface TsgoProcessResult {\n  readonly stdout: string;\n  readonly stderr: string;\n  readonly status: number;\n}\n\n/**\n * Run `effect-tsgo diagnostics` with the caller's own argv and return its raw\n * output.\n *\n * Nothing here interprets or re-renders what comes back: `@effect/tsgo`\n * validates its own flags, formats its own diagnostics and chooses its own exit\n * code, which is the only way a wrapper stays identical to it across releases.\n */\nexport const spawnTsgoDiagnostics = (\n  argv: readonly string[],\n  options: { readonly cwd?: string; readonly timeoutMs?: number; readonly inheritStderr?: boolean } = {},\n): TsgoProcessResult => {\n  const bin = resolveTsgoBin();\n  if (!bin) {\n    throw new TsgoDiagnosticsError(\n      'Unable to resolve @effect/tsgo. Reinstall effect-analyzer and its platform dependencies.',\n    );\n  }\n  const result = spawnSync(process.execPath, [bin, 'diagnostics', ...argv], {\n    cwd: options.cwd ?? process.cwd(),\n    encoding: 'utf-8',\n    maxBuffer: 64 * 1024 * 1024,\n    timeout: options.timeoutMs ?? 120_000,\n    stdio: ['ignore', 'pipe', options.inheritStderr === true ? 'inherit' : 'pipe'],\n  });\n  if (result.error) throw result.error;\n  return {\n    stdout: result.stdout ?? '',\n    stderr: result.stderr ?? '',\n    status: result.status ?? 1,\n  };\n};\n\nexport interface RunTsgoOptions {\n  /** Project to check. Optional when `file` is given, as upstream allows. */\n  readonly project?: string | undefined;\n  /** Single file to check, forwarded as `--file`. */\n  readonly file?: string | undefined;\n  readonly cwd?: string;\n  readonly timeoutMs?: number;\n  /** Inline JSON replacing the project's plugin options, as `--lspconfig`. */\n  readonly lspconfig?: string | undefined;\n  readonly severity?: string | undefined;\n  readonly strict?: boolean;\n  readonly progress?: boolean;\n  readonly listFiles?: boolean;\n}\n\nexport const runTsgoDiagnostics = (options: RunTsgoOptions): TsgoResult => {\n  const bin = resolveTsgoBin();\n  if (!bin) {\n    throw new TsgoDiagnosticsError(\n      'Unable to resolve @effect/tsgo. Reinstall effect-analyzer and its platform dependencies.',\n    );\n  }\n\n  const projectResolutionCwd = options.cwd ?? process.cwd();\n  const projectPath = options.project === undefined\n    ? undefined\n    : resolveTsgoProjectPath(options.project, projectResolutionCwd);\n  // When the caller supplies an absolute project from another cwd, execute in\n  // the project directory so effect-tsgo resolves that consumer's TypeScript\n  // and Effect packages rather than packages belonging to the host process.\n  const cwd = options.cwd ?? (projectPath === undefined ? process.cwd() : dirname(projectPath));\n\n  // Only what the caller asked for: `@effect/tsgo` reads the project's own\n  // `@effect/language-service` plugin options, and synthesising one here would\n  // replace configured severities with rule defaults.\n  const lspconfig = options.lspconfig;\n\n  const argv = [\n    bin,\n    'diagnostics',\n    ...(projectPath === undefined ? [] : ['--project', projectPath]),\n    ...(options.file === undefined ? [] : ['--file', options.file]),\n    '--format',\n    'json',\n    ...(options.severity === undefined ? [] : ['--severity', options.severity]),\n    ...(options.strict === true ? ['--strict'] : []),\n    ...(options.progress === true ? ['--progress'] : []),\n    ...(options.listFiles === true ? ['--list-files'] : []),\n    ...(lspconfig === undefined ? [] : ['--lspconfig', lspconfig]),\n  ];\n\n  let stdout: string;\n  try {\n    stdout = execFileSync(\n      process.execPath,\n      argv,\n      {\n        cwd,\n        encoding: 'utf-8',\n        // A non-zero exit just means diagnostics were found; the JSON is still\n        // on stdout, so read it from the thrown error rather than bailing out.\n        maxBuffer: 64 * 1024 * 1024,\n        timeout: options.timeoutMs ?? 120_000,\n        // `--progress` narrates to stderr; let it through so it reaches the\n        // user's terminal instead of being buffered and discarded.\n        stdio: ['ignore', 'pipe', options.progress === true ? 'inherit' : 'pipe'],\n      },\n    );\n  } catch (error) {\n    const processError = error as {\n      readonly stdout?: string | Buffer;\n      readonly stderr?: string | Buffer;\n    };\n    const out = processError.stdout;\n    stdout = out === undefined\n      ? ''\n      : typeof out === 'string'\n        ? out\n        : out.toString('utf-8');\n    const result = parseTsgoOutput(stdout);\n    if (result) return result;\n\n    const stderr = processError.stderr;\n    const detail = stderr === undefined\n      ? ''\n      : typeof stderr === 'string'\n        ? stderr.trim()\n        : stderr.toString('utf-8').trim();\n    const target = projectPath ?? options.file ?? '(no target)';\n    throw new TsgoDiagnosticsError(\n      detail.length > 0\n        ? `@effect/tsgo diagnostics failed: ${detail}`\n        : `@effect/tsgo diagnostics failed for ${target}`,\n      error,\n    );\n  }\n\n  const result = parseTsgoOutput(stdout);\n  if (!result) {\n    throw new TsgoDiagnosticsError(\n      `@effect/tsgo returned unparseable diagnostics for ${projectPath ?? options.file ?? '(no target)'}`,\n    );\n  }\n  return result;\n};\n","/** Deep operations over the Effect IR. */\n\nimport { Option } from 'effect';\nimport type { StaticEffectIR, StaticFlowNode } from './types';\nimport { getStaticChildren } from './types';\n\nexport interface IRVisit {\n  readonly node: StaticFlowNode;\n  readonly parent: StaticFlowNode | undefined;\n  readonly ancestors: readonly StaticFlowNode[];\n  readonly index: number;\n}\n\nexport interface IRIndex {\n  readonly nodes: readonly StaticFlowNode[];\n  readonly byId: ReadonlyMap<string, StaticFlowNode>;\n  readonly parentById: ReadonlyMap<string, StaticFlowNode>;\n  readonly spanPathById: ReadonlyMap<string, readonly string[]>;\n  readonly idsBySpanPath: ReadonlyMap<string, readonly string[]>;\n}\n\n/** Exhaustive child access with an empty-array identity for leaf nodes. */\nexport const childrenOf = (node: StaticFlowNode): readonly StaticFlowNode[] =>\n  Option.getOrElse(getStaticChildren(node), () => [] as const);\n\n/** Depth-first pre-order traversal of an IR forest. */\nexport const visitIR = (\n  roots: readonly StaticFlowNode[],\n  visitor: (visit: IRVisit) => void,\n): void => {\n  let index = 0;\n  const visit = (\n    nodes: readonly StaticFlowNode[],\n    parent: StaticFlowNode | undefined,\n    ancestors: readonly StaticFlowNode[],\n  ): void => {\n    for (const node of nodes) {\n      visitor({ node, parent, ancestors, index: index++ });\n      visit(childrenOf(node), node, [...ancestors, node]);\n    }\n  };\n  visit(roots, undefined, []);\n};\n\nexport const flattenIR = (\n  roots: readonly StaticFlowNode[],\n): readonly StaticFlowNode[] => {\n  const nodes: StaticFlowNode[] = [];\n  visitIR(roots, ({ node }) => nodes.push(node));\n  return nodes;\n};\n\n/** Name emitted by Effect's runtime tracer, when statically exact. */\nexport const runtimeSpanName = (\n  node: StaticFlowNode,\n): string | undefined => {\n  if (node.spanName) return node.spanName;\n  return node.type === 'effect' ? node.tracedName : undefined;\n};\n\nexport const runtimeSpanNames = (\n  node: StaticFlowNode,\n): readonly string[] => {\n  if (node.spanNames && node.spanNames.length > 0) return node.spanNames;\n  const name = runtimeSpanName(node);\n  return name ? [name] : [];\n};\n\nexport const spanPathKey = (path: readonly string[]): string =>\n  path.join('\\u001f');\n\n/** Build all common indexes once for diagnostics, renderers, and overlays. */\nexport const indexIR = (ir: StaticEffectIR): IRIndex => {\n  const nodes: StaticFlowNode[] = [];\n  const byId = new Map<string, StaticFlowNode>();\n  const parentById = new Map<string, StaticFlowNode>();\n  const spanPathById = new Map<string, readonly string[]>();\n  const mutableIdsBySpanPath = new Map<string, string[]>();\n\n  visitIR(ir.root.children, ({ node, parent, ancestors }) => {\n    nodes.push(node);\n    byId.set(node.id, node);\n    if (parent) parentById.set(node.id, parent);\n\n    const ownNames = runtimeSpanNames(node);\n    if (ownNames.length === 0) return;\n    const ancestorPath = ancestors.flatMap((ancestor) => {\n      return runtimeSpanNames(ancestor);\n    });\n    const path = [...ancestorPath, ...ownNames];\n    spanPathById.set(node.id, path);\n    for (let i = 1; i <= ownNames.length; i++) {\n      const key = spanPathKey([...ancestorPath, ...ownNames.slice(0, i)]);\n      const ids = mutableIdsBySpanPath.get(key) ?? [];\n      if (!ids.includes(node.id)) ids.push(node.id);\n      mutableIdsBySpanPath.set(key, ids);\n    }\n  });\n\n  return {\n    nodes,\n    byId,\n    parentById,\n    spanPathById,\n    idsBySpanPath: mutableIdsBySpanPath,\n  };\n};\n","/** Located facts used to assess source representation and runtime joinability. */\n\nimport type { SourceLocation, StaticEffectIR, StaticFlowNode } from './types';\nimport { indexIR, runtimeSpanName } from './ir';\n\nexport type FidelityFindingKind =\n  | 'unknown-node'\n  | 'opaque-node'\n  | 'dynamic-span-name'\n  | 'duplicate-span-path';\n\nexport interface FidelityFinding {\n  readonly kind: FidelityFindingKind;\n  readonly nodeId: string;\n  readonly message: string;\n  readonly suggestion: string;\n  readonly reason?: string | undefined;\n  readonly location?: SourceLocation | undefined;\n}\n\nexport interface FidelityDimension {\n  readonly exact: boolean;\n  readonly resolved: number;\n  readonly total: number;\n  readonly rate: number;\n}\n\nexport interface IRFidelityAssessment {\n  readonly exact: boolean;\n  readonly score: number;\n  readonly sourceRepresentation: FidelityDimension;\n  readonly runtimeJoinability: FidelityDimension;\n  readonly staticOnlyNodes: number;\n  readonly findings: readonly FidelityFinding[];\n}\n\nconst findingForNode = (node: StaticFlowNode): FidelityFinding | undefined => {\n  if (node.type === 'unknown') {\n    return {\n      kind: 'unknown-node',\n      nodeId: node.id,\n      message: `The analyzer could not resolve this expression: ${node.reason}`,\n      suggestion: 'Use a supported Effect v4 construct or extract the expression into a named Effect.fn operation.',\n      reason: node.reason,\n      location: node.location,\n    };\n  }\n  if (node.type === 'opaque') {\n    return {\n      kind: 'opaque-node',\n      nodeId: node.id,\n      message: `The analyzer intentionally treats this source as opaque: ${node.reason}`,\n      suggestion: 'Extract diagram-relevant work into a named Effect.fn operation or an explicit Effect.withSpan region.',\n      reason: node.reason,\n      location: node.location,\n    };\n  }\n  if (\n    node.spanNameDynamic === true ||\n    (node.type === 'effect' &&\n      node.callee.includes('withSpan') &&\n      runtimeSpanName(node) === undefined)\n  ) {\n    return {\n      kind: 'dynamic-span-name',\n      nodeId: node.id,\n      message: 'The runtime span name is computed, so a trace cannot be joined to this static node exactly.',\n      suggestion: 'Use a literal Effect.withSpan name and put dynamic values in span attributes.',\n      location: node.location,\n    };\n  }\n  return undefined;\n};\n\nconst rate = (resolved: number, total: number): number =>\n  total === 0 ? 1 : resolved / total;\n\nexport const assessIRFidelity = (ir: StaticEffectIR): IRFidelityAssessment => {\n  const index = indexIR(ir);\n  const findings: FidelityFinding[] = [];\n  const sourceUnresolvedIds = new Set<string>();\n  const runtimeInexactIds = new Set<string>();\n  const runtimeNodeIds = new Set(index.spanPathById.keys());\n\n  for (const node of index.nodes) {\n    const finding = findingForNode(node);\n    if (!finding) continue;\n    findings.push(finding);\n    if (finding.kind === 'unknown-node' || finding.kind === 'opaque-node') {\n      sourceUnresolvedIds.add(node.id);\n    }\n    if (finding.kind === 'dynamic-span-name') {\n      runtimeNodeIds.add(node.id);\n      runtimeInexactIds.add(node.id);\n    }\n  }\n\n  for (const [spanPath, ids] of index.idsBySpanPath) {\n    if (ids.length < 2) continue;\n    const printablePath = spanPath.split('\\u001f').join(' > ');\n    for (const nodeId of ids) {\n      runtimeInexactIds.add(nodeId);\n      const node = index.byId.get(nodeId);\n      findings.push({\n        kind: 'duplicate-span-path',\n        nodeId,\n        message: `Multiple static nodes emit the runtime span path \"${printablePath}\".`,\n        suggestion: 'Give sibling Effect.withSpan or Effect.fn regions distinct literal names.',\n        location: node?.location,\n      });\n    }\n  }\n\n  for (const nodeId of sourceUnresolvedIds) {\n    if (runtimeNodeIds.has(nodeId)) runtimeInexactIds.add(nodeId);\n  }\n\n  const sourceResolved = index.nodes.length - sourceUnresolvedIds.size;\n  const runtimeResolved = runtimeNodeIds.size - runtimeInexactIds.size;\n  const penalizedIds = new Set([...sourceUnresolvedIds, ...runtimeInexactIds]);\n  const score = index.nodes.length === 0\n    ? 100\n    : Math.round(((index.nodes.length - penalizedIds.size) / index.nodes.length) * 100);\n\n  return {\n    exact: findings.length === 0,\n    score,\n    sourceRepresentation: {\n      exact: sourceUnresolvedIds.size === 0,\n      resolved: sourceResolved,\n      total: index.nodes.length,\n      rate: rate(sourceResolved, index.nodes.length),\n    },\n    runtimeJoinability: {\n      exact: runtimeInexactIds.size === 0,\n      resolved: runtimeResolved,\n      total: runtimeNodeIds.size,\n      rate: rate(runtimeResolved, runtimeNodeIds.size),\n    },\n    staticOnlyNodes: index.nodes.length - index.spanPathById.size,\n    findings,\n  };\n};\n","/** Diagram fidelity: whether the IR honestly represents the source program. */\n\nimport type { SourceLocation, StaticEffectIR } from './types';\nimport { indexIR, spanPathKey } from './ir';\nimport {\n  assessIRFidelity,\n  type FidelityFindingKind,\n} from './fidelity-findings';\n\nexport type DiagramFidelityIssueKind = FidelityFindingKind;\n\nexport interface DiagramFidelityIssue {\n  readonly kind: DiagramFidelityIssueKind;\n  readonly nodeId: string;\n  readonly message: string;\n  readonly suggestion: string;\n  readonly location?: SourceLocation | undefined;\n}\n\nexport interface DiagramFidelityReport {\n  readonly exact: boolean;\n  readonly score: number;\n  readonly totalNodes: number;\n  readonly exactRuntimeNodes: number;\n  readonly staticOnlyNodes: number;\n  readonly ambiguousRuntimeNodes: number;\n  readonly unresolvedNodes: number;\n  readonly issues: readonly DiagramFidelityIssue[];\n}\n\nexport const computeDiagramFidelity = (\n  ir: StaticEffectIR,\n): DiagramFidelityReport => {\n  const assessment = assessIRFidelity(ir);\n  const issues: readonly DiagramFidelityIssue[] = assessment.findings;\n\n  return {\n    exact: assessment.exact,\n    score: assessment.score,\n    totalNodes: assessment.sourceRepresentation.total,\n    exactRuntimeNodes: assessment.runtimeJoinability.resolved,\n    staticOnlyNodes: assessment.staticOnlyNodes,\n    ambiguousRuntimeNodes: new Set(issues\n      .filter((issue) => issue.kind === 'duplicate-span-path')\n      .map((issue) => issue.nodeId)).size,\n    unresolvedNodes: new Set(issues\n      .filter((issue) => issue.kind !== 'duplicate-span-path')\n      .map((issue) => issue.nodeId)).size,\n    issues,\n  };\n};\n\nexport const formatDiagramFidelity = (\n  report: DiagramFidelityReport,\n): string => {\n  if (report.exact) {\n    return `✓ Exact diagram fidelity (${String(report.score)}/100)`;\n  }\n  const lines = [\n    `✗ Inexact diagram fidelity (${String(report.score)}/100): ${String(report.issues.length)} issue${report.issues.length === 1 ? '' : 's'}`,\n    '',\n  ];\n  for (const issue of report.issues) {\n    const location = issue.location\n      ? `${issue.location.filePath}:${String(issue.location.line)}:${String(issue.location.column)}`\n      : issue.nodeId;\n    lines.push(`[${issue.kind}] ${location}`, `  ${issue.message}`, `  Fix: ${issue.suggestion}`, '');\n  }\n  return lines.join('\\n').trimEnd();\n};\n\nexport const findStaticNodesForSpanPath = (\n  ir: StaticEffectIR,\n  path: readonly string[],\n): readonly string[] => indexIR(ir).idsBySpanPath.get(spanPathKey(path)) ?? [];\n","/**\n * Error Channel Analysis — cross-file report of error handling quality.\n *\n * Detects:\n * - Programs with generic `E` error types instead of concrete errors\n * - Missing catchTag handlers for known tagged errors\n * - Error type widening patterns\n * - Unhandled error types across the project\n */\n\nimport type {\n  StaticEffectIR,\n  StaticFlowNode,\n  StaticErrorHandlerNode,\n} from './types';\nimport {\n  isStaticEffectNode,\n  isStaticErrorHandlerNode,\n  getStaticChildren,\n} from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ErrorChannelIssue {\n  readonly type: 'generic-error' | 'unhandled-error' | 'missing-catch-tag' | 'error-type-widening' | 'no-error-handlers';\n  readonly programName: string;\n  readonly filePath: string;\n  readonly line: number;\n  readonly errorType: string;\n  readonly description: string;\n  readonly suggestion: string;\n  readonly severity: 'error' | 'warning' | 'info';\n}\n\nexport interface ErrorChannelAnalysis {\n  readonly issues: readonly ErrorChannelIssue[];\n  readonly summary: ErrorChannelSummary;\n}\n\nexport interface ErrorChannelSummary {\n  readonly totalPrograms: number;\n  readonly programsWithGenericError: number;\n  readonly programsWithNoErrorHandlers: number;\n  readonly programsWithUnhandledErrors: number;\n  readonly uniqueErrorTypes: readonly string[];\n  readonly topErrorTypes: readonly { readonly type: string; readonly count: number }[];\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport const analyzeErrorChannels = (\n  irs: readonly StaticEffectIR[],\n): ErrorChannelAnalysis => {\n  const issues: ErrorChannelIssue[] = [];\n  const errorTypeCounts = new Map<string, number>();\n  let programsWithGenericError = 0;\n  let programsWithNoErrorHandlers = 0;\n  let programsWithUnhandledErrors = 0;\n\n  for (const ir of irs) {\n    const programIssues = analyzeProgramErrorChannel(ir);\n    issues.push(...programIssues);\n\n    // Count error types\n    for (const et of ir.root.errorTypes) {\n      const normalized = et.trim();\n      if (normalized && normalized !== 'never') {\n        errorTypeCounts.set(normalized, (errorTypeCounts.get(normalized) ?? 0) + 1);\n      }\n    }\n\n    // Check for generic error type\n    const hasGenericError = ir.root.errorTypes.some(\n      (e) => e.trim() === 'unknown' || e.trim() === 'Error' || e.trim() === 'E',\n    );\n    if (hasGenericError) {\n      programsWithGenericError++;\n    }\n\n    // Check for error handlers\n    const errorHandlerCount = countErrorHandlers(ir.root);\n    if (errorHandlerCount === 0 && ir.root.errorTypes.some((e) => e.trim() !== 'never')) {\n      programsWithNoErrorHandlers++;\n    }\n  }\n\n  // Find programs with unhandled errors (error types not caught by any handler)\n  for (const ir of irs) {\n    const unhandled = findUnhandledErrors(ir);\n    if (unhandled.length > 0) {\n      programsWithUnhandledErrors++;\n      for (const uh of unhandled) {\n        issues.push({\n          type: 'unhandled-error',\n          programName: ir.root.programName,\n          filePath: ir.metadata.filePath,\n          line: ir.root.location?.line ?? 1,\n          errorType: uh,\n          description: `Error type \"${uh}\" is not handled in program \"${ir.root.programName}\"`,\n          suggestion: `Add a catchTag(\"${uh}\", handler) or catch handler for this error type`,\n          severity: 'warning',\n        });\n      }\n    }\n  }\n\n  const uniqueErrorTypes = [...errorTypeCounts.keys()].sort();\n  const topErrorTypes = [...errorTypeCounts.entries()]\n    .sort((a, b) => b[1] - a[1])\n    .slice(0, 20)\n    .map(([type, count]) => ({ type, count }));\n\n  return {\n    issues,\n    summary: {\n      totalPrograms: irs.length,\n      programsWithGenericError,\n      programsWithNoErrorHandlers,\n      programsWithUnhandledErrors,\n      uniqueErrorTypes,\n      topErrorTypes,\n    },\n  };\n};\n\nconst analyzeProgramErrorChannel = (ir: StaticEffectIR): ErrorChannelIssue[] => {\n  const issues: ErrorChannelIssue[] = [];\n\n  // Check for generic error type on the program level\n  for (const errorType of ir.root.errorTypes) {\n    const normalized = errorType.trim();\n    if (normalized === 'unknown') {\n      issues.push({\n        type: 'generic-error',\n        programName: ir.root.programName,\n        filePath: ir.metadata.filePath,\n        line: ir.root.location?.line ?? 1,\n        errorType: 'unknown',\n        description: `Program \"${ir.root.programName}\" has unknown error type — all errors are possible`,\n        suggestion: 'Define specific tagged errors and narrow the error channel',\n        severity: 'warning',\n      });\n    } else if (normalized === 'Error') {\n      issues.push({\n        type: 'generic-error',\n        programName: ir.root.programName,\n        filePath: ir.metadata.filePath,\n        line: ir.root.location?.line ?? 1,\n        errorType: 'Error',\n        description: `Program \"${ir.root.programName}\" has built-in Error type — catchTag cannot discriminate`,\n        suggestion: 'Use Data.TaggedError for typed error channels',\n        severity: 'warning',\n      });\n    }\n  }\n\n  // Check for error type widening (mapErrorCause, orElse, etc. that widen)\n  visitNodes(ir.root, (node) => {\n    if (isStaticErrorHandlerNode(node)) {\n      checkErrorHandlerWidening(node, ir, issues);\n    }\n  });\n\n  return issues;\n};\n\nconst checkErrorHandlerWidening = (\n  node: StaticErrorHandlerNode,\n  ir: StaticEffectIR,\n  issues: ErrorChannelIssue[],\n): void => {\n  // orDie converts typed errors to defects (widening)\n  if (node.handlerType === 'orDie' || node.handlerType === 'orDieWith') {\n    issues.push({\n      type: 'error-type-widening',\n      programName: ir.root.programName,\n      filePath: ir.metadata.filePath,\n      line: node.location?.line ?? 1,\n      errorType: 'defect',\n      description: `${node.handlerType} converts typed errors to defects — loses type safety`,\n      suggestion: 'Reserve orDie for truly unrecoverable errors; use catchTag for recoverable ones',\n      severity: 'info',\n    });\n  }\n\n  // ignore/ignoreLogged swallows errors\n  if (node.handlerType === 'ignore' || node.handlerType === 'ignoreLogged') {\n    issues.push({\n      type: 'error-type-widening',\n      programName: ir.root.programName,\n      filePath: ir.metadata.filePath,\n      line: node.location?.line ?? 1,\n      errorType: 'void',\n      description: `${node.handlerType} swallows errors — recovery is impossible`,\n      suggestion: 'Ensure errors are truly ignorable; consider Effect.logError + Effect.succeed for observable swallowing',\n      severity: 'warning',\n    });\n  }\n\n  // eventually retries forever — can mask errors\n  if (node.handlerType === 'eventually') {\n    issues.push({\n      type: 'error-type-widening',\n      programName: ir.root.programName,\n      filePath: ir.metadata.filePath,\n      line: node.location?.line ?? 1,\n      errorType: 'never',\n      description: 'eventually retries forever — errors are never surfaced',\n      suggestion: 'Use retry with a bounded schedule (Schedule.recurs, Schedule.upTo) for observable retry behavior',\n      severity: 'info',\n    });\n  }\n};\n\nconst findUnhandledErrors = (ir: StaticEffectIR): readonly string[] => {\n  const caughtTags = new Set<string>();\n  const hasCatchAll = { value: false };\n\n  visitNodes(ir.root, (node) => {\n    if (isStaticErrorHandlerNode(node)) {\n      if (node.handlerType === 'catch' || node.handlerType === 'catchCause') {\n        hasCatchAll.value = true;\n      }\n      if (node.handlerType === 'catchTag' && node.errorTag) {\n        caughtTags.add(node.errorTag);\n      }\n      if (node.handlerType === 'catchTags' && node.errorTags) {\n        for (const tag of node.errorTags) {\n          caughtTags.add(tag);\n        }\n      }\n    }\n  });\n\n  // If there's a catch, all errors are handled (albeit generically)\n  if (hasCatchAll.value) return [];\n\n  // Collect error types from effect nodes that aren't caught\n  const unhandled: string[] = [];\n  visitNodes(ir.root, (node) => {\n    if (isStaticEffectNode(node) && node.typeSignature) {\n      const errType = node.typeSignature.errorType.trim();\n      if (errType && errType !== 'never' && errType !== 'unknown' && errType !== 'Error') {\n        // Check if this looks like a tagged error (has _tag pattern)\n        const tagMatch = /\\{.*_tag.*:.*\"([^\"]+)\".*\\}/.exec(errType);\n        if (tagMatch && tagMatch[1]) {\n          const tag = tagMatch[1];\n          if (!caughtTags.has(tag)) {\n            unhandled.push(tag);\n          }\n        }\n      }\n    }\n  });\n\n  return [...new Set(unhandled)];\n};\n\nconst countErrorHandlers = (node: StaticFlowNode | { children: readonly StaticFlowNode[] }): number => {\n  let count = 0;\n\n  const visit = (n: StaticFlowNode) => {\n    if (isStaticErrorHandlerNode(n)) {\n      count++;\n    }\n    const childrenOpt = getStaticChildren(n);\n    if (Option.isSome(childrenOpt)) {\n      for (const child of childrenOpt.value) {\n        visit(child);\n      }\n    }\n  };\n\n  if ('children' in node) {\n    const children = (node as { children: readonly StaticFlowNode[] }).children;\n    for (const child of children) {\n      visit(child);\n    }\n  } else {\n    visit(node);\n  }\n\n  return count;\n};\n\nconst visitNodes = (\n  root: { children: readonly StaticFlowNode[] } | StaticFlowNode,\n  fn: (node: StaticFlowNode) => void,\n): void => {\n  const visit = (node: StaticFlowNode) => {\n    fn(node);\n    const childrenOpt = getStaticChildren(node);\n    if (Option.isSome(childrenOpt)) {\n      for (const child of childrenOpt.value) {\n        visit(child);\n      }\n    }\n  };\n\n  if ('children' in root) {\n    const children = (root as { children: readonly StaticFlowNode[] }).children;\n    for (const child of children) {\n      visit(child);\n    }\n  } else {\n    visit(root);\n  }\n};\n\n// =============================================================================\n// Renderers\n// =============================================================================\n\nexport const renderErrorChannelReport = (analysis: ErrorChannelAnalysis): string => {\n  const lines: string[] = [];\n  const s = analysis.summary;\n\n  lines.push('# Error Channel Analysis\\n');\n  lines.push('## Summary\\n');\n  lines.push(`- Total programs: ${s.totalPrograms}`);\n  lines.push(`- Programs with generic error: ${s.programsWithGenericError}`);\n  lines.push(`- Programs with no error handlers: ${s.programsWithNoErrorHandlers}`);\n  lines.push(`- Programs with unhandled errors: ${s.programsWithUnhandledErrors}`);\n  lines.push('');\n\n  if (s.topErrorTypes.length > 0) {\n    lines.push('## Top Error Types\\n');\n    lines.push('| Error Type | Count |');\n    lines.push('|------------|-------|');\n    for (const { type, count } of s.topErrorTypes) {\n      lines.push(`| \\`${type}\\` | ${count} |`);\n    }\n    lines.push('');\n  }\n\n  if (analysis.issues.length > 0) {\n    lines.push('## Issues\\n');\n    for (const issue of analysis.issues) {\n      const icon = issue.severity === 'error' ? '❌' : issue.severity === 'warning' ? '⚠️' : 'ℹ️';\n      lines.push(`${icon} **[${issue.type}]** ${issue.programName}`);\n      lines.push(`   Error: \\`${issue.errorType}\\``);\n      lines.push(`   ${issue.description}`);\n      lines.push(`   at ${issue.filePath}:${issue.line}`);\n      lines.push(`   💡 ${issue.suggestion}`);\n      lines.push('');\n    }\n  }\n\n  return lines.join('\\n');\n};\n\nexport const renderErrorChannelJson = (analysis: ErrorChannelAnalysis, pretty = true): string =>\n  JSON.stringify(analysis, null, pretty ? 2 : 0);\n","/**\n * Service Dependency Health — detects service DI issues across a project.\n *\n * Detects:\n * - Unsatisfied services (required but never provided)\n * - Dead services (defined but never consumed)\n * - Layer inefficiencies (multiple provides that could be merged)\n * - Duplicate provides in merge chains\n */\n\nimport type { StaticEffectIR } from './types';\nimport { isStaticLayerNode, getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ServiceHealthIssue {\n  readonly type: 'unsatisfied' | 'dead-service' | 'layer-inefficiency' | 'duplicate-provide';\n  readonly service: string;\n  readonly description: string;\n  readonly files: readonly string[];\n  readonly suggestion: string;\n  readonly severity: 'error' | 'warning' | 'info';\n}\n\nexport interface ServiceHealthAnalysis {\n  readonly issues: readonly ServiceHealthIssue[];\n  readonly summary: ServiceHealthSummary;\n}\n\nexport interface ServiceHealthSummary {\n  readonly totalServices: number;\n  readonly satisfiedServices: number;\n  readonly unsatisfiedServices: number;\n  readonly deadServices: number;\n  readonly layerInefficiencies: number;\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport interface ServiceRegistry {\n  readonly defined: Map<string, readonly string[]>; // service -> files where defined\n  readonly required: Map<string, readonly string[]>; // service -> files where required\n  readonly provided: Map<string, readonly string[]>; // service -> files where provided\n}\n\nexport const buildServiceRegistry = (\n  irs: readonly StaticEffectIR[],\n  serviceDefinitions: ReadonlyMap<string, { tagId: string; methods: readonly string[]; properties: readonly string[] }[]> = new Map(),\n): ServiceRegistry => {\n  const defined = new Map<string, string[]>();\n  const required = new Map<string, string[]>();\n  const provided = new Map<string, string[]>();\n\n  // Collect from service definitions (Effect.Service classes, Context.Tags)\n  for (const [filePath, defs] of serviceDefinitions) {\n    for (const def of defs) {\n      const files = defined.get(def.tagId) ?? [];\n      files.push(filePath);\n      defined.set(def.tagId, files);\n    }\n  }\n\n  // Collect from IRs\n  for (const ir of irs) {\n    const filePath = ir.metadata.filePath;\n\n    // Requirements\n    if (ir.root.requiredServices) {\n      for (const req of ir.root.requiredServices) {\n        const files = required.get(req.serviceId) ?? [];\n        files.push(filePath);\n        required.set(req.serviceId, files);\n      }\n    }\n\n    // Dependencies\n    for (const dep of ir.root.dependencies) {\n      if (dep.isLayer) {\n        const files = provided.get(dep.name) ?? [];\n        files.push(filePath);\n        provided.set(dep.name, files);\n      }\n    }\n  }\n\n  return {\n    defined: new Map([...defined.entries()].map(([k, v]) => [k, [...new Set(v)]])),\n    required: new Map([...required.entries()].map(([k, v]) => [k, [...new Set(v)]])),\n    provided: new Map([...provided.entries()].map(([k, v]) => [k, [...new Set(v)]])),\n  };\n};\n\nexport const analyzeServiceHealth = (\n  registry: ServiceRegistry,\n  irs: readonly StaticEffectIR[],\n): ServiceHealthAnalysis => {\n  const issues: ServiceHealthIssue[] = [];\n\n  // Find unsatisfied services\n  const unsatisfied = findUnsatisfiedServices(registry);\n  for (const { service, files } of unsatisfied) {\n    issues.push({\n      type: 'unsatisfied',\n      service,\n      description: `Service \"${service}\" is required but never provided in the project`,\n      files,\n      suggestion: `Provide a Layer for \"${service}\" or remove the requirement if unused`,\n      severity: 'error',\n    });\n  }\n\n  // Find dead services\n  const dead = findDeadServices(registry);\n  for (const { service, files } of dead) {\n    issues.push({\n      type: 'dead-service',\n      service,\n      description: `Service \"${service}\" is defined but never consumed`,\n      files,\n      suggestion: `Remove \"${service}\" if unused, or wire it into the dependency graph`,\n      severity: 'info',\n    });\n  }\n\n  // Find layer inefficiencies\n  const layerIssues = findLayerInefficiencies(irs);\n  issues.push(...layerIssues);\n\n  const satisfiedCount = [...registry.required.keys()].filter(\n    (s) => registry.provided.has(s),\n  ).length;\n\n  return {\n    issues,\n    summary: {\n      totalServices: new Set([...registry.required.keys(), ...registry.provided.keys()]).size,\n      satisfiedServices: satisfiedCount,\n      unsatisfiedServices: unsatisfied.length,\n      deadServices: dead.length,\n      layerInefficiencies: layerIssues.length,\n    },\n  };\n};\n\nconst findUnsatisfiedServices = (\n  registry: ServiceRegistry,\n): readonly { readonly service: string; readonly files: readonly string[] }[] => {\n  const unsatisfied: { service: string; files: readonly string[] }[] = [];\n\n  for (const [service, files] of registry.required) {\n    if (!registry.provided.has(service) && !registry.defined.has(service)) {\n      unsatisfied.push({ service, files });\n    }\n  }\n\n  return unsatisfied;\n};\n\nconst findDeadServices = (\n  registry: ServiceRegistry,\n): readonly { readonly service: string; readonly files: readonly string[] }[] => {\n  const dead: { service: string; files: readonly string[] }[] = [];\n\n  for (const [service, files] of registry.defined) {\n    if (!registry.required.has(service)) {\n      dead.push({ service, files });\n    }\n  }\n\n  return dead;\n};\n\nconst findLayerInefficiencies = (\n  irs: readonly StaticEffectIR[],\n): ServiceHealthIssue[] => {\n  const issues: ServiceHealthIssue[] = [];\n\n  for (const ir of irs) {\n    const provideCount = countLayerProvides(ir.root);\n    if (provideCount > 3) {\n      issues.push({\n        type: 'layer-inefficiency',\n        service: ir.root.programName,\n        description: `Program \"${ir.root.programName}\" has ${provideCount} Layer.provide calls — consider Layer.mergeAll`,\n        files: [ir.metadata.filePath],\n        suggestion: 'Merge multiple Layer.provide calls into a single Layer.mergeAll for cleaner composition',\n        severity: 'info',\n      });\n    }\n  }\n\n  return issues;\n};\n\nconst countLayerProvides = (node: { children: readonly import('./types').StaticFlowNode[] }): number => {\n  let count = 0;\n\n  const visit = (n: import('./types').StaticFlowNode) => {\n    if (isStaticLayerNode(n)) {\n      count++;\n    }\n    // Also count Effect.provide operations\n    if (n.type === 'effect' && (n.callee.includes('provide') || n.callee.includes('Layer.'))) {\n      count++;\n    }\n    const childrenOpt = getStaticChildren(n);\n    if (Option.isSome(childrenOpt)) {\n      for (const child of childrenOpt.value) {\n        visit(child);\n      }\n    }\n  };\n\n  for (const child of node.children) {\n    visit(child);\n  }\n\n  return count;\n};\n\n// =============================================================================\n// Renderers\n// =============================================================================\n\nexport const renderServiceHealthReport = (analysis: ServiceHealthAnalysis): string => {\n  const lines: string[] = [];\n  const s = analysis.summary;\n\n  lines.push('# Service Dependency Health\\n');\n  lines.push('## Summary\\n');\n  lines.push(`- Total services: ${s.totalServices}`);\n  lines.push(`- Satisfied: ${s.satisfiedServices}`);\n  lines.push(`- Unsatisfied: ${s.unsatisfiedServices}`);\n  lines.push(`- Dead (unused): ${s.deadServices}`);\n  lines.push(`- Layer inefficiencies: ${s.layerInefficiencies}`);\n  lines.push('');\n\n  if (analysis.issues.length > 0) {\n    lines.push('## Issues\\n');\n    for (const issue of analysis.issues) {\n      const icon = issue.severity === 'error' ? '❌' : issue.severity === 'warning' ? '⚠️' : 'ℹ️';\n      const typeLabel = issue.type === 'unsatisfied'\n        ? 'Unsatisfied Service'\n        : issue.type === 'dead-service'\n          ? 'Dead Service'\n          : issue.type === 'layer-inefficiency'\n            ? 'Layer Inefficiency'\n            : 'Duplicate Provide';\n      lines.push(`${icon} **[${typeLabel}]** ${issue.service}`);\n      lines.push(`   ${issue.description}`);\n      if (issue.files.length > 0) {\n        lines.push(`   Files: ${issue.files.slice(0, 5).join(', ')}${issue.files.length > 5 ? ` (+${issue.files.length - 5} more)` : ''}`);\n      }\n      lines.push(`   💡 ${issue.suggestion}`);\n      lines.push('');\n    }\n  }\n\n  return lines.join('\\n');\n};\n\nexport const renderServiceHealthJson = (analysis: ServiceHealthAnalysis, pretty = true): string =>\n  JSON.stringify(analysis, null, pretty ? 2 : 0);\n","/**\n * Performance Anti-Patterns — detects common performance issues in Effect code.\n *\n * Detects:\n * - Sequential operations that could be parallel (Effect.all)\n * - Unbounded concurrency on large collections\n * - Missing request batching (N+1 patterns)\n * - Unbounded retries without Schedule.recurs or Schedule.upTo\n * - Large gen blocks (>50 yields)\n * - Effect.forEach without concurrency option\n */\n\nimport type {\n  StaticEffectIR,\n  StaticFlowNode,\n} from './types';\nimport {\n  isStaticParallelNode,\n  isStaticRetryNode,\n  isStaticGeneratorNode,\n  isStaticEffectNode,\n  getStaticChildren,\n} from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface PerformanceIssue {\n  readonly type: 'sequential-could-parallel' | 'unbounded-concurrency' | 'n-plus-one' | 'large-gen-block' | 'missing-batching' | 'unbounded-retry' | 'forEach-sequential';\n  readonly filePath: string;\n  readonly programName: string;\n  readonly line: number;\n  readonly description: string;\n  readonly suggestion: string;\n  readonly estimatedImpact: 'low' | 'medium' | 'high';\n}\n\nexport interface PerformanceAnalysis {\n  readonly issues: readonly PerformanceIssue[];\n  readonly summary: PerformanceSummary;\n}\n\nexport interface PerformanceSummary {\n  readonly totalPrograms: number;\n  readonly sequentialCouldParallel: number;\n  readonly unboundedConcurrency: number;\n  readonly largeGenBlocks: number;\n  readonly unboundedRetries: number;\n  readonly forEachSequential: number;\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport const analyzePerformance = (\n  irs: readonly StaticEffectIR[],\n): PerformanceAnalysis => {\n  const issues: PerformanceIssue[] = [];\n  let sequentialCouldParallel = 0;\n  let unboundedConcurrency = 0;\n  let largeGenBlocks = 0;\n  let unboundedRetries = 0;\n  let forEachSequential = 0;\n\n  for (const ir of irs) {\n    const filePath = ir.metadata.filePath;\n    const programName = ir.root.programName;\n\n    visitNodes(ir.root, (node) => {\n      // Check for unbounded parallelism\n      if (isStaticParallelNode(node)) {\n        if (node.concurrency === 'unbounded' && node.children.length > 5) {\n          issues.push({\n            type: 'unbounded-concurrency',\n            filePath,\n            programName,\n            line: node.location?.line ?? 1,\n            description: `Effect.all with unbounded concurrency (${node.children.length} branches) — can overwhelm resources`,\n            suggestion: 'Use { concurrency: N } to limit parallelism (e.g., { concurrency: 4 })',\n            estimatedImpact: 'high',\n          });\n          unboundedConcurrency++;\n        }\n\n        // Check for sequential that could be parallel\n        if (node.mode === 'sequential' && node.children.length >= 3) {\n          // Heuristic: if all children are independent effects (no data dependencies), suggest parallel\n          const allIndependent = node.children.every((child) => {\n            if (child.type === 'effect') {\n              // Simple heuristic: if it's a service call or constructor, likely independent\n              return child.callee.includes('Effect.') || child.serviceCall !== undefined;\n            }\n            return false;\n          });\n\n          if (allIndependent) {\n            issues.push({\n              type: 'sequential-could-parallel',\n              filePath,\n              programName,\n              line: node.location?.line ?? 1,\n              description: `Effect.all runs ${node.children.length} independent effects sequentially — could be parallel`,\n              suggestion: 'Use Effect.all(effects, { concurrency: \"unbounded\" }) for parallel execution',\n              estimatedImpact: 'medium',\n            });\n            sequentialCouldParallel++;\n          }\n        }\n      }\n\n      // Check for large gen blocks\n      if (isStaticGeneratorNode(node)) {\n        const yieldCount = node.yields.length;\n        if (yieldCount > 30) {\n          issues.push({\n            type: 'large-gen-block',\n            filePath,\n            programName,\n            line: node.location?.line ?? 1,\n            description: `Effect.gen has ${yieldCount} yields — consider breaking into smaller functions`,\n            suggestion: 'Extract logical sections into separate Effect-returning functions for better testability and readability',\n            estimatedImpact: 'low',\n          });\n          largeGenBlocks++;\n        }\n      }\n\n      // Check for unbounded retries\n      if (isStaticRetryNode(node)) {\n        const schedule = node.schedule ?? '';\n        const hasBound = schedule.includes('recurs') ||\n          schedule.includes('upTo') ||\n          schedule.includes('intersect') ||\n          schedule.includes('whileOutput');\n\n        if (!hasBound && (schedule.includes('forever') || schedule.includes('spaced') || schedule.includes('exponential') || schedule.includes('fibonacci'))) {\n          issues.push({\n            type: 'unbounded-retry',\n            filePath,\n            programName,\n            line: node.location?.line ?? 1,\n            description: `Retry uses unbounded schedule — can run forever`,\n            suggestion: 'Add Schedule.recurs(N) or Schedule.upTo(duration) to bound retries',\n            estimatedImpact: 'medium',\n          });\n          unboundedRetries++;\n        }\n      }\n\n      // Check for Effect.forEach without concurrency\n      if (isStaticEffectNode(node) && node.callee === 'Effect.forEach') {\n        // Heuristic: check if the source text includes concurrency option\n        // This is a rough check — the actual source would need to be inspected\n        issues.push({\n          type: 'forEach-sequential',\n          filePath,\n          programName,\n          line: node.location?.line ?? 1,\n          description: 'Effect.forEach without explicit concurrency — defaults to sequential',\n          suggestion: 'Add { concurrency: \"unbounded\" } or { concurrency: N } to make the choice explicit',\n          estimatedImpact: 'medium',\n        });\n        forEachSequential++;\n      }\n    });\n  }\n\n  return {\n    issues,\n    summary: {\n      totalPrograms: irs.length,\n      sequentialCouldParallel,\n      unboundedConcurrency,\n      largeGenBlocks,\n      unboundedRetries,\n      forEachSequential,\n    },\n  };\n};\n\nconst visitNodes = (\n  root: { children: readonly StaticFlowNode[] } | StaticFlowNode,\n  fn: (node: StaticFlowNode) => void,\n): void => {\n  const visit = (node: StaticFlowNode) => {\n    fn(node);\n    const childrenOpt = getStaticChildren(node);\n    if (Option.isSome(childrenOpt)) {\n      for (const child of childrenOpt.value) {\n        visit(child);\n      }\n    }\n  };\n\n  if ('children' in root) {\n    const children = (root as { children: readonly StaticFlowNode[] }).children;\n    for (const child of children) {\n      visit(child);\n    }\n  } else {\n    visit(root);\n  }\n};\n\n// =============================================================================\n// Renderers\n// =============================================================================\n\nexport const renderPerformanceReport = (analysis: PerformanceAnalysis): string => {\n  const lines: string[] = [];\n  const s = analysis.summary;\n\n  lines.push('# Performance Anti-Patterns\\n');\n  lines.push('## Summary\\n');\n  lines.push(`- Total programs: ${s.totalPrograms}`);\n  lines.push(`- Sequential could be parallel: ${s.sequentialCouldParallel}`);\n  lines.push(`- Unbounded concurrency: ${s.unboundedConcurrency}`);\n  lines.push(`- Large gen blocks: ${s.largeGenBlocks}`);\n  lines.push(`- Unbounded retries: ${s.unboundedRetries}`);\n  lines.push(`- forEach without concurrency: ${s.forEachSequential}`);\n  lines.push('');\n\n  if (analysis.issues.length > 0) {\n    lines.push('## Issues\\n');\n    for (const issue of analysis.issues) {\n      const impactIcon = issue.estimatedImpact === 'high' ? '🔴' : issue.estimatedImpact === 'medium' ? '🟡' : '🟢';\n      lines.push(`${impactIcon} **[${issue.type}]** ${issue.programName}`);\n      lines.push(`   ${issue.description}`);\n      lines.push(`   at ${issue.filePath}:${issue.line}`);\n      lines.push(`   💡 ${issue.suggestion}`);\n      lines.push('');\n    }\n  }\n\n  return lines.join('\\n');\n};\n\nexport const renderPerformanceJson = (analysis: PerformanceAnalysis, pretty = true): string =>\n  JSON.stringify(analysis, null, pretty ? 2 : 0);\n"],"mappings":"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KC,EAAQ,KAAK,CAAC,EACzBA,EAAU,GACV,QACF,CAEAA,GAAWI,CACb,CAEA,IAAMC,EAAOL,EAAQ,KAAK,EAC1B,OAAIK,GAAMN,EAAM,KAAKM,CAAI,EAElBN,EAAM,OAAO,OAAO,CAC7B,CAaA,IAAMO,GAAgBC,GACpBA,EACG,QAAQ,qBAAsB,EAAE,EAChC,QAAQ,aAAc,EAAE,EACxB,KAAK,EACL,UAAU,EAAG,GAAG,EAIrB,IAAMC,GAAmB,uCAsBlB,SAASC,GAA0BC,EAA4C,CACpF,IAAMC,EAAWD,EAAK,QAAQ,EAAE,QAAQ,EAClCE,EAAQC,GAAiB,KAAKF,CAAQ,EAC5C,GAAKC,EACL,MAAO,CACL,aAAcE,GAAaF,EAAM,CAAC,CAAE,EACpC,UAAWE,GAAaF,EAAM,CAAC,CAAE,EACjC,aAAcE,GAAaF,EAAM,CAAC,CAAE,EACpC,cAAeD,CACjB,CACF,CCplBO,IAAMI,GAAyB,CACpC,SACA,YACA,cACA,WACA,aACA,kBACA,mBACA,eACA,aACA,UACA,cACA,iBACA,SACA,aACA,QACA,YACA,iBACA,WACA,WACA,aACA,kBACA,eACA,sBACA,gBACA,gBACA,SACA,cACA,eACA,oBACA,kBACA,UACA,gBACA,aACF,EAEaC,GAAuB,CAClC,MACA,QACA,cACA,gBACA,WACA,UACA,gBACA,UACA,UACA,QACA,gBACF,EAEaC,GAAoB,CAC/B,kBACA,qBACA,YACA,gBACA,UACA,WACA,sBACA,wBACA,kBACA,SACA,mBACF,EAEaC,GAAsB,CACjC,WACA,QACA,UACA,aACA,aACA,UACA,eACA,eACA,gBACA,aACA,aACA,aACA,aACA,SACA,UACA,aACA,QACA,YACA,aACA,mBACA,eACA,iBACA,YACA,eACF,EAEaC,GAAiB,CAC5B,cACA,QACA,WACA,UACA,wBACA,QACF,EAMaC,GAAsE,CACjF,aAAc,MACd,iBAAkB,UAClB,iBAAkB,UAClB,aAAc,MACd,iBAAkB,UAClB,kBAAmB,WACnB,qBAAsB,cACtB,uBAAwB,gBACxB,mBAAoB,YACpB,iBAAkB,UAClB,kBAAmB,WACnB,iBAAkB,UAClB,aAAc,MACd,YAAa,KACb,gBAAiB,SACjB,gBAAiB,SACjB,qBAAsB,cACtB,iBAAkB,UAClB,YAAa,KACb,gBAAiB,SACjB,eAAgB,OAClB,EACaC,GAAuB,IAAI,IAAI,CAAC,UAAW,UAAW,UAAW,WAAY,cAAe,gBAAiB,YAAa,UAAW,UAAW,WAAY,MAAO,KAAM,SAAS,CAAC,EACnLC,GAAmBC,GAA4BA,KAAUH,GAEzDI,GAA2D,CACtE,aAAc,OACd,YAAa,MACb,cAAe,QACf,aAAc,OACd,eAAgB,SAChB,gBAAiB,UACjB,YAAa,MACb,WAAY,KACZ,mBAAoB,aACpB,eAAgB,SAChB,eAAgB,SAChB,eAAgB,SAChB,sBAAuB,gBACvB,iCAAkC,2BAClC,aAAc,OACd,uBAAwB,iBACxB,uBAAwB,iBACxB,YAAa,KACf,EACaC,GAAiB,IAAI,IAAI,CAAC,aAAc,2BAA4B,gBAAgB,CAAC,EACrFC,GAAeH,GAC1BA,EAAO,WAAW,QAAQ,GAAKA,KAAUC,GAE9BG,GAA2D,CACtE,aAAc,OACd,YAAa,MACb,kBAAmB,YACnB,iBAAkB,WAClB,mBAAoB,aACpB,cAAe,QACf,iBAAkB,WAClB,gBAAiB,UACjB,qBAAsB,eACtB,eAAgB,SAChB,mBAAoB,aACpB,eAAgB,SAChB,gBAAiB,UACjB,cAAe,QACf,kBAAmB,YACnB,sBAAuB,gBACvB,gBAAiB,UACjB,YAAa,MACb,eAAgB,QAClB,EACaC,GAAqB,IAAI,IAAI,CAAC,OAAQ,MAAO,YAAa,WAAY,aAAc,OAAO,CAAC,EAC5FC,GAAeN,GAC1BA,EAAO,WAAW,QAAQ,GAAKA,KAAUI,GAE9BG,GAAwD,CACnE,eAAgB,UAChB,YAAa,OACb,WAAY,MACZ,iBAAkB,YAClB,YAAa,OACb,YAAa,OACb,aAAc,QACd,iBAAkB,YAClB,iBAAkB,YAClB,qBAAsB,gBACtB,YAAa,OACb,kBAAmB,aACnB,cAAe,SACf,gBAAiB,WACjB,eAAgB,UAChB,WAAY,MACZ,eAAgB,UAChB,gBAAiB,WACjB,eAAgB,UAChB,eAAgB,UAChB,WAAY,MACZ,eAAgB,UAChB,gBAAiB,UACnB,EACaC,GAAoB,IAAI,IAAI,CAAC,UAAW,OAAQ,MAAO,YAAa,OAAQ,MAAM,CAAC,EACnFC,GAAcT,GACzBA,EAAO,WAAW,OAAO,IAAMA,KAAUO,IAAe,cAAc,KAAKP,CAAM,GAEtEU,GAAoE,CAC/E,uBAAwB,cACxB,qBAAsB,YACtB,kBAAmB,SACnB,iBAAkB,QAClB,kBAAmB,SACnB,gBAAiB,OACjB,oBAAqB,WACrB,oBAAqB,WACrB,mBAAoB,UACpB,kBAAmB,SACnB,gBAAiB,OACjB,gBAAiB,OACjB,iBAAkB,QAClB,mBAAoB,UACpB,oBAAqB,WACrB,mBAAoB,UACpB,qBAAsB,YACtB,iBAAkB,QAClB,mBAAoB,UACpB,mBAAoB,UACpB,oBAAqB,WACrB,uBAAwB,cACxB,iBAAkB,QAClB,sBAAuB,aACvB,qBAAsB,YACtB,kBAAmB,SACnB,kBAAmB,SACnB,oBAAqB,UACvB,EACaC,GAAkBX,GAC7BA,EAAO,WAAW,WAAW,IAAMA,KAAUU,IAAmB,kBAAkB,KAAKV,CAAM,GAElFY,GAAwB,CACnC,iBACA,mBACA,qBACA,uBACA,eACA,cACA,kBACA,mBACA,gBACF,EAEaC,GAAuB,CAClC,MACA,QACA,WACA,SACF,EAEaC,GAAmB,CAC9B,UACA,iBACA,2BACA,kBACA,QACA,SACA,cACF,EAMaC,GAAe,CAC1B,UACA,SACA,YACA,UACA,SACA,UACA,YACA,aACA,WACA,mBACA,SACA,SACA,WACA,kBACA,eACA,cACA,eACA,SACA,QACA,QACA,UACA,UACA,SACA,WACA,WACA,QACA,aACA,aACA,gBACA,QACA,SACA,SACA,UACA,UACA,SACA,eACA,SACA,SACA,cACA,SACA,eACA,eACA,wBACA,YACA,YACA,eACA,UACA,UACA,UACA,WACA,cACA,cACA,WACA,cACA,WACA,UACA,gBACA,UACA,YACA,iBACA,aACA,UACA,WACA,WACA,qBACA,SACA,YACA,aACA,YACA,QACA,cACA,YACA,YACA,eACA,WACA,QACA,UACA,QACA,WACA,WACA,aACA,e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","names":["rules_entry_exports","__export","DEFAULT_LINT_RULES","FLATMAP_CHAIN_DEFAULT_THRESHOLD","LARGE_GEN_DEFAULT_THRESHOLD","PROVIDE_MERGE_DEFAULT_THRESHOLD","SCORECARD_WEIGHTS","SEQUENTIAL_FAIL_DEFAULT_THRESHOLD","analyze","analyzeErrorChannels","analyzePerformance","analyzeServiceHealth","buildLintScorecard","buildRuleIndex","buildServiceRegistry","catchVsCatchTagRule","compareAgainstBaseline","complexLayerRule","computeDiagramFidelity","createFlatMapChainRule","createLargeGenBlockRule","createProvideMergeChainRule","createSequentialFailRule","deadCodeRule","deferredNoResolveRule","errorTypeTooWideRule","exitCodeFor","explainRule","findRuleDoc","findStaticNodesForSpanPath","fingerprintOf","flatMapChainRule","formatDiagnostics","formatDiagnosticsJSON","formatDiagramFidelity","formatLintReport","getRuleCodesForProfile","getSummary","largeGenBlockRule","lintEffectProgram","lintSourceCode","lintSourceFile","listAllRuleDocs","missingErrorHandlerRule","orDieWarningRule","provideMergeChainRule","redundantPipeRule","renderErrorChannelJson","renderErrorChannelReport","renderPerformanceJson","renderPerformanceReport","renderRuleDocsJson","renderRuleDocsText","renderRuleIndexJson","renderServiceHealthJson","renderServiceHealthReport","runSourceLintScan","searchRuleDocs","sequentialFailRule","swallowedErrorRule","toSarif","unboundedParallelismRule","untaggedYieldRule","validateStrict","__toCommonJS","import_node_module","import_meta","tsMorphModule","tsMorphLoader","projectCache","getBuiltinModule","id","loadNodeTsMorph","moduleBuiltin","createRequire","setTsMorphLoader","loader","tsMorphLoader","tsMorphModule","loadTsMorph","tsMorphModule","configuredModule","tsMorphLoader","loadNodeTsMorph","createProject","tsConfigPath","cacheKey","cached","projectCache","Project","options","project","createProjectFromSource","code","filePath","Project","loadTsMorph","import_meta","nodeModuleLocation","setTsMorphLoader","import_effect","import_effect","AnalysisError","code","message","location","isStaticEffectNode","node","isStaticGeneratorNode","isStaticPipeNode","isStaticParallelNode","isStaticErrorHandlerNode","node","isStaticRetryNode","isStaticLayerNode","node","isStaticTransformNode","node","isStaticConcurrencyPrimitiveNode","node","getStaticChildren","node","y","retryNode","list","n","src","children","c","import_effect","import_effect","EFFECT_TYPE_REGEX_3","EFFECT_TYPE_REGEX_2","effectTypeSignatureFromTypeText","typeText","clean","s","match3","match2","tryResolveGenericFromInnerExpression","node","typeChecker","SyntaxKind","loadTsMorph","call","expr","propAccess","baseExpr","baseSig","extractEffectTypeSignature","args","arg","argSig","_typeChecker","nodeType","isEffectType","typeArgs","extractTypeArguments","aType","eType","rType","errorTypeStr","typeToString","resolved","fromText","eTrim","fromCallee","tryExtractFromCalleeReturnType","callee","callSignatures","returnType","returnArgs","returnText","fromReturnText","symbol","decl","returnTypeText","sigs","retType","retArgs","fromAnnotation","type","name","aliasSymbol","aliasName","aliasTypeArgs","extractServiceRequirements","requirements","locationNode","nodeTypeArgs","parent","varDecl","declaredType","extractRequirementsType","services","extractServicesFromContext","service","sourceFile","offset","line","column","location","contextType","contextMatch","tagType","extractTagIdentifier","parts","splitTopLevelUnion","part","match","splitTopLevelUnion","typeText","parts","current","depth","inString","i","ch","last","cleanTypeArg","s","LAYER_TYPE_REGEX","extractLayerTypeSignature","node","typeText","match","LAYER_TYPE_REGEX","cleanTypeArg","ERROR_HANDLER_PATTERNS","CONDITIONAL_PATTERNS","RESOURCE_PATTERNS","COLLECTION_PATTERNS","FIBER_PATTERNS","TRANSFORM_OPS","EFFECTFUL_TRANSFORMS","isTransformCall","callee","MATCH_OP_MAP","EXHAUSTIVE_OPS","isMatchCall","CAUSE_OP_MAP","CAUSE_CONSTRUCTORS","isCauseCall","EXIT_OP_MAP","EXIT_CONSTRUCTORS","isExitCall","SCHEDULE_OP_MAP","isScheduleCall","INTERRUPTION_PATTERNS","DO_NOTATION_PATTERNS","CACHING_PATTERNS","API_PREFIXES","BUILT_IN_TYPE_NAMES","KNOWN_EFFECT_NAMESPACES","isServiceTagCallee","getSemanticDescription","p","getSemanticDescriptionWithAliases","effectAliases","direct","dotIndex","prefix","method","isLikelyDirectEffectInitializer","initializer","effectImportNames","nonProgramEffectImportNames","SyntaxKind","loadTsMorph","isNonProgramName","name","isRunEntrypointCalleeText","exprText","isDirectEffectCalleeText","isPipeCall","alias","isLikelyEffectCall","call","isMethodPipeCall","arg","base","isInSameScope","node","scope","current","k","blockContainsEffectLikeUsage","block","awaitExpr","expr","blockContainsRunEntrypointUsage","prop","init","body","bodyBlock","ret","awaited","conditional","text","isEffectPackageSpecifier","specifier","EFFECT_NAMESPACE_NAMES","KNOWN_INTERNAL_MODULES","parseServiceIdsFromContextType","requiredType","skip","normalized","s","getNumericLiteralFromNode","kind","n","unary","operand","v","EFFECT_RUNTIME_PRIMITIVE_NAMES","isRuntimePrimitiveDependency","name","firstSegment","CANONICAL_EFFECT_SERVICE_NAMES","canonicalizeServiceDisplayName","DEFAULT_OPTIONS","idCounter","resetIdCounter","generateId","nodeTextCache","getNodeText","node","text","collectErrorTypes","nodes","set","visit","list","err","part","splitTopLevelUnion","children","getStaticChildren","collectDependencies","byName","reqs","r","displayName","callee","looksLikeService","KNOWN_EFFECT_NAMESPACES","BUILT_IN_TYPE_NAMES","extractLocation","filePath","includeLocations","sourceFile","pos","line","column","endPos","end","extractJSDocDescription","jsDocs","firstJsDoc","comment","description","c","tagIndex","rawText","descriptionMatch","leadingComments","lastComment","commentText","cleaned","extractJSDocTags","tryGetJsDocText","n","SyntaxKind","loadTsMorph","current","kind","grandparent","parseJSDocTags","params","returns","throws","example","tagPattern","match","tag","rest","paramMatch","value","exampleStart","nextTagMatch","getJSDocFromParentVariable","parent","parentKind","isJsOrJsxPath","path","extractYieldVariableName","yieldNode","extractProgramName","getEnclosingVariableName","start","propertyName","containerName","ancestor","depth","extractEnclosingEffectFnName","callExpr","exprText","args","firstArg","createEmptyStats","DEFAULT_LABEL_MAX","truncateDisplayText","s","max","truncate","extractFunctionName","callee","withoutArgs","parts","receiver","KNOWN_EFFECT_NAMESPACES","BUILT_IN_TYPE_NAMES","computeDisplayName","node","variableName","fnName","wrapper","truncate","op","channelOps","sinkOps","computeSemanticRole","node","desc","callee","unwrapExpression","expr","SyntaxKind","loadTsMorph","normalizeSlashes","value","normalizePath","normalized","isAbsolute","parts","stack","part","dirnamePath","lastSeparator","joinPath","resolvePath","hasPathPrefix","prefix","normalizedValue","normalizedPrefix","effectAliasCache","symbolResolutionCache","getNodeExistsSync","maybeProcess","fsBuiltin","getNamesReExportedFromEffect","barrelSourceFile","out","decl","specifier","isEffectPackageSpecifier","EFFECT_NAMESPACE_NAMES","n","named","alias","resolveBarrelSourceFile","project","currentFilePath","baseDir","dirnamePath","resolved","resolvePath","candidates","joinPath","p","f","resolveModulePath","existsSync","isSpecifierUnderKnownEffectInternalsRoot","knownEffectInternalsRoot","normalizedSpecifier","normalizedResolved","normalizedRoot","hasPathPrefix","getEffectImportNames","sourceFile","names","currentPath","def","ns","barrelFile","reExported","toCheck","text","needsDeepTrace","entry","traceReExportChain","getEffectLikeNamespaceAliases","aliases","importDecl","moduleSpecifier","namespaceImport","aliasName","basename","KNOWN_INTERNAL_MODULES","NON_PROGRAM_EFFECT_MODULE_BASENAMES","getNonProgramEffectImportNames","getAliasesForFile","sf","effectSubmoduleAliasCache","canonicalNamespaceFromSpecifier","getEffectSubmoduleAliasMap","map","nsImport","canonical","originalName","normalizeEffectCallee","callee","dotIdx","rest","name","maxDepth","exportDecl","namedExport","nextBarrel","resolveCalleeModuleOrigin","calleeText","cache","nsText","cached","result","resolveNamespaceImportModuleSpecifier","expr","isEffectLikeCallExpression","call","effectAliases","API_PREFIXES","SyntaxKind","loadTsMorph","propAccess","isEffectCallee","prefix","WORKFLOW_FACTORY_NAMES","isWorkflowFactoryCall","calleeText","name","isWorkflowMakeCall","call","expr","loadTsMorph","prop","args","third","SyntaxKind","isWorkflowPackageSpecifier","specifier","_currentFilePath","isWorkflowNamespaceFromPackage","localName","isActivityNamespaceFromPackage","objectArgHasAnyProperty","propertyNames","arg","props","names","p","isWorkflowMakeOptionsCall","importSpecifierByLocalName","currentFilePath","baseText","isActivityMakeOptionsCall","getWorkflowBodyNodeForRunCall","runCall","sourceFile","innerCall","varDecls","decl","initializer","isInsideEffectGen","node","current","text","isTopLevelVariableDeclaration","isYieldBoundDeclaration","getCallExpressionFromInitializer","awaited","buildDiscoveryInfo","discoveryConfidence","discoveryReason","EFFECT_FAMILY_TYPE_HINTS","hasEffectFamilyTypeHint","hint","DISCOVERY_CONFIDENCE_RANK","isRunCall","exprText","bodyContainsRunMainOrRunPromise","body","isIndirectRunMainWrapper","_sourceFile","kind","init","isRuntimeCurriedForm","innerExprText","findEffectPrograms","_opts","programs","seenCallStarts","workflowProgramBuilders","effectImportNames","getEffectLikeNamespaceAliases","nonProgramEffectImportNames","getNonProgramEffectImportNames","importDecl","def","ns","named","inferAliasBackedDiscovery","aliasName","isSpecifierUnderKnownEffectInternalsRoot","inferDirectInitializerDiscovery","inferFromNestedEffectAliasUsage","propertyAccesses","base","calls","c","callee","local","nested","inferTypeAnnotatedDiscovery","typeText","n","isExportedDecl","fnReturnTypeText","typeArgText","isProgramRootExported","program","inferMethodReturnDiscovery","returnStatements","ret","isLikelyDirectEffectInitializer","filePath","varDeclarations","initCall","genCalls","expression","callStart","isWorkflowInvocation","propertyAccess","objectText","methodName","extractProgramName","isEffectLikeCallExpression","extractEnclosingEffectFnName","pipeName","hasEffectInArgs","callInitializer","looksLikeEffect","typeDiscovery","topLevelStatements","stmt","calleeExpr","lastArg","lastArgText","baseName","DATA_SCHEMA_CLASS_PATTERNS","classDeclarations","classDecl","clause","clauseText","topLevelClasses","parent","className","members","properties","m","memberName","fullName","methods","method","getters","getter","functionDeclarations","fnDecl","returnTypeNode","threshold","confidence","alias","extractServiceDefinitionsFromFile","results","typeChecker","extExpr","extText","typeArgs","inner","interfaceTypeNode","type","sym","propName","classText","hasCustomEquality","hasCustomHash","r","import_effect","import_effect","import_effect","compactCallbackCalleeLabel","call","expr","SyntaxKind","loadTsMorph","canonicalizeCallbackLabel","label","CALLBACK_NOISE_LABELS","shouldSkipCallbackSummaryLabel","availableLabels","candidate","summarizeLoopCallbackSource","loopType","callbackBody","labels","node","filtered","index","joined","suffix","buildCallbackSummaryNodes","fnNode","filePath","includeLocations","body","calls","seen","collectFrom","callee","callbackNode","generateId","extractLocation","computeDisplayName","computeSemanticRole","stmt","desc","isFunctionBoundaryForCallbackSummary","kind","summarizeResumePayloads","sourceFile","opts","warnings","stats","resumeParamName","summaries","visit","payload","payloadText","compactPayload","key","filterHandlerSummaryNoise","nodes","seenEffectLabels","summarizeNamedCallbackHandlers","block","decl","init","handlerFn","buildPureCallbackSummaryNodes","handlerNode","addEffectSummary","description","canonicalLabel","addConditionalSummary","condition","text","isLayerOrEffectInitializerCallee","initCall","initText","srcFile","normalized","normalizeEffectCallee","resolveLayerInitializerFromImport","ident","importSpec","isLayerInit","SyntaxKind","loadTsMorph","sourceFile","project","currentPath","specifier","targetFile","resolveBarrelSourceFile","resolvedPath","resolveModulePath","added","tryDecl","d","init","list","v","exportName","exported","decls","targetName","declList","resolveLayerInitializerFromDefaultImport","importDecl","resolveIdentifierToLayerInitializer","node","name","sym","decl","fromDecls","sf","id","fromDefault","spec","n","fromImport","isPromiseLikeText","text","EFFECT_RUNTIME_PRIMITIVE_PREFIXES","isEffectRuntimePrimitive","prefix","isLikelyServiceStreamProperty","propertyName","normalizeInferredServiceType","typeName","inferServiceTypeFromObjectName","objectName","inferred","BUILT_IN_TYPE_NAMES","KNOWN_EFFECT_NAMESPACES","tryResolveServicePropertyAccess","node","methodName","firstSegment","fallback","type","symbol","classifyUseCallbackKind","fnNode","bodyText","fnTypeText","createAnalysisContext","getAnalyze","bindAnalysisContext","context","analyzer","args","import_effect","channelOpCategory","op","sinkOpCategory","parseEffectAllOptions","optionsNode","SyntaxKind","loadTsMorph","concurrency","batching","discard","prop","name","init","text","n","parseScheduleInfo","scheduleText","baseStrategy","maxRetries","recursMatch","recurUpToMatch","jittered","conditions","analyzeStreamCall","deps","call","callee","sourceFile","filePath","opts","warnings","stats","serviceScope","args","SyntaxKind","loadTsMorph","baseExpr","analyzedBase","effectiveSource","pipeline","sink","backpressureStrategy","constructorType","arg","analyzed","streamNode","generateId","extractLocation","computeDisplayName","computeSemanticRole","source","opName","classifyOperator","op","isEffectful","callbackArg","callbackBody","buildCallbackSummaryNodes","buildPureCallbackSummaryNodes","opCategory","cardinality","windowSize","stride","getNumericLiteralFromNode","thisOp","effectiveConstructorType","srcStream","analyzeChannelCall","channelOpCategory","srcChan","channelNode","analyzeSinkCall","sinkOpCategory","srcSink","sinkNode","import_effect","analyzeRetryCall","deps","call","sourceFile","filePath","opts","warnings","stats","args","source","schedule","scheduleNode","hasFallback","expr","loadTsMorph","exprSource","generateId","scheduleInfo","parseScheduleInfo","retryNode","extractLocation","computeDisplayName","computeSemanticRole","analyzeTimeoutCall","duration","getNodeText","exprText","timeoutNode","analyzeScheduleCall","callee","scheduleOp","SCHEDULE_OP_MAP","scheduleText","import_effect","analyzeConcurrencyPrimitiveCall","call","callee","_sourceFile","filePath","opts","_warnings","_stats","SyntaxKind","loadTsMorph","primitive","operation","strategy","capacity","permitCount","args","first","getNumericLiteralFromNode","lifecycleOptions","arg","text","constructorType","innerPrimNode","generateId","extractLocation","streamNode","computeDisplayName","computeSemanticRole","concurrencyNode","analyzeFiberCall","deps","sourceFile","warnings","stats","isScoped","isDaemon","fiberSource","joinPoint","firstArg","scopeContext","parent","parentText","fiberNode","analyzeInterruptionCall","interruptionType","source","handler","expr","propAccess","interruptionNode","import_effect","analyzeParallelCall","deps","call","callee","sourceFile","filePath","opts","warnings","stats","serviceScope","args","children","SyntaxKind","loadTsMorph","firstArg","elements","elem","analyzed","props","prop","initializer","concurrency","batching","discard","parsed","parseEffectAllOptions","mode","branchLabels","child","computeDisplayName","parallelNode","generateId","extractLocation","computeSemanticRole","analyzeRaceCall","arg","raceLabels","raceNode","import_effect","classifyErrorHandlerName","callee","analyzeErrorHandlerCall","deps","call","sourceFile","filePath","opts","warnings","stats","args","handlerType","source","handler","expr","loadTsMorph","exprSource","generateId","errorTag","errorTags","tagArg","objArg","a","p","handlerNode","extractLocation","computeDisplayName","computeSemanticRole","import_effect","analyzeResourceCall","deps","call","callee","sourceFile","filePath","opts","warnings","stats","args","resourceOperation","acquire","release","useEffect","generateId","expr","loadTsMorph","propAccess","exprSource","resourceNode","extractLocation","computeDisplayName","computeSemanticRole","import_effect","analyzeConditionalCall","deps","call","callee","sourceFile","filePath","opts","warnings","stats","args","conditionalType","condition","onTrue","onFalse","secondArg","SyntaxKind","loadTsMorph","props","prop","propAssign","name","init","expr","exprSource","generateId","truncatedCondition","conditionalNode","extractLocation","computeDisplayName","computeSemanticRole","analyzeLoopCall","loopType","bodyArgIndex","iterSource","body","callbackBody","rawSource","bodyArg","fn","effectfulSummary","buildCallbackSummaryNodes","pureSummary","buildPureCallbackSummaryNodes","summarizeLoopCallbackSource","predicateArg","loopNode","analyzeMatchCall","matchOp","MATCH_OP_MAP","isExhaustive","EXHAUSTIVE_OPS","matchedTags","arg0","arg","obj","matchNode","analyzeCauseCall","causeOp","CAUSE_OP_MAP","isConstructor","CAUSE_CONSTRUCTORS","children","childNodes","child","causeKind","childKinds","c","k","causeNode","analyzeExitCall","exitOp","EXIT_OP_MAP","EXIT_CONSTRUCTORS","exitNode","analyzeTransformCall","transformType","TRANSFORM_OPS","isEffectful","EFFECTFUL_TRANSFORMS","source","fnText","transformNode","analysisContext","createAnalysisContext","analyzeEffectExpression","analyzeStreamCall","bindAnalysisContext","analyzeChannelCall","analyzeSinkCall","analyzeRetryCall","analyzeTimeoutCall","analyzeFiberCall","analyzeInterruptionCall","analyzeParallelCall","analyzeRaceCall","analyzeErrorHandlerCall","analyzeResourceCall","analyzeConditionalCall","analyzeLoopCall","analyzeCauseCall","analyzeTransformCall","SCHEMA_OPS","EFFECT_PIPE_OP_REGEX","pipeArgsIncludeEffectOp","call","arg","asErrorHandler","analyzed","stats","loadTsMorph","text","ERROR_HANDLER_PATTERNS","pattern","handlerType","classifyErrorHandlerName","node","generateId","computeDisplayName","computeSemanticRole","analyzePipeChain","sourceFile","filePath","opts","warnings","serviceScope","SyntaxKind","args","expr","isMethodPipe","baseExpr","transformArgs","baseNode","resolveIdentifierToLayerInitializer","baseSourceFile","basePath","project","inProject","added","initial","transformations","sourceOrderedSpanNames","spanNameDynamic","filteredTransformations","t","argText","match","spanNames","spanName","typeFlow","typeChecker","flow","initialSig","extractEffectTypeSignature","argNode","sig","innerSpanNames","mergedSpanNames","innermost","pipeNode","unwrapExpression","body","unknownNode","extractLocation","returnedExpr","stmt","analyzeEffectCall","operation","objectText","propertyName","serviceId","serviceEffectNode","isLikelyServiceStreamProperty","streamNode","inferredServiceCall","tryResolveServicePropertyAccess","isEffectCallee","getAliasesForFile","effectNode","normalizeEffectCallee","objLit","HANDLER_PROPS","props","handlerEntries","hasKnownHandler","prop","assignment","propName","initializer","tagText","newExpr","ctorText","ctorName","typeText","unknownReason","callee","normalizedCallee","calleeOperation","location","isEffectMethodPipe","nodes","baseCallText","baseText","baseCallOrExprText","analyzeLayerCall","layerNode","analyzeConcurrencyPrimitiveCall","FIBER_PATTERNS","p","INTERRUPTION_PATTERNS","resourceOps","resourceOpPrefixes","isResourceOp","op","baseCall","baseCallee","baseOperation","conditionalOp","CONDITIONAL_PATTERNS","isSchemaOp","collectionOp","COLLECTION_PATTERNS","isTransformCall","isMatchCall","analyzeMatchCall","isCauseCall","isExitCall","analyzeExitCall","isScheduleCall","analyzeScheduleCall","callbackBody","usePattern","isConstructorWithCallback","c","asyncCallback","firstArg","fn","innerNodes","block","retExpr","isEffectLikeCallExpression","resumeParamName","resumeCallCount","visit","returnsCanceller","k","handlerSummaries","summarizeNamedCallbackHandlers","propAccess","callbackArg","callbackFn","callbackNodes","buildCallbackSummaryNodes","wrapperExpr","classifyUseCallbackKind","effectJSDoc","extractJSDocDescription","typeSignature","requiredServices","extractServiceRequirements","serviceCall","tryResolveServiceCall","serviceMethod","methodName","provideKind","contextArgText","constructorKind","fiberRefName","KNOWN_FIBER_REFS","refName","tracedName","strMatch","innerCall","innerCallee","fnArgs","filteredRequiredServices","service","isEffectRuntimePrimitive","getSemanticDescriptionWithAliases","extractJSDocTags","objExpr","objectName","firstSegment","KNOWN_EFFECT_NAMESPACES","normalized","normalizedFirstSegment","type","symbol","typeName","BUILT_IN_TYPE_NAMES","operations","elements","elem","toAnalyze","argSourceFile","isMerged","lifecycle","provides","extractTagNames","item","callNode","first","pae","obj","isProvideCall","requiresSet","depName","baseArg","collectRequires","eff","req","calleeText","layer","r","getStaticChildren","layerSig","extractLayerTypeSignature","parseServiceIdsFromContextType","id","layerOpName","layerName","isMemoMap","analyzeProgram","program","sourceFile","filePath","opts","tsVersion","warnings","stats","createEmptyStats","children","analyzeProgramNode","programJSDoc","getJSDocFromParentVariable","typeChecker","typeSignature","extractEffectTypeSignature","requiredServices","extractServiceRequirements","root","generateId","collectDependencies","collectErrorTypes","extractLocation","extractJSDocTags","serviceDefinitions","extractServiceDefinitionsFromFile","node","programType","genCall","args","genChildren","analyzeGeneratorFunction","outerPipe","findOuterPipeOnGen","applyOuterPipeTransformsToGen","outerLayerUnwrap","findOuterLayerUnwrapOnGen","unwrapNode","computeDisplayName","computeSemanticRole","analyzePipeChain","call","SyntaxKind","loadTsMorph","pipeResult","analyzeRunEntrypointExpression","callbackInArgs","arg","workflowBody","getWorkflowBodyNodeForRunCall","effect","analyzeEffectExpression","exprText","initializer","SK","outerCall","outerExpr","innerCall","innerCallee","genArg","fnArgs","tracedName","firstArg","strMatch","constructorKind","fnMetaNode","enrichedFnNode","classDecl","callee","clause","clauseText","description","classEffectNode","extractJSDocDescription","body","returnStatements","ret","expr","result","SK2","isFunctionBoundary","kind","containsGeneratorYield","found","child","extractLiteralValue","resolveConditionConsts","condition","constValues","resolved","name","value","pattern","replacement","simplifyBooleanExpression","hasTerminatorStatement","stmts","last","collectYieldExpressionsDF","results","collectCallExpressionsBoundaryAware","calls","visit","current","STEP_FUNCTIONS","isStepCall","extractStringLiteral","parseBranchCases","casesObj","cases","objLit","prop","analyzeStepCall","callExpr","ctx","stepId","innerEffect","analyzed","label","expression","c","effectsArg","arrayLit","element","iterSource","fn","effectNode","analyzeYieldNode","yieldNode","yieldExpr","isDelegated","opaqueNode","extractYieldVariableName","effectExpr","unwrappedCall","unwrapExpression","calleeExpr","unwrappedExpr","stepResult","variableName","enrichedStep","isServiceTagCallee","enrichedEffect","analyzeGeneratorBody","block","stmt","nodes","analyzeStatement","analyzeExpressionForYields","varStmt","VariableDeclarationKind","isConst","decl","init","literalValue","calleeText","yieldEntries","declName","lastEntry","ifStmt","condYields","thenStmt","elseStmt","onTrue","analyzeStatementBlock","onFalse","resolvedCondition","decisionLabel","decisionNode","y","switchStmt","clauses","hasFallthrough","hasDefault","currentLabels","currentBodyYields","currentIsDefault","caseClause","clauseStmts","clauseStmt","resolvedExpression","switchNode","forStmt","headerYields","entries","e","incrementor","bodyStmt","bodyYields","hasEarlyExit","checkEarlyExit","loopBody","loopNode","forOfStmt","iterExpr","iterVariable","forInStmt","whileStmt","doStmt","tryStmt","tryBlock","tryYields","catchClause","catchVariable","catchYields","catchBlock","finallyBlock","finallyYields","hasTerminalInTry","tryCatchNode","descendantCalls","entry","termNode","valueYields","k","unwrapped","exprKind","ternary","whenTrue","whenFalse","trueYields","falseYields","resolvedCond","binary","operatorToken","left","right","rightYields","yieldExprs","serviceScope","generatorAdapterParams","fnLike","param","yields","stmtKind","aliases","getAliasesForFile","isEffectLikeCallExpression","analyzeEffectCall","generatorJSDoc","generatorNode","parent","pa","grandparent","outer","pipeCall","transformArgs","wrapChildren","gen","argCall","argExprText","text","argArgs","location","source","scheduleArg","schedule","scheduleNode","retryNode","lastArg","lastArgText","analyzeEffectFile","filePath","options","opts","DEFAULT_OPTIONS","ts","Project","loadTsMorph","project","isJsOrJsxPath","createProject","error","AnalysisError","existingFile","sourceFile","programs","findEffectPrograms","program","analyzeProgram","analyzeEffectSource","code","createProjectFromSource","createResult","programs","program","AnalysisError","p","name","found","available","analyze","filePath","options","resetIdCounter","programsEffect","analyzeEffectFile","code","analyzeEffectSource","import_effect","import_effect","collectLayerNodes","nodes","result","node","layer","info","op","children","getStaticChildren","buildLayerDependencyGraph","ir","layers","edges","serviceToLayers","depLayerId","svc","list","req","DEFAULT_OPTIONS","validateStrict","ir","options","opts","diagnostics","validateNodes","validateFiberLeaks","validateResourceScopes","validateConcurrencyBounds","validateDeadCodePaths","validateUnusedServices","normalizeText","text","trimmed","normalizedDiagnostics","diagnostic","severityRank","severity","canonicalDiagnostics","a","b","aPath","bPath","aLine","bLine","aCol","bCol","sevCmp","dedupedDiagnostics","seen","key","errors","warnings","nodes","hasAncestorErrorHandler","node","currentHasErrorHandler","eff","validateEffectNode","errorType","child","children","getStaticChildren","joinPointsInScope","fiber","inScope","isScope","callee","label","layerGraph","buildLayerDependencyGraph","consumedServices","layer","req","collectConsumedServicesFromNodes","svc","consumed","reqs","r","formatDiagnostics","result","lines","diag","icon","loc","formatDiagnosticsJSON","d","getSummary","import_effect","import_effect","visit","node","fn","childrenOpt","getStaticChildren","child","walkRoot","ir","containsLogging","found","isStaticEffectNode","c","isSilentNoOpHandler","handler","hasNoOpTerminal","swallowedErrorRule","issues","isStaticErrorHandlerNode","LARGE_GEN_DEFAULT_THRESHOLD","createLargeGenBlockRule","threshold","n","isStaticGeneratorNode","count","largeGenBlockRule","FLATMAP_CHAIN_DEFAULT_THRESHOLD","createFlatMapChainRule","isStaticPipeNode","run","runStart","flagged","t","isStaticTransformNode","topLevelProvideLayerCount","isStaticLayerNode","tagMentions","first","flatMapChainRule","PROVIDE_MERGE_DEFAULT_THRESHOLD","createProvideMergeChainRule","provideMergeChainRule","SEQUENTIAL_FAIL_DEFAULT_THRESHOLD","createSequentialFailRule","failCount","firstFailLoc","y","inner","sequentialFailRule","deferredNoResolveRule","makes","hasResolver","isStaticConcurrencyPrimitiveNode","op","deferreds","d","untaggedYieldRule","ir","issues","checkNode","node","_parentId","isStaticGeneratorNode","yield_","isStaticEffectNode","childrenOpt","getStaticChildren","child","missingErrorHandlerRule","hasErrorHandler","currentHasHandler","isStaticErrorHandlerNode","op","collectUsedNamesInSubtree","used","visit","n","callee","c","deadCodeRule","yields","i","varName","usedLater","j","laterYield","name","complexLayerRule","layerCount","layerProvideCount","countLayers","catchVsCatchTagRule","errorTypeTooWideRule","err","unboundedParallelismRule","isStaticParallelNode","redundantPipeRule","isStaticPipeNode","orDieWarningRule","DEFAULT_LINT_RULES","swallowedErrorRule","largeGenBlockRule","flatMapChainRule","provideMergeChainRule","sequentialFailRule","deferredNoResolveRule","lintEffectProgram","rules","allIssues","rule","normalizeText","text","trimmed","normalizedIssues","issue","severityRank","severity","canonicalIssues","a","b","aPath","bPath","aLine","bLine","aCol","bCol","sevCmp","dedupedIssues","seen","key","errors","warnings","infos","formatLintReport","result","programName","lines","icon","D","RULE_DOCS","makeLocation","node","filePath","start","sf","line","column","calleeText","call","isInsideEffectGen","current","txt","isInsideEffectSyncOrTry","isInsideParallelEffect","findImmediateEffectCallContext","cur","tryHasCatchField","SyntaxKind","loadTsMorph","first","p","checkUntaggedThrow","ctx","issues","stmt","expr","name","ctxCall","checkMutableInConcurrent","bin","op","lhs","id","sym","decls","d","vd","list","letDecl","findParallelAncestor","n","binParallel","declParallel","checkRunPromiseThenChain","parent","propName","checkRunSyncOnAsync","isAsyncEffectText","text","asyncIdents","init","callee","args","argText","TEST_FILE_PATTERN","TEST_DIR_PATTERN","isTestFilePath","checkLiveLayerInTest","seen","isIntegrationTest","isRuntimeUse","pk","runtimeRef","ref","checkNondeterministicTestApi","ctor","checkDetachedFiberInTest","checkSleepWithoutTestClockInTest","PROMISE_API_REPLACEMENTS","checkPromiseApiInGen","replacement","checkForEachWithoutConcurrency","CATCH_RECEIVERS","isIdentityHandler","argNode","expectedReFail","kind","arrow","fn","match","param","body","block","findFunctionArg","i","arg","k","checkIdentityCatch","handler","checkEmptyEffectAll","empty","checkLayerDuplicateMerge","idx","SCHEDULE_BOUNDS","findEnclosingPipeOrChain","checkScheduleUnbounded","candidates","pa","label","isStreamScheduleConsumer","pipeOrChain","containerText","b","SECRET_TOKENS","stringLiteralValue","looksLikeSecret","value","lower","tok","checkConfigSecretWithoutRedacted","lit","matched","EFFECT_CONSTRUCTOR_NAMES","checkReturnEffectFromSync","obj","initK","bodyExpr","stmts","only","innerName","checkYieldPromise","ye","operand","calleeExpr","isPromiseStatic","isGlobalFetch","BARREL_PACKAGES","isTestOrFixtureFile","checkBarrelImportFromEffect","decl","spec","named","ni","moduleName","localName","checkArrayPushSpread","a","isUnsafeApiCallee","checkUnsafeApiUsage","checkTryPromiseWithoutCatch","lintSourceFile","fp","sourceText","lineStarts","disablesByLine","PRAGMA_RE","m","pos","targetLine","rest","rules","set","r","RULE_ALIASES","isSuppressed","rule","filteredIssues","severityRank","severity","canonicalIssues","aPath","bPath","aLine","bLine","aCol","bCol","sevCmp","dedupedIssues","issue","key","docs","RULE_DOCS","lintSourceCode","code","Project","fs","import_node_path","import_node_crypto","RULE_DOC_BASE","normalizeDisplayText","text","withDocUrl","domain","code","SOURCE_RULE_DOCS_BASE","SOURCE_RULE_DOCS","x","STRICT_RULE_DOCS_BY_RULE","STRICT_RULE_DOCS","rule","EFFECT_LINT_RULE_DOCS","DEFAULT_LINT_RULES","severityRank","severity","normalizeRuleDoc","doc","cachedAllDocs","searchCache","explainCache","listAllRuleDocs","canonical","a","b","sevCmp","seen","deduped","key","findRuleDoc","normalizedCode","docs","found","d","getRuleCodesForProfile","profile","select","migrationTags","hay","t","searchRuleDocs","query","q","cached","all","scored","title","desc","example","score","renderRuleDocsText","lines","currentDomain","renderRuleDocsJson","pretty","buildRuleIndex","renderRuleIndexJson","explainRule","import_node_child_process","import_node_module","import_node_path","TsgoDiagnosticsError","message","cause","resolveTsgoBinFrom","from","require","manifestPath","manifest","bin","entry","resolveTsgoBin","roots","nodeModuleLocation","root","found","toSeverity","severity","readTsgoProjectFiles","projectPath","Project","loadTsMorph","f","resolveTsgoProjectPath","project","cwd","parseTsgoOutput","stdout","start","parsed","diagnostics","summary","d","toSeverity","runTsgoDiagnostics","options","bin","resolveTsgoBin","TsgoDiagnosticsError","projectResolutionCwd","projectPath","resolveTsgoProjectPath","cwd","lspconfig","argv","stdout","error","processError","out","result","parseTsgoOutput","stderr","detail","target","SEVERITY_ORDER","exitCodeFor","findings","failOn","threshold","f","SCORECARD_WEIGHTS","TS_EXTENSIONS","severityRank","severity","canonicalSort","a","b","sevCmp","fingerprintOf","finding","key","stableFingerprint","parseSuppressions","source","lines","suppressions","re","line","match","rule","reason","applySuppressions","byTarget","suppression","consumed","updated","stale","dedupe","sorted","out","seen","toFinding","filePath","issue","column","base","walk","path","depth","stat","entries","files","entry","full","runSourceLintScan","pathArg","options","basePath","candidates","staleSuppressions","suppressionsMissingReason","s","rawFindings","lintSourceCode","applied","x","tsgo","scanned","result","runTsgoDiagnostics","inProject","readTsgoProjectFiles","diagnostic","unchecked","c","compareAgainstBaseline","current","baseline","currentByFp","baselineByFp","newFindings","fp","resolvedFindings","unchangedFindings","toSarif","ruleId","doc","findRuleDoc","level","buildLintScorecard","rows","existing","severityPenalty","penalty","row","import_effect","childrenOf","node","getStaticChildren","visitIR","roots","visitor","index","visit","nodes","parent","ancestors","runtimeSpanName","node","runtimeSpanNames","name","spanPathKey","path","indexIR","ir","nodes","byId","parentById","spanPathById","mutableIdsBySpanPath","visitIR","parent","ancestors","ownNames","ancestorPath","ancestor","i","key","ids","findingForNode","node","runtimeSpanName","rate","resolved","total","assessIRFidelity","ir","index","indexIR","findings","sourceUnresolvedIds","runtimeInexactIds","runtimeNodeIds","finding","spanPath","ids","printablePath","nodeId","sourceResolved","runtimeResolved","penalizedIds","score","computeDiagramFidelity","ir","assessment","assessIRFidelity","issues","issue","formatDiagramFidelity","report","lines","location","findStaticNodesForSpanPath","path","indexIR","spanPathKey","import_effect","analyzeErrorChannels","irs","issues","errorTypeCounts","programsWithGenericError","programsWithNoErrorHandlers","programsWithUnhandledErrors","ir","programIssues","analyzeProgramErrorChannel","et","normalized","e","countErrorHandlers","unhandled","findUnhandledErrors","uh","uniqueErrorTypes","topErrorTypes","b","type","count","errorType","visitNodes","node","isStaticErrorHandlerNode","checkErrorHandlerWidening","caughtTags","hasCatchAll","tag","isStaticEffectNode","errType","tagMatch","visit","n","childrenOpt","getStaticChildren","child","children","root","fn","renderErrorChannelReport","analysis","lines","s","issue","icon","renderErrorChannelJson","pretty","import_effect","buildServiceRegistry","irs","serviceDefinitions","defined","required","provided","filePath","defs","def","files","ir","req","dep","k","v","analyzeServiceHealth","registry","issues","unsatisfied","findUnsatisfiedServices","service","dead","findDeadServices","layerIssues","findLayerInefficiencies","satisfiedCount","provideCount","countLayerProvides","node","count","visit","n","isStaticLayerNode","childrenOpt","getStaticChildren","child","renderServiceHealthReport","analysis","lines","s","issue","icon","typeLabel","renderServiceHealthJson","pretty","import_effect","analyzePerformance","irs","issues","sequentialCouldParallel","unboundedConcurrency","largeGenBlocks","unboundedRetries","forEachSequential","ir","filePath","programName","visitNodes","node","isStaticParallelNode","child","isStaticGeneratorNode","yieldCount","isStaticRetryNode","schedule","isStaticEffectNode","root","fn","visit","childrenOpt","getStaticChildren","children","renderPerformanceReport","analysis","lines","s","issue","impactIcon","renderPerformanceJson","pretty"]}