{"version":3,"sources":["../src/diagram-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/complexity.ts","../src/ir.ts","../src/fidelity-findings.ts","../src/diagram-fidelity.ts","../src/diagram-quality.ts","../src/path-generator.ts","../src/output/mermaid.ts","../src/data-flow.ts","../src/error-flow.ts","../src/runtime-trace.ts","../src/diff/diff-engine.ts","../src/diff/render-markdown.ts","../src/diff/render-json.ts","../src/diff/render-mermaid.ts","../src/diff/resolve-source.ts","../src/output/mermaid-railway.ts","../src/service-flow.ts","../src/output/mermaid-services.ts","../src/output/mermaid-errors.ts","../src/output/mermaid-decisions.ts","../src/output/mermaid-causes.ts","../src/output/mermaid-concurrency.ts","../src/output/mermaid-timeline.ts","../src/layer-graph.ts","../src/output/mermaid-layers.ts","../src/output/mermaid-retry.ts","../src/output/mermaid-testability.ts","../src/output/mermaid-dataflow.ts","../src/output/auto-diagram.ts","../src/output/json.ts","../src/output/html.ts","../src/output/docs.ts","../src/output/explain.ts","../src/output/summary.ts","../src/output/test-matrix.ts"],"sourcesContent":["/** Diagram and documentation interface for Effect v4. */\n\nexport { analyze } from './analyze';\nexport * from './complexity';\nexport * from './diagram-fidelity';\nexport * from './diagram-quality';\nexport * from './runtime-trace';\nexport * from './diff';\nexport * from './output/mermaid';\nexport * from './output/mermaid-railway';\nexport * from './output/mermaid-services';\nexport * from './output/mermaid-errors';\nexport * from './output/mermaid-decisions';\nexport * from './output/mermaid-causes';\nexport * from './output/mermaid-concurrency';\nexport * from './output/mermaid-timeline';\nexport * from './output/mermaid-layers';\nexport * from './output/mermaid-retry';\nexport * from './output/mermaid-testability';\nexport * from './output/mermaid-dataflow';\nexport * from './output/auto-diagram';\nexport * from './output/json';\nexport * from './output/html';\nexport * from './output/docs';\nexport * from './output/explain';\nexport * from './output/summary';\nexport * from './output/test-matrix';\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    | '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  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 } 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|catchCause|catchTag|catchTags|catchSome|catchSomeCause|catchSomeDefect|orElse|orElseSucceed|orElseFail|orElseFailWith|orDie|orDieWith|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\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(analyzed);\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    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    const callee = call.getExpression().getText();\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\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    let handlerType: StaticErrorHandlerNode['handlerType'];\n    if (callee.includes('catchCause')) {\n      handlerType = 'catchCause';\n    } else if (callee.includes('catchSomeCause')) {\n      handlerType = 'catchSomeCause';\n    } else if (callee.includes('catchSomeDefect')) {\n      handlerType = 'catchSomeDefect';\n    } else if (callee.includes('catchDefect')) {\n      handlerType = 'catchDefect';\n    } else if (callee.includes('catchTags')) {\n      handlerType = 'catchTags';\n    } else if (callee.includes('catchIf')) {\n      handlerType = 'catchIf';\n    } else if (callee.includes('catchSome')) {\n      handlerType = 'catchSome';\n    } else if (callee.includes('catchTag')) {\n      handlerType = 'catchTag';\n    } else if (callee.includes('catch')) {\n      handlerType = 'catch';\n    } else if (callee.includes('orElseFail')) {\n      handlerType = 'orElseFail';\n    } else if (callee.includes('orElseSucceed')) {\n      handlerType = 'orElseSucceed';\n    } else if (callee.includes('orElse')) {\n      handlerType = 'orElse';\n    } else if (callee.includes('orDieWith')) {\n      handlerType = 'orDieWith';\n    } else if (callee.includes('orDie')) {\n      handlerType = 'orDie';\n    } else if (callee.includes('flip')) {\n      handlerType = 'flip';\n    } else if (callee.includes('mapErrorCause')) {\n      handlerType = 'mapErrorCause';\n    } else if (callee.includes('mapBoth')) {\n      handlerType = 'mapBoth';\n    } else if (callee.includes('mapError')) {\n      handlerType = 'mapError';\n    } else if (callee.includes('unsandbox')) {\n      handlerType = 'unsandbox';\n    } else if (callee.includes('sandbox')) {\n      handlerType = 'sandbox';\n    } else if (callee.includes('parallelErrors')) {\n      handlerType = 'parallelErrors';\n    } else if (callee.includes('filterOrDieMessage')) {\n      handlerType = 'filterOrDieMessage';\n    } else if (callee.includes('filterOrDie')) {\n      handlerType = 'filterOrDie';\n    } else if (callee.includes('filterOrElse')) {\n      handlerType = 'filterOrElse';\n    } else if (callee.includes('filterOrFail')) {\n      handlerType = 'filterOrFail';\n    } else if (callee.includes('matchCauseEffect')) {\n      handlerType = 'matchCauseEffect';\n    } else if (callee.includes('matchCause')) {\n      handlerType = 'matchCause';\n    } else if (callee.includes('matchEffect')) {\n      handlerType = 'matchEffect';\n    } else if (callee.includes('match')) {\n      handlerType = 'match';\n    } else if (callee.includes('firstSuccessOf')) {\n      handlerType = 'firstSuccessOf';\n    } else if (callee.includes('ignoreLogged')) {\n      handlerType = 'ignoreLogged';\n    } else if (callee.includes('ignore')) {\n      handlerType = 'ignore';\n    } else if (callee.includes('eventually')) {\n      handlerType = 'eventually';\n    } else {\n      handlerType = 'catch';\n    }\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 * Complexity Metrics Calculator\n *\n * Calculates complexity metrics for Effect programs including:\n * - Cyclomatic complexity (McCabe)\n * - Cognitive complexity (Sonar-style)\n * - Path count (bounded or unbounded)\n * - Depth and breadth metrics\n */\n\nimport { Option } from 'effect';\nimport { getStaticChildren } from './types';\nimport type {\n  StaticEffectIR,\n  StaticFlowNode,\n  ComplexityMetrics,\n  ComplexityThresholds,\n} from './types';\n\n// =============================================================================\n// Default Thresholds\n// =============================================================================\n\nexport const DEFAULT_THRESHOLDS: ComplexityThresholds = {\n  cyclomaticWarning: 10,\n  cyclomaticError: 20,\n  pathCountWarning: 50,\n  maxDepthWarning: 5,\n};\n\n// =============================================================================\n// Main Calculator\n// =============================================================================\n\nexport function calculateComplexity(ir: StaticEffectIR): ComplexityMetrics {\n  const nodes = ir.root.children;\n\n  const cyclomatic = calculateCyclomaticComplexity(nodes);\n  const cognitive = calculateCognitiveComplexity(nodes);\n  const pathCount = calculatePathCount(nodes);\n  const maxDepth = calculateMaxDepth(nodes);\n  const maxParallelBreadth = calculateMaxParallelBreadth(nodes);\n  const decisionPoints = countDecisionPoints(nodes);\n\n  return {\n    cyclomaticComplexity: cyclomatic,\n    cognitiveComplexity: cognitive,\n    pathCount,\n    maxDepth,\n    maxParallelBreadth,\n    decisionPoints,\n  };\n}\n\n// =============================================================================\n// Cyclomatic Complexity\n// =============================================================================\n\nfunction calculateCyclomaticComplexity(\n  nodes: readonly StaticFlowNode[],\n): number {\n  let complexity = 1;\n  for (const node of nodes) {\n    complexity += countDecisionPointsInNode(node);\n  }\n  return complexity;\n}\n\nfunction countDecisionPointsInNode(node: StaticFlowNode): number {\n  const children = getStaticChildren(node);\n  const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n  let count = 0;\n\n  switch (node.type) {\n    case 'conditional':\n      count += 1;\n      for (const child of childList) {\n        count += countDecisionPointsInNode(child);\n      }\n      break;\n\n    case 'race':\n      count += Math.max(0, node.children.length - 1);\n      for (const child of node.children) {\n        count += countDecisionPointsInNode(child);\n      }\n      break;\n\n    case 'loop':\n      count += 1;\n      count += countDecisionPointsInNode(node.body);\n      break;\n\n    case 'generator':\n    case 'pipe':\n    case 'parallel':\n    case 'error-handler':\n    case 'retry':\n    case 'timeout':\n    case 'resource':\n    case 'layer':\n      for (const child of childList) {\n        count += countDecisionPointsInNode(child);\n      }\n      break;\n\n    case 'decision':\n      count += 1;\n      for (const child of childList) {\n        count += countDecisionPointsInNode(child);\n      }\n      break;\n\n    case 'switch':\n      count += Math.max(0, node.cases.length - 1);\n      for (const child of childList) {\n        count += countDecisionPointsInNode(child);\n      }\n      break;\n\n    case 'try-catch':\n      count += 1;\n      for (const child of childList) {\n        count += countDecisionPointsInNode(child);\n      }\n      break;\n\n    case 'terminal':\n    case 'opaque':\n      for (const child of childList) {\n        count += countDecisionPointsInNode(child);\n      }\n      break;\n\n    case 'match':\n      if (node.matchedTags && node.matchedTags.length > 1) {\n        count += node.matchedTags.length - 1;\n      }\n      break;\n\n    case 'interruption':\n      if (node.handler) {\n        count += 1;\n        count += countDecisionPointsInNode(node.handler);\n      }\n      if (node.source) {\n        count += countDecisionPointsInNode(node.source);\n      }\n      break;\n\n    case 'cause':\n      if (node.children) {\n        for (const child of node.children) {\n          count += countDecisionPointsInNode(child);\n        }\n      }\n      break;\n\n    case 'transform':\n      if (node.source) {\n        count += countDecisionPointsInNode(node.source);\n      }\n      break;\n\n    case 'channel':\n    case 'sink':\n      if (node.source) {\n        count += countDecisionPointsInNode(node.source);\n      }\n      break;\n\n    case 'exit':\n    case 'schedule':\n    case 'effect':\n    case 'unknown':\n      break;\n  }\n\n  return count;\n}\n\n// =============================================================================\n// Cognitive Complexity\n// =============================================================================\n\nfunction calculateCognitiveComplexity(\n  nodes: readonly StaticFlowNode[],\n): number {\n  return calculateCognitiveForNodes(nodes, 0);\n}\n\nfunction calculateCognitiveForNodes(\n  nodes: readonly StaticFlowNode[],\n  nestingDepth: number,\n): number {\n  let complexity = 0;\n  for (const node of nodes) {\n    complexity += calculateCognitiveForNode(node, nestingDepth);\n  }\n  return complexity;\n}\n\nfunction calculateCognitiveForNode(\n  node: StaticFlowNode,\n  nestingDepth: number,\n): number {\n  const children = getStaticChildren(node);\n  const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n  let complexity = 0;\n\n  switch (node.type) {\n    case 'conditional':\n      complexity += 1 + nestingDepth;\n      complexity += calculateCognitiveForNode(node.onTrue, nestingDepth + 1);\n      if (node.onFalse) {\n        complexity += calculateCognitiveForNode(node.onFalse, nestingDepth + 1);\n      }\n      break;\n\n    case 'loop':\n      complexity += 1 + nestingDepth;\n      complexity += calculateCognitiveForNode(node.body, nestingDepth + 1);\n      break;\n\n    case 'race':\n      complexity += node.children.length;\n      for (const child of node.children) {\n        complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n      }\n      break;\n\n    case 'parallel':\n      complexity += Math.max(0, node.children.length - 1);\n      for (const child of node.children) {\n        complexity += calculateCognitiveForNode(child, nestingDepth);\n      }\n      break;\n\n    case 'generator':\n    case 'pipe':\n    case 'error-handler':\n    case 'retry':\n    case 'timeout':\n    case 'resource':\n    case 'layer':\n      for (const child of childList) {\n        complexity += calculateCognitiveForNode(child, nestingDepth);\n      }\n      break;\n\n    case 'decision':\n      complexity += 1 + nestingDepth;\n      for (const child of node.onTrue) {\n        complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n      }\n      if (node.onFalse) {\n        for (const child of node.onFalse) {\n          complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n        }\n      }\n      break;\n\n    case 'switch':\n      complexity += 1 + nestingDepth;\n      for (const caseItem of node.cases) {\n        for (const child of caseItem.body) {\n          complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n        }\n      }\n      break;\n\n    case 'try-catch':\n      complexity += 1 + nestingDepth;\n      for (const child of childList) {\n        complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n      }\n      break;\n\n    case 'terminal':\n      if (node.value) {\n        for (const child of node.value) {\n          complexity += calculateCognitiveForNode(child, nestingDepth);\n        }\n      }\n      break;\n\n    case 'opaque':\n      break;\n\n    case 'match':\n      if (node.matchedTags && node.matchedTags.length > 0) {\n        complexity += 1 + nestingDepth;\n      }\n      break;\n\n    case 'interruption':\n      if (node.handler) {\n        complexity += 1 + nestingDepth;\n        complexity += calculateCognitiveForNode(node.handler, nestingDepth + 1);\n      }\n      if (node.source) {\n        complexity += calculateCognitiveForNode(node.source, nestingDepth);\n      }\n      break;\n\n    case 'cause':\n      if (node.children) {\n        for (const child of node.children) {\n          complexity += calculateCognitiveForNode(child, nestingDepth);\n        }\n      }\n      break;\n\n    case 'transform':\n      if (node.source) {\n        complexity += calculateCognitiveForNode(node.source, nestingDepth);\n      }\n      break;\n\n    case 'channel':\n    case 'sink':\n      if (node.source) {\n        complexity += calculateCognitiveForNode(node.source, nestingDepth);\n      }\n      break;\n\n    case 'exit':\n    case 'schedule':\n    case 'effect':\n    case 'unknown':\n      break;\n  }\n\n  return complexity;\n}\n\n// =============================================================================\n// Path Count\n// =============================================================================\n\nfunction calculatePathCount(\n  nodes: readonly StaticFlowNode[],\n): number | 'unbounded' {\n  let pathCount = 1;\n  let hasUnbounded = false;\n\n  for (const node of nodes) {\n    const result = pathCountForNode(node);\n    if (result === 'unbounded') {\n      hasUnbounded = true;\n    } else {\n      pathCount *= result;\n    }\n  }\n\n  return hasUnbounded ? 'unbounded' : pathCount;\n}\n\nfunction pathCountForNode(node: StaticFlowNode): number | 'unbounded' {\n  const children = getStaticChildren(node);\n  const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n  switch (node.type) {\n    case 'conditional': {\n      const truePaths = pathCountForNodes([node.onTrue]);\n      const falsePaths = node.onFalse\n        ? pathCountForNodes([node.onFalse])\n        : 1;\n      if (truePaths === 'unbounded' || falsePaths === 'unbounded') {\n        return 'unbounded';\n      }\n      return truePaths + falsePaths;\n    }\n\n    case 'race': {\n      let total = 0;\n      for (const child of node.children) {\n        const childPaths = pathCountForNode(child);\n        if (childPaths === 'unbounded') return 'unbounded';\n        total += childPaths;\n      }\n      return Math.max(1, total);\n    }\n\n    case 'parallel': {\n      let product = 1;\n      for (const child of node.children) {\n        const childPaths = pathCountForNode(child);\n        if (childPaths === 'unbounded') return 'unbounded';\n        product *= childPaths;\n      }\n      return product;\n    }\n\n    case 'loop':\n      return 'unbounded';\n\n    case 'generator':\n    case 'pipe':\n    case 'error-handler':\n    case 'retry':\n    case 'timeout':\n    case 'resource':\n    case 'layer':\n      return pathCountForNodes(childList);\n\n    case 'effect':\n    case 'unknown':\n    case 'opaque':\n      return 1;\n\n    case 'decision': {\n      const truePaths = pathCountForNodes([...node.onTrue]);\n      const falsePaths = node.onFalse\n        ? pathCountForNodes([...node.onFalse])\n        : 1;\n      if (truePaths === 'unbounded' || falsePaths === 'unbounded') {\n        return 'unbounded';\n      }\n      return truePaths + falsePaths;\n    }\n\n    case 'switch': {\n      let total = 0;\n      for (const c of node.cases) {\n        const casePaths = pathCountForNodes([...c.body]);\n        if (casePaths === 'unbounded') return 'unbounded';\n        total += casePaths;\n      }\n      return Math.max(1, total);\n    }\n\n    case 'try-catch':\n    case 'terminal':\n    case 'stream':\n    case 'concurrency-primitive':\n    case 'fiber':\n    case 'interruption':\n    case 'transform':\n    case 'match':\n    case 'cause':\n    case 'exit':\n    case 'schedule':\n    case 'channel':\n    case 'sink':\n      return pathCountForNodes(childList);\n  }\n}\n\nfunction pathCountForNodes(\n  nodes: readonly StaticFlowNode[],\n): number | 'unbounded' {\n  let product = 1;\n  for (const node of nodes) {\n    const paths = pathCountForNode(node);\n    if (paths === 'unbounded') return 'unbounded';\n    product *= paths;\n  }\n  return product;\n}\n\n// =============================================================================\n// Depth\n// =============================================================================\n\nfunction calculateMaxDepth(nodes: readonly StaticFlowNode[]): number {\n  let maxDepth = 0;\n  for (const node of nodes) {\n    maxDepth = Math.max(maxDepth, depthOfNode(node, 0));\n  }\n  return maxDepth;\n}\n\nfunction depthOfNode(node: StaticFlowNode, currentDepth: number): number {\n  const children = getStaticChildren(node);\n  const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n  let maxChildDepth = currentDepth;\n\n  switch (node.type) {\n    case 'conditional':\n      maxChildDepth = Math.max(\n        maxChildDepth,\n        depthOfNode(node.onTrue, currentDepth + 1),\n      );\n      if (node.onFalse) {\n        maxChildDepth = Math.max(\n          maxChildDepth,\n          depthOfNode(node.onFalse, currentDepth + 1),\n        );\n      }\n      break;\n\n    case 'loop':\n      maxChildDepth = Math.max(\n        maxChildDepth,\n        depthOfNode(node.body, currentDepth + 1),\n      );\n      break;\n\n    case 'parallel':\n    case 'race':\n      for (const child of node.children) {\n        maxChildDepth = Math.max(\n          maxChildDepth,\n          depthOfNode(child, currentDepth + 1),\n        );\n      }\n      break;\n\n    case 'generator':\n    case 'pipe':\n    case 'error-handler':\n    case 'retry':\n    case 'timeout':\n    case 'resource':\n    case 'layer':\n      for (const child of childList) {\n        maxChildDepth = Math.max(\n          maxChildDepth,\n          depthOfNode(child, currentDepth),\n        );\n      }\n      break;\n\n    case 'decision':\n      for (const child of node.onTrue) {\n        maxChildDepth = Math.max(\n          maxChildDepth,\n          depthOfNode(child, currentDepth + 1),\n        );\n      }\n      if (node.onFalse) {\n        for (const child of node.onFalse) {\n          maxChildDepth = Math.max(\n            maxChildDepth,\n            depthOfNode(child, currentDepth + 1),\n          );\n        }\n      }\n      break;\n\n    case 'switch':\n      for (const caseItem of node.cases) {\n        for (const child of caseItem.body) {\n          maxChildDepth = Math.max(\n            maxChildDepth,\n            depthOfNode(child, currentDepth + 1),\n          );\n        }\n      }\n      break;\n\n    case 'try-catch':\n      for (const child of childList) {\n        maxChildDepth = Math.max(\n          maxChildDepth,\n          depthOfNode(child, currentDepth + 1),\n        );\n      }\n      break;\n\n    case 'terminal':\n      if (node.value) {\n        for (const child of node.value) {\n          maxChildDepth = Math.max(\n            maxChildDepth,\n            depthOfNode(child, currentDepth),\n          );\n        }\n      }\n      break;\n\n    case 'opaque':\n      break;\n\n    case 'match':\n      break;\n\n    case 'interruption':\n      if (node.source) {\n        maxChildDepth = Math.max(maxChildDepth, depthOfNode(node.source, currentDepth + 1));\n      }\n      if (node.handler) {\n        maxChildDepth = Math.max(maxChildDepth, depthOfNode(node.handler, currentDepth + 1));\n      }\n      break;\n\n    case 'cause':\n      if (node.children) {\n        for (const child of node.children) {\n          maxChildDepth = Math.max(maxChildDepth, depthOfNode(child, currentDepth));\n        }\n      }\n      break;\n\n    case 'transform':\n      if (node.source) {\n        maxChildDepth = Math.max(maxChildDepth, depthOfNode(node.source, currentDepth));\n      }\n      break;\n\n    case 'channel':\n    case 'sink':\n      if (node.source) {\n        maxChildDepth = Math.max(maxChildDepth, depthOfNode(node.source, currentDepth));\n      }\n      break;\n\n    case 'exit':\n    case 'schedule':\n    case 'effect':\n    case 'unknown':\n      break;\n  }\n\n  return maxChildDepth;\n}\n\n// =============================================================================\n// Parallel Breadth\n// =============================================================================\n\nfunction calculateMaxParallelBreadth(\n  nodes: readonly StaticFlowNode[],\n): number {\n  let maxBreadth = 0;\n  for (const node of nodes) {\n    maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node));\n  }\n  return maxBreadth;\n}\n\nfunction parallelBreadthOfNode(node: StaticFlowNode): number {\n  const children = getStaticChildren(node);\n  const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n  let maxBreadth = 0;\n\n  switch (node.type) {\n    case 'parallel':\n    case 'race':\n      maxBreadth = node.children.length;\n      for (const child of node.children) {\n        maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n      }\n      break;\n\n    case 'conditional':\n      maxBreadth = Math.max(\n        parallelBreadthOfNode(node.onTrue),\n        node.onFalse ? parallelBreadthOfNode(node.onFalse) : 0,\n      );\n      break;\n\n    case 'loop':\n      maxBreadth = parallelBreadthOfNode(node.body);\n      break;\n\n    case 'generator':\n    case 'pipe':\n    case 'error-handler':\n    case 'retry':\n    case 'timeout':\n    case 'resource':\n    case 'layer':\n      for (const child of childList) {\n        maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n      }\n      break;\n\n    case 'decision':\n      for (const child of node.onTrue) {\n        maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n      }\n      if (node.onFalse) {\n        for (const child of node.onFalse) {\n          maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n        }\n      }\n      break;\n\n    case 'switch':\n      for (const caseItem of node.cases) {\n        for (const child of caseItem.body) {\n          maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n        }\n      }\n      break;\n\n    case 'try-catch':\n      for (const child of childList) {\n        maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n      }\n      break;\n\n    case 'terminal':\n      if (node.value) {\n        for (const child of node.value) {\n          maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n        }\n      }\n      break;\n\n    case 'opaque':\n      break;\n\n    case 'interruption':\n      if (node.source) {\n        maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node.source));\n      }\n      if (node.handler) {\n        maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node.handler));\n      }\n      break;\n\n    case 'cause':\n      if (node.children) {\n        for (const child of node.children) {\n          maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n        }\n      }\n      break;\n\n    case 'transform':\n      if (node.source) {\n        maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node.source));\n      }\n      break;\n\n    case 'channel':\n    case 'sink':\n      if (node.source) {\n        maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node.source));\n      }\n      break;\n\n    case 'match':\n    case 'exit':\n    case 'schedule':\n    case 'effect':\n    case 'unknown':\n      break;\n  }\n\n  return maxBreadth;\n}\n\n// =============================================================================\n// Decision Points\n// =============================================================================\n\nfunction countDecisionPoints(nodes: readonly StaticFlowNode[]): number {\n  let count = 0;\n  for (const node of nodes) {\n    count += countDecisionPointsInNode(node);\n  }\n  return count;\n}\n\n// =============================================================================\n// Assessment\n// =============================================================================\n\nexport interface ComplexityAssessment {\n  level: 'low' | 'medium' | 'high' | 'very-high';\n  warnings: ComplexityWarning[];\n  recommendations: string[];\n}\n\nexport interface ComplexityWarning {\n  type: 'cyclomatic' | 'cognitive' | 'paths' | 'depth' | 'breadth';\n  message: string;\n  severity: 'warning' | 'error';\n}\n\nexport function assessComplexity(\n  metrics: ComplexityMetrics,\n  thresholds: ComplexityThresholds = DEFAULT_THRESHOLDS,\n): ComplexityAssessment {\n  const warnings: ComplexityWarning[] = [];\n  const recommendations: string[] = [];\n\n  if (metrics.cyclomaticComplexity >= thresholds.cyclomaticError) {\n    warnings.push({\n      type: 'cyclomatic',\n      message: `Cyclomatic complexity (${metrics.cyclomaticComplexity}) exceeds error threshold (${thresholds.cyclomaticError})`,\n      severity: 'error',\n    });\n    recommendations.push(\n      'Consider breaking this program into smaller effects',\n    );\n  } else if (metrics.cyclomaticComplexity >= thresholds.cyclomaticWarning) {\n    warnings.push({\n      type: 'cyclomatic',\n      message: `Cyclomatic complexity (${metrics.cyclomaticComplexity}) exceeds warning threshold (${thresholds.cyclomaticWarning})`,\n      severity: 'warning',\n    });\n    recommendations.push(\n      'Consider simplifying conditional logic or extracting sub-effects',\n    );\n  }\n\n  if (metrics.pathCount === 'unbounded') {\n    warnings.push({\n      type: 'paths',\n      message: 'Program has unbounded paths due to loops',\n      severity: 'warning',\n    });\n    recommendations.push(\n      'Ensure loop termination conditions are well-tested',\n    );\n  } else if (metrics.pathCount >= thresholds.pathCountWarning) {\n    warnings.push({\n      type: 'paths',\n      message: `Path count (${metrics.pathCount}) exceeds threshold (${thresholds.pathCountWarning})`,\n      severity: 'warning',\n    });\n    recommendations.push(\n      'High path count makes exhaustive testing difficult - consider simplifying',\n    );\n  }\n\n  if (metrics.maxDepth >= thresholds.maxDepthWarning) {\n    warnings.push({\n      type: 'depth',\n      message: `Nesting depth (${metrics.maxDepth}) exceeds threshold (${thresholds.maxDepthWarning})`,\n      severity: 'warning',\n    });\n    recommendations.push(\n      'Deep nesting reduces readability - consider flattening or extracting',\n    );\n  }\n\n  let level: ComplexityAssessment['level'] = 'low';\n  const hasError = warnings.some((w) => w.severity === 'error');\n  const hasWarning = warnings.some((w) => w.severity === 'warning');\n\n  if (hasError) {\n    level = 'very-high';\n  } else if (hasWarning) {\n    level = warnings.length >= 2 ? 'high' : 'medium';\n  }\n\n  return {\n    level,\n    warnings,\n    recommendations,\n  };\n}\n\n// =============================================================================\n// Summary\n// =============================================================================\n\nexport function formatComplexitySummary(\n  metrics: ComplexityMetrics,\n  assessment: ComplexityAssessment,\n): string {\n  const lines: string[] = [];\n\n  lines.push('## Effect Program Complexity Report');\n  lines.push('');\n  lines.push(`**Overall Complexity:** ${assessment.level.toUpperCase()}`);\n  lines.push('');\n  lines.push('### Metrics');\n  lines.push('');\n  lines.push('| Metric | Value |');\n  lines.push('|--------|-------|');\n  lines.push(`| Cyclomatic Complexity | ${metrics.cyclomaticComplexity} |`);\n  lines.push(`| Cognitive Complexity | ${metrics.cognitiveComplexity} |`);\n  lines.push(`| Unique Paths | ${metrics.pathCount} |`);\n  lines.push(`| Max Nesting Depth | ${metrics.maxDepth} |`);\n  lines.push(`| Max Parallel Breadth | ${metrics.maxParallelBreadth} |`);\n  lines.push(`| Decision Points | ${metrics.decisionPoints} |`);\n  lines.push('');\n\n  if (assessment.warnings.length > 0) {\n    lines.push('### Warnings');\n    lines.push('');\n    for (const warning of assessment.warnings) {\n      const icon = warning.severity === 'error' ? 'ERROR' : 'WARNING';\n      lines.push(`- **${icon}:** ${warning.message}`);\n    }\n    lines.push('');\n  }\n\n  if (assessment.recommendations.length > 0) {\n    lines.push('### Recommendations');\n    lines.push('');\n    for (const rec of assessment.recommendations) {\n      lines.push(`- ${rec}`);\n    }\n    lines.push('');\n  }\n\n  return lines.join('\\n');\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","import { Option } from 'effect';\nimport type {\n  StaticEffectIR,\n  StaticFlowNode,\n  StaticEffectNode,\n  DiagramQuality,\n  DiagramQualityMetrics,\n  DiagramQualityWithFile,\n  DiagramTopOffendersReport,\n  DiagramTopOffenderEntry,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { generatePaths } from './path-generator';\nimport { summarizePathSteps } from './output/mermaid';\n\nexport interface DiagramQualityHintInput {\n  readonly reasons?: readonly string[] | undefined;\n  readonly tips?: readonly string[] | undefined;\n}\n\nexport interface DiagramQualityOptions {\n  readonly styleGuideSummary?: boolean | undefined;\n  readonly hints?: DiagramQualityHintInput | undefined;\n}\n\nconst MAX_PROGRAM_TIPS = 3;\nconst MAX_FILE_TIPS = 5;\n\nfunction clamp(n: number, min: number, max: number): number {\n  return Math.max(min, Math.min(max, n));\n}\n\nfunction uniqueCapped(items: readonly string[], max: number): string[] {\n  return [...new Set(items)].slice(0, max);\n}\n\nfunction startsWithAllowedTipPrefix(tip: string): boolean {\n  return (\n    tip.startsWith('Consider') ||\n    tip.startsWith('If you want clearer diagrams') ||\n    tip.startsWith('For larger programs')\n  );\n}\n\nfunction normalizeTip(tip: string): string {\n  if (startsWithAllowedTipPrefix(tip)) return tip;\n  return `Consider ${tip.charAt(0).toLowerCase()}${tip.slice(1)}`;\n}\n\nfunction collectAllNodes(nodes: readonly StaticFlowNode[]): StaticFlowNode[] {\n  const out: StaticFlowNode[] = [];\n  const visit = (list: readonly StaticFlowNode[]) => {\n    for (const node of list) {\n      out.push(node);\n      const children = Option.getOrElse(getStaticChildren(node), () => [] as readonly StaticFlowNode[]);\n      if (children.length > 0) visit(children);\n    }\n  };\n  visit(nodes);\n  return out;\n}\n\nfunction isLogLike(name: string): boolean {\n  const n = name.toLowerCase();\n  return n.includes('log') || n.includes('logger') || n.includes('taperror');\n}\n\nfunction looksAnonymousEffectNode(node: StaticEffectNode): boolean {\n  const callee = node.callee.trim();\n  if (callee === '' || callee === '_' || callee === 'Effect') return true;\n  if (/call expression/i.test(callee)) return true;\n  if (/^program-\\d+$/i.test(node.name ?? '')) return true;\n  return false;\n}\n\nfunction isServiceCallNode(node: StaticFlowNode): node is StaticEffectNode {\n  return (\n    node.type === 'effect' &&\n    (node.semanticRole === 'service-call' ||\n      node.serviceCall !== undefined ||\n      node.serviceMethod !== undefined)\n  );\n}\n\nfunction hasNamedServiceCallee(node: StaticEffectNode): boolean {\n  const c = node.callee.trim();\n  if (c === '' || c === '_' || c === 'Effect') return false;\n  if (/unknown/i.test(c) || /call expression/i.test(c)) return false;\n  return true;\n}\n\nfunction computeMetrics(\n  ir: StaticEffectIR,\n  options: DiagramQualityOptions = {},\n): DiagramQualityMetrics {\n  const nodes = collectAllNodes(ir.root.children);\n  const detailedSteps = nodes.length;\n  const effects = nodes.filter((n): n is StaticEffectNode => n.type === 'effect');\n\n  const sideEffects = effects.filter((n) => n.semanticRole === 'side-effect');\n  const logEffects = effects.filter((n) => isLogLike(n.displayName ?? n.name ?? n.callee));\n  const unknownNodes = nodes.filter((n) => n.type === 'unknown').length;\n\n  const anonymousNodeCount = nodes.filter((n) => {\n    if (n.type === 'unknown') return true;\n    if (n.type === 'pipe') return true;\n    if (n.type === 'effect') return looksAnonymousEffectNode(n);\n    return false;\n  }).length;\n\n  const serviceCalls = nodes.filter((n) => isServiceCallNode(n));\n  const namedServiceCalls = serviceCalls.filter((n) => hasNamedServiceCallee(n));\n\n  const pipeNodes = nodes.filter((n): n is StaticFlowNode & { type: 'pipe'; transformations: readonly StaticFlowNode[] } => n.type === 'pipe');\n  const pipeChainCount = pipeNodes.length;\n  const maxPipeChainLength = pipeNodes.length > 0\n    ? Math.max(...pipeNodes.map((p) => 1 + p.transformations.length))\n    : 0;\n\n  const paths = generatePaths(ir);\n  const representativePath = [...paths].sort((a, b) => b.steps.length - a.steps.length)[0];\n  const summary = representativePath\n    ? summarizePathSteps(representativePath, {\n        collapseRepeatedLogs: true,\n        collapsePureTransforms: true,\n        styleGuide: options.styleGuideSummary ?? false,\n      })\n    : { steps: [] as const, collapsedGroups: 0 };\n\n  const ratioBase = detailedSteps > 0 ? detailedSteps : 1;\n  const serviceBase = serviceCalls.length > 0 ? serviceCalls.length : 1;\n\n  return {\n    stepCountDetailed: detailedSteps,\n    stepCountSummary: summary.steps.length,\n    collapsedGroupsSummary: summary.collapsedGroups,\n    logRatio: logEffects.length / ratioBase,\n    sideEffectRatio: sideEffects.length / ratioBase,\n    anonymousNodeCount,\n    anonymousRatio: anonymousNodeCount / ratioBase,\n    unknownNodeCount: unknownNodes,\n    serviceCallCount: serviceCalls.length,\n    namedServiceCallRatio: namedServiceCalls.length / serviceBase,\n    pipeChainCount,\n    maxPipeChainLength,\n  };\n}\n\nfunction scoreFromMetrics(metrics: DiagramQualityMetrics): { score: number; band: DiagramQuality['band'] } {\n  const unknownPenalty = Math.min(35, metrics.unknownNodeCount * 8);\n  const anonymousPenalty = Math.min(25, Math.round(metrics.anonymousRatio * 40));\n  const stepPenalty =\n    metrics.stepCountDetailed > 24\n      ? Math.min(22, Math.round((metrics.stepCountDetailed - 24) * 0.6))\n      : 0;\n  const logPenalty = Math.min(12, Math.round(metrics.logRatio * 30));\n  const sideEffectPenalty =\n    metrics.sideEffectRatio > 0.75\n      ? Math.min(8, Math.round((metrics.sideEffectRatio - 0.75) * 40))\n      : 0;\n\n  const score = clamp(\n    Math.round(100 - unknownPenalty - anonymousPenalty - stepPenalty - logPenalty - sideEffectPenalty),\n    0,\n    100,\n  );\n  const band: DiagramQuality['band'] = score >= 75 ? 'good' : score >= 50 ? 'ok' : 'noisy';\n  return { score, band };\n}\n\nfunction reasonsFromMetrics(metrics: DiagramQualityMetrics): string[] {\n  const reasons: string[] = [];\n  const logCount = Math.round(metrics.logRatio * Math.max(metrics.stepCountDetailed, 1));\n\n  if (metrics.stepCountDetailed >= 60) {\n    reasons.push(`High step count (${String(metrics.stepCountDetailed)}). Consider summary mode.`);\n  } else if (metrics.stepCountDetailed >= 35) {\n    reasons.push(`Moderate step count (${String(metrics.stepCountDetailed)}). Summary mode may improve readability.`);\n  }\n\n  if (logCount >= 12 || metrics.logRatio >= 0.35) {\n    reasons.push(`Many log steps (${String(logCount)}). Consider collapsing logs or summary mode.`);\n  }\n\n  if (metrics.anonymousNodeCount >= 5) {\n    reasons.push(`${String(metrics.anonymousNodeCount)} anonymous nodes from pipe chains or unnamed calls.`);\n  }\n\n  if (metrics.unknownNodeCount > 0) {\n    reasons.push(`${String(metrics.unknownNodeCount)} unresolved nodes may reduce diagram clarity.`);\n  }\n\n  if (metrics.serviceCallCount >= 3 && metrics.namedServiceCallRatio < 0.7) {\n    reasons.push(\n      `Service call naming clarity is ${(metrics.namedServiceCallRatio * 100).toFixed(0)}% (${String(metrics.serviceCallCount)} calls).`,\n    );\n  }\n\n  return reasons;\n}\n\nfunction tipsFromMetrics(metrics: DiagramQualityMetrics): string[] {\n  const tips: string[] = [];\n  const logCount = Math.round(metrics.logRatio * Math.max(metrics.stepCountDetailed, 1));\n\n  if (metrics.stepCountDetailed >= 35) {\n    tips.push('For larger programs, consider summary mode.');\n  }\n  if (logCount >= 12 || metrics.logRatio >= 0.35) {\n    tips.push('For larger programs, consider grouping logs or using summary mode.');\n  }\n  if (metrics.anonymousNodeCount >= 5) {\n    tips.push('Consider naming intermediate values or extracting named helpers.');\n  }\n  if (metrics.pipeChainCount >= 4 || metrics.maxPipeChainLength >= 6) {\n    tips.push('If you want clearer diagrams, consider splitting long pipe chains into named steps.');\n  }\n  if (metrics.serviceCallCount >= 3 && metrics.namedServiceCallRatio < 0.7) {\n    tips.push('Consider naming service-call intermediates to make boundaries explicit.');\n  }\n\n  return uniqueCapped(tips.map(normalizeTip), MAX_PROGRAM_TIPS);\n}\n\nexport function computeProgramDiagramQuality(\n  ir: StaticEffectIR,\n  options: DiagramQualityOptions = {},\n): DiagramQuality {\n  const metrics = computeMetrics(ir, options);\n  const { score, band } = scoreFromMetrics(metrics);\n  const reasons = reasonsFromMetrics(metrics);\n  const tips = tipsFromMetrics(metrics);\n\n  const hintReasons = options.hints?.reasons ?? [];\n  const hintTips = (options.hints?.tips ?? []).map(normalizeTip);\n\n  return {\n    score,\n    band,\n    metrics,\n    reasons: uniqueCapped([...reasons, ...hintReasons], 8),\n    tips: uniqueCapped([...tips, ...hintTips], MAX_PROGRAM_TIPS),\n  };\n}\n\nfunction aggregateMetrics(qualities: readonly DiagramQuality[]): DiagramQualityMetrics {\n  if (qualities.length === 0) {\n    return {\n      stepCountDetailed: 0,\n      stepCountSummary: 0,\n      collapsedGroupsSummary: 0,\n      logRatio: 0,\n      sideEffectRatio: 0,\n      anonymousNodeCount: 0,\n      anonymousRatio: 0,\n      unknownNodeCount: 0,\n      serviceCallCount: 0,\n      namedServiceCallRatio: 0,\n      pipeChainCount: 0,\n      maxPipeChainLength: 0,\n    };\n  }\n\n  const weights = qualities.map((q) => Math.max(1, q.metrics.stepCountDetailed));\n  const totalWeight = weights.reduce((a, b) => a + b, 0);\n  const weightedAvg = (picker: (q: DiagramQuality) => number): number =>\n    qualities.reduce((sum, q, i) => sum + picker(q) * (weights[i] ?? 1), 0) / totalWeight;\n  const weightedSum = (picker: (q: DiagramQuality) => number): number =>\n    qualities.reduce((sum, q) => sum + picker(q), 0);\n\n  return {\n    stepCountDetailed: Math.round(weightedAvg((q) => q.metrics.stepCountDetailed)),\n    stepCountSummary: Math.round(weightedAvg((q) => q.metrics.stepCountSummary)),\n    collapsedGroupsSummary: Math.round(weightedAvg((q) => q.metrics.collapsedGroupsSummary)),\n    logRatio: weightedAvg((q) => q.metrics.logRatio),\n    sideEffectRatio: weightedAvg((q) => q.metrics.sideEffectRatio),\n    anonymousNodeCount: Math.round(weightedSum((q) => q.metrics.anonymousNodeCount)),\n    anonymousRatio: weightedAvg((q) => q.metrics.anonymousRatio),\n    unknownNodeCount: Math.round(weightedSum((q) => q.metrics.unknownNodeCount)),\n    serviceCallCount: Math.round(weightedSum((q) => q.metrics.serviceCallCount)),\n    namedServiceCallRatio: weightedAvg((q) => q.metrics.namedServiceCallRatio),\n    pipeChainCount: Math.round(weightedSum((q) => q.metrics.pipeChainCount)),\n    maxPipeChainLength: Math.max(...qualities.map((q) => q.metrics.maxPipeChainLength)),\n  };\n}\n\nexport function computeFileDiagramQuality(\n  filePath: string,\n  programs: readonly StaticEffectIR[],\n  options: DiagramQualityOptions = {},\n): DiagramQualityWithFile {\n  const programQualities = programs.map((ir) => computeProgramDiagramQuality(ir, options));\n  const metrics = aggregateMetrics(programQualities);\n  const weightedScore = programQualities.length > 0\n    ? Math.round(\n        programQualities.reduce(\n          (sum, q) => sum + q.score * Math.max(1, q.metrics.stepCountDetailed),\n          0,\n        ) /\n          programQualities.reduce((sum, q) => sum + Math.max(1, q.metrics.stepCountDetailed), 0),\n      )\n    : 100;\n\n  const band: DiagramQuality['band'] =\n    weightedScore >= 75 ? 'good' : weightedScore >= 50 ? 'ok' : 'noisy';\n\n  const reasons = uniqueCapped(\n    [\n      ...reasonsFromMetrics(metrics),\n      ...(options.hints?.reasons ?? []),\n    ],\n    10,\n  );\n  const tips = uniqueCapped(\n    [\n      ...tipsFromMetrics(metrics),\n      ...((options.hints?.tips ?? []).map(normalizeTip)),\n    ].filter(startsWithAllowedTipPrefix),\n    MAX_FILE_TIPS,\n  );\n\n  return {\n    filePath,\n    quality: {\n      score: weightedScore,\n      band,\n      metrics,\n      reasons,\n      tips,\n    },\n  };\n}\n\nfunction makeEntry(filePath: string, metricValue: number, tip: string): DiagramTopOffenderEntry {\n  return {\n    filePath,\n    metricValue,\n    tip: normalizeTip(tip),\n  };\n}\n\nfunction rankTop(\n  entries: readonly DiagramQualityWithFile[],\n  valueOf: (q: DiagramQualityWithFile) => number,\n  tip: (q: DiagramQualityWithFile) => string,\n  topN: number,\n): DiagramTopOffenderEntry[] {\n  return [...entries]\n    .sort((a, b) => {\n      const dv = valueOf(b) - valueOf(a);\n      if (dv !== 0) return dv;\n      return a.filePath.localeCompare(b.filePath);\n    })\n    .slice(0, topN)\n    .map((q) => makeEntry(q.filePath, valueOf(q), tip(q)));\n}\n\nexport function buildTopOffendersReport(\n  fileQualities: readonly DiagramQualityWithFile[],\n  topN = 10,\n): DiagramTopOffendersReport {\n  const capped = clamp(topN, 1, 50);\n  return {\n    largestPrograms: rankTop(\n      fileQualities,\n      (q) => q.quality.metrics.stepCountDetailed,\n      () => 'For larger programs, consider summary mode.',\n      capped,\n    ),\n    mostAnonymousNodes: rankTop(\n      fileQualities,\n      (q) => q.quality.metrics.anonymousNodeCount,\n      () => 'Consider naming intermediate values or extracting named helpers.',\n      capped,\n    ),\n    mostUnknownNodes: rankTop(\n      fileQualities,\n      (q) => q.quality.metrics.unknownNodeCount,\n      () => 'If you want clearer diagrams, consider extracting helpers to reduce unresolved nodes.',\n      capped,\n    ),\n    highestLogRatio: rankTop(\n      fileQualities,\n      (q) => q.quality.metrics.logRatio,\n      () => 'For larger programs, consider grouping logs or using summary mode.',\n      capped,\n    ),\n  };\n}\n\n","/**\n * Path Generator\n *\n * Generates all possible execution paths through an Effect program based on\n * static analysis. Each path represents a unique sequence of steps that could\n * execute given certain conditions.\n */\n\nimport type {\n  StaticEffectIR,\n  StaticFlowNode,\n  StaticDecisionNode,\n  StaticSwitchNode,\n  StaticTryCatchNode,\n  StaticTerminalNode,\n  StaticCauseNode,\n  StaticMatchNode,\n  StaticTransformNode,\n  StaticChannelNode,\n  StaticSinkNode,\n  StaticInterruptionNode,\n  EffectPath,\n  PathStepRef,\n  PathCondition,\n} from './types';\n\n// =============================================================================\n// Options\n// =============================================================================\n\nexport interface PathGeneratorOptions {\n  /** Maximum paths to generate (default: 1000) */\n  maxPaths?: number;\n  /** Whether to include loop iterations as separate paths (default: false) */\n  expandLoops?: boolean;\n  /** Maximum loop iterations to expand if expandLoops is true (default: 3) */\n  maxLoopIterations?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<PathGeneratorOptions> = {\n  maxPaths: 1000,\n  expandLoops: false,\n  maxLoopIterations: 3,\n};\n\n// =============================================================================\n// Path Generation\n// =============================================================================\n\nexport interface PathGenerationResult {\n  /** Generated effect paths */\n  paths: EffectPath[];\n  /** Whether the maxPaths limit was hit (truncation occurred) */\n  limitHit: boolean;\n}\n\n/**\n * Generate all possible execution paths through an Effect program.\n */\nexport function generatePaths(\n  ir: StaticEffectIR,\n  options: PathGeneratorOptions = {},\n): EffectPath[] {\n  return generatePathsWithMetadata(ir, options).paths;\n}\n\n/**\n * Generate all possible execution paths with metadata.\n */\nexport function generatePathsWithMetadata(\n  ir: StaticEffectIR,\n  options: PathGeneratorOptions = {},\n): PathGenerationResult {\n  const opts = { ...DEFAULT_OPTIONS, ...options };\n\n  const context: PathContext = {\n    opts,\n    pathCount: 0,\n    hasHitLimit: false,\n    controlStack: [],\n  };\n\n  const initialState: PathState = {\n    steps: [],\n    conditions: [],\n    hasLoops: false,\n    hasUnresolvedRefs: false,\n  };\n\n  const states = generatePathsForNodes(ir.root.children, initialState, context);\n\n  const paths: EffectPath[] = states.map((state, index) => ({\n    id: `path-${index + 1}`,\n    description: generatePathDescription(state),\n    steps: state.steps,\n    conditions: state.conditions,\n    hasLoops: state.hasLoops,\n    hasUnresolvedRefs: state.hasUnresolvedRefs,\n  }));\n\n  return {\n    paths,\n    limitHit: context.hasHitLimit,\n  };\n}\n\n// =============================================================================\n// Internal Types\n// =============================================================================\n\ninterface ControlTarget {\n  readonly kind: 'loop' | 'switch' | 'block';\n  readonly label?: string;\n  readonly breakContinuationNodeId: string;\n  readonly continueContinuationNodeId?: string; // only for loops\n}\n\ninterface PathContext {\n  opts: Required<PathGeneratorOptions>;\n  pathCount: number;\n  hasHitLimit: boolean;\n  controlStack: ControlTarget[];\n}\n\ninterface PathState {\n  steps: PathStepRef[];\n  conditions: PathCondition[];\n  hasLoops: boolean;\n  hasUnresolvedRefs: boolean;\n}\n\n// =============================================================================\n// Path Generation Logic\n// =============================================================================\n\nfunction generatePathsForNodes(\n  nodes: readonly StaticFlowNode[],\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  if (nodes.length === 0) {\n    return [currentState];\n  }\n\n  let states: PathState[] = [currentState];\n\n  for (const node of nodes) {\n    const newStates: PathState[] = [];\n    for (const state of states) {\n      newStates.push(...generatePathsForNode(node, state, context));\n    }\n    states = newStates;\n    if (node.type === 'terminal') {\n      const term = node;\n      if (term.terminalKind === 'return' || term.terminalKind === 'throw') {\n        return states;\n      }\n    }\n  }\n\n  return states;\n}\n\nfunction generatePathsForNode(\n  node: StaticFlowNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  switch (node.type) {\n    case 'effect':\n      return handleEffectNode(node, currentState);\n    case 'generator':\n      return handleGeneratorNode(node, currentState, context);\n    case 'pipe':\n      return handlePipeNode(node, currentState, context);\n    case 'parallel':\n      return handleParallelNode(node, currentState, context);\n    case 'race':\n      return handleRaceNode(node, currentState, context);\n    case 'error-handler':\n      return handleErrorHandlerNode(node, currentState, context);\n    case 'retry':\n    case 'timeout':\n      return handleSingleChildNode(node, currentState, context);\n    case 'resource':\n      return handleResourceNode(node, currentState, context);\n    case 'conditional':\n      return handleConditionalNode(node, currentState, context);\n    case 'loop':\n      return handleLoopNode(node, currentState, context);\n    case 'layer':\n      return handleLayerNode(node, currentState, context);\n    case 'stream':\n      return handleStreamNode(node, currentState, context);\n    case 'concurrency-primitive':\n    case 'fiber':\n      return handleConcurrencyOrFiberNode(node, currentState, context);\n    case 'decision':\n      return handleDecisionNode(node, currentState, context);\n    case 'switch':\n      return handleSwitchNode(node, currentState, context);\n    case 'try-catch':\n      return handleTryCatchNode(node, currentState, context);\n    case 'terminal':\n      return handleTerminalNode(node, currentState, context);\n    case 'cause':\n      return handleCauseNode(node, currentState, context);\n    case 'exit':\n    case 'schedule':\n      return handleLeafStepNode(node, currentState);\n    case 'match':\n      return handleMatchNode(node, currentState, context);\n    case 'transform':\n      return handleTransformNode(node, currentState, context);\n    case 'channel':\n      return handleChannelNode(node, currentState, context);\n    case 'sink':\n      return handleSinkNode(node, currentState, context);\n    case 'interruption':\n      return handleInterruptionNode(node, currentState, context);\n    case 'opaque':\n      return [currentState]; // treat as no-op, path continues\n    case 'unknown':\n      return [currentState];\n    default:\n      return [currentState];\n  }\n}\n\nfunction handleEffectNode(\n  node: StaticFlowNode & { type: 'effect' },\n  currentState: PathState,\n): PathState[] {\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name: node.name ?? node.callee,\n    repeated: false,\n  };\n  return [\n    {\n      ...currentState,\n      steps: [...currentState.steps, stepRef],\n    },\n  ];\n}\n\nfunction handleGeneratorNode(\n  node: StaticFlowNode & { type: 'generator' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const children = node.yields.map((y) => y.effect);\n  return generatePathsForNodes(children, currentState, context);\n}\n\nfunction handlePipeNode(\n  node: StaticFlowNode & { type: 'pipe' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const children = [node.initial, ...node.transformations];\n  return generatePathsForNodes(children, currentState, context);\n}\n\nfunction handleParallelNode(\n  node: StaticFlowNode & { type: 'parallel' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  let combinedStates: PathState[] = [currentState];\n\n  for (const child of node.children) {\n    const newCombinedStates: PathState[] = [];\n    for (const state of combinedStates) {\n      const childStates = generatePathsForNode(child, state, context);\n      for (const childState of childStates) {\n        newCombinedStates.push({\n          steps: childState.steps,\n          conditions: childState.conditions,\n          hasLoops: state.hasLoops || childState.hasLoops,\n          hasUnresolvedRefs:\n            state.hasUnresolvedRefs || childState.hasUnresolvedRefs,\n        });\n      }\n    }\n    combinedStates = newCombinedStates;\n  }\n\n  return combinedStates;\n}\n\nfunction handleRaceNode(\n  node: StaticFlowNode & { type: 'race' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  if (node.children.length === 0) {\n    return [currentState];\n  }\n\n  const atLimit =\n    context.hasHitLimit ||\n    context.pathCount + node.children.length >= context.opts.maxPaths;\n  if (atLimit) {\n    context.hasHitLimit = true;\n    const first = node.children[0];\n    if (first) {\n      return generatePathsForNode(first, currentState, context);\n    }\n    return [currentState];\n  }\n\n  const allStates: PathState[] = [];\n  const maxAllowed = context.opts.maxPaths;\n\n  for (const child of node.children) {\n    if (allStates.length >= maxAllowed) {\n      context.hasHitLimit = true;\n      break;\n    }\n    const childStates = generatePathsForNode(child, currentState, context);\n    const roomLeft = maxAllowed - allStates.length;\n    const toAdd = childStates.slice(0, roomLeft);\n    allStates.push(...toAdd);\n    if (toAdd.length < childStates.length) {\n      context.hasHitLimit = true;\n    }\n  }\n\n  context.pathCount += Math.max(0, allStates.length - 1);\n  return allStates.length > 0 ? allStates : [currentState];\n}\n\nfunction handleErrorHandlerNode(\n  node: StaticFlowNode & { type: 'error-handler' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const sourceStates = generatePathsForNode(node.source, currentState, context);\n  if (!node.handler) {\n    return sourceStates;\n  }\n  const handlerStates = generatePathsForNode(\n    node.handler,\n    currentState,\n    context,\n  );\n  return [...sourceStates, ...handlerStates];\n}\n\nfunction handleSingleChildNode(\n  node: StaticFlowNode & { type: 'retry' | 'timeout' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  return generatePathsForNode(node.source, currentState, context);\n}\n\nfunction handleResourceNode(\n  node: StaticFlowNode & { type: 'resource' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const resourceNodes: StaticFlowNode[] = [node.acquire, node.release];\n  if (node.use) {\n    resourceNodes.push(node.use);\n  }\n  return generatePathsForNodes(resourceNodes, currentState, context);\n}\n\nfunction handleConditionalNode(\n  node: StaticFlowNode & { type: 'conditional' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const trueCondition: PathCondition = {\n    expression: node.condition,\n    mustBe: node.conditionalType === 'unless' ? false : true,\n    location: node.location,\n  };\n\n  const trueState: PathState = {\n    ...currentState,\n    conditions: [...currentState.conditions, trueCondition],\n  };\n\n  const trueStates = generatePathsForNode(node.onTrue, trueState, context);\n\n  const falseCondition: PathCondition = {\n    expression: node.condition,\n    mustBe: node.conditionalType === 'unless' ? true : false,\n    location: node.location,\n  };\n\n  const falseState: PathState = {\n    ...currentState,\n    conditions: [...currentState.conditions, falseCondition],\n  };\n\n  if (node.onFalse) {\n    const falseStates = generatePathsForNode(node.onFalse, falseState, context);\n    return [...trueStates, ...falseStates];\n  }\n\n  return [...trueStates, falseState];\n}\n\nfunction handleLoopNode(\n  node: StaticFlowNode & { type: 'loop' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const bodyStates = generatePathsForNode(node.body, currentState, context);\n  return bodyStates.map((state) => ({\n    ...state,\n    steps: state.steps.map((step, idx) =>\n      idx >= currentState.steps.length ? { ...step, repeated: true } : step,\n    ),\n    hasLoops: true,\n  }));\n}\n\nfunction handleLayerNode(\n  node: StaticFlowNode & { type: 'layer' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  return generatePathsForNodes(node.operations, currentState, context);\n}\n\nfunction handleStreamNode(\n  node: StaticFlowNode & { type: 'stream' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name: node.pipeline.length > 0 ? `Stream.${node.pipeline.map((p) => p.operation).join(' → ')}` : 'Stream',\n    repeated: false,\n  };\n  const stateWithStep = {\n    ...currentState,\n    steps: [...currentState.steps, stepRef],\n  };\n  return generatePathsForNode(node.source, stateWithStep, context);\n}\n\nfunction handleConcurrencyOrFiberNode(\n  node: StaticFlowNode & { type: 'concurrency-primitive' | 'fiber' },\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name:\n      node.type === 'concurrency-primitive'\n        ? `${node.primitive}.${node.operation}`\n        : node.operation,\n    repeated: false,\n  };\n  const stateWithStep = {\n    ...currentState,\n    steps: [...currentState.steps, stepRef],\n  };\n  const child =\n    node.type === 'concurrency-primitive' ? node.source : node.fiberSource;\n  if (child) {\n    return generatePathsForNode(child, stateWithStep, context);\n  }\n  return [stateWithStep];\n}\n\nfunction handleDecisionNode(\n  node: StaticDecisionNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const trueCondition: PathCondition = {\n    expression: node.condition,\n    mustBe: true,\n    location: node.location,\n  };\n  const trueState: PathState = {\n    ...currentState,\n    conditions: [...currentState.conditions, trueCondition],\n  };\n  const trueStates = generatePathsForNodes(node.onTrue, trueState, context);\n\n  if (node.onFalse && node.onFalse.length > 0) {\n    const falseCondition: PathCondition = {\n      expression: node.condition,\n      mustBe: false,\n      location: node.location,\n    };\n    const falseState: PathState = {\n      ...currentState,\n      conditions: [...currentState.conditions, falseCondition],\n    };\n    const falseStates = generatePathsForNodes(node.onFalse, falseState, context);\n    return [...trueStates, ...falseStates];\n  }\n\n  const falseCondition: PathCondition = {\n    expression: node.condition,\n    mustBe: false,\n    location: node.location,\n  };\n  const falseState: PathState = {\n    ...currentState,\n    conditions: [...currentState.conditions, falseCondition],\n  };\n  return [...trueStates, falseState];\n}\n\nfunction handleSwitchNode(\n  node: StaticSwitchNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const allStates: PathState[] = [];\n\n  for (const caseItem of node.cases) {\n    const caseLabel = caseItem.labels.join(' / ');\n    const caseCondition: PathCondition = {\n      expression: `${node.expression} === ${caseLabel}`,\n      mustBe: true,\n      location: node.location,\n    };\n    const caseState: PathState = {\n      ...currentState,\n      conditions: [...currentState.conditions, caseCondition],\n    };\n    const caseStates = generatePathsForNodes(caseItem.body, caseState, context);\n    allStates.push(...caseStates);\n  }\n\n  return allStates.length > 0 ? allStates : [currentState];\n}\n\nfunction handleTryCatchNode(\n  node: StaticTryCatchNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  // Try path (success)\n  const tryStates = generatePathsForNodes(node.tryBody, currentState, context);\n\n  // Catch path\n  const catchStates: PathState[] = [];\n  if (node.catchBody && node.catchBody.length > 0) {\n    const catchCondition: PathCondition = {\n      expression: 'throws',\n      mustBe: true,\n      location: node.location,\n    };\n    const catchState: PathState = {\n      ...currentState,\n      conditions: [...currentState.conditions, catchCondition],\n    };\n    catchStates.push(...generatePathsForNodes(node.catchBody, catchState, context));\n  }\n\n  const combined = [...tryStates, ...catchStates];\n\n  // Finally path: if present, append to all paths\n  if (node.finallyBody && node.finallyBody.length > 0) {\n    const finalStates: PathState[] = [];\n    for (const state of combined) {\n      finalStates.push(...generatePathsForNodes(node.finallyBody, state, context));\n    }\n    return finalStates;\n  }\n\n  return combined;\n}\n\nfunction handleTerminalNode(\n  node: StaticTerminalNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  // If the terminal has value nodes (e.g., return yield* effect), process them first\n  let state = currentState;\n  if (node.value && node.value.length > 0) {\n    const valueStates = generatePathsForNodes(node.value, currentState, context);\n    // Take the first resulting state (value expressions produce sequential steps)\n    state = valueStates[0] ?? currentState;\n  }\n\n  switch (node.terminalKind) {\n    case 'return':\n    case 'throw':\n      // Path terminates — add a step marking the termination\n      return [{\n        ...state,\n        steps: [...state.steps, {\n          nodeId: node.id,\n          name: node.terminalKind,\n          repeated: false,\n        }],\n      }];\n\n    case 'break':\n    case 'continue':\n      // These are structurally captured — just continue the path\n      return [state];\n  }\n}\n\n// =============================================================================\n// New node type handlers (cause, exit, schedule, match, transform, channel, sink, interruption)\n// =============================================================================\n\nfunction handleLeafStepNode(\n  node: StaticFlowNode,\n  currentState: PathState,\n): PathState[] {\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name: node.name ?? node.type,\n    repeated: false,\n  };\n  return [{\n    ...currentState,\n    steps: [...currentState.steps, stepRef],\n  }];\n}\n\nfunction handleCauseNode(\n  node: StaticCauseNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name: node.name ?? `Cause.${node.causeOp}`,\n    repeated: false,\n  };\n  const stateWithStep: PathState = {\n    ...currentState,\n    steps: [...currentState.steps, stepRef],\n  };\n\n  if (node.children && node.children.length > 0) {\n    return generatePathsForNodes([...node.children], stateWithStep, context);\n  }\n  return [stateWithStep];\n}\n\nfunction handleMatchNode(\n  node: StaticMatchNode,\n  currentState: PathState,\n  _context: PathContext,\n): PathState[] {\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name: node.name ?? `Match.${node.matchOp}`,\n    repeated: false,\n  };\n  return [{\n    ...currentState,\n    steps: [...currentState.steps, stepRef],\n  }];\n}\n\nfunction handleTransformNode(\n  node: StaticTransformNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  let state = currentState;\n  if (node.source) {\n    const sourceStates = generatePathsForNode(node.source, currentState, context);\n    state = sourceStates[0] ?? currentState;\n  }\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name: node.name ?? node.transformType,\n    repeated: false,\n  };\n  return [{\n    ...state,\n    steps: [...state.steps, stepRef],\n  }];\n}\n\nfunction handleChannelNode(\n  node: StaticChannelNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  let state = currentState;\n  if (node.source) {\n    const sourceStates = generatePathsForNode(node.source, currentState, context);\n    state = sourceStates[0] ?? currentState;\n  }\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name: node.name ?? `Channel${node.pipeline.length > 0 ? `.${node.pipeline.map(p => p.operation).join('.')}` : ''}`,\n    repeated: false,\n  };\n  return [{\n    ...state,\n    steps: [...state.steps, stepRef],\n  }];\n}\n\nfunction handleSinkNode(\n  node: StaticSinkNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  let state = currentState;\n  if (node.source) {\n    const sourceStates = generatePathsForNode(node.source, currentState, context);\n    state = sourceStates[0] ?? currentState;\n  }\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name: node.name ?? `Sink${node.pipeline.length > 0 ? `.${node.pipeline.map(p => p.operation).join('.')}` : ''}`,\n    repeated: false,\n  };\n  return [{\n    ...state,\n    steps: [...state.steps, stepRef],\n  }];\n}\n\nfunction handleInterruptionNode(\n  node: StaticInterruptionNode,\n  currentState: PathState,\n  context: PathContext,\n): PathState[] {\n  const stepRef: PathStepRef = {\n    nodeId: node.id,\n    name: node.name ?? node.interruptionType,\n    repeated: false,\n  };\n  const stateWithStep: PathState = {\n    ...currentState,\n    steps: [...currentState.steps, stepRef],\n  };\n\n  if (node.source) {\n    const sourceStates = generatePathsForNode(node.source, stateWithStep, context);\n    if (node.handler) {\n      // Fork: source path + handler path (on interrupt)\n      const handlerStates = generatePathsForNode(node.handler, stateWithStep, context);\n      return [...sourceStates, ...handlerStates];\n    }\n    return sourceStates;\n  }\n  return [stateWithStep];\n}\n\n// =============================================================================\n// Path Description\n// =============================================================================\n\nfunction generatePathDescription(state: PathState): string {\n  const parts: string[] = [];\n\n  if (state.conditions.length > 0) {\n    const conditionParts = state.conditions.map((c) => {\n      const verb = c.mustBe ? 'is true' : 'is false';\n      const expr =\n        c.expression.length > 30\n          ? c.expression.slice(0, 30) + '...'\n          : c.expression;\n      return `${expr} ${verb}`;\n    });\n    parts.push(`When ${conditionParts.join(' AND ')}`);\n  }\n\n  const stepNames = state.steps\n    .map((s) => {\n      const name = s.name ?? s.nodeId;\n      return s.repeated ? `${name} (repeated)` : name;\n    })\n    .join(' → ');\n\n  if (stepNames) {\n    parts.push(`Steps: ${stepNames}`);\n  }\n\n  if (state.hasLoops) {\n    parts.push('[contains loops]');\n  }\n  if (state.hasUnresolvedRefs) {\n    parts.push('[has unresolved refs]');\n  }\n\n  return parts.join('. ') || 'Empty path';\n}\n\n// =============================================================================\n// Path Statistics\n// =============================================================================\n\nexport interface PathStatistics {\n  totalPaths: number;\n  pathLimitHit: boolean;\n  pathsWithLoops: number;\n  pathsWithUnresolvedRefs: number;\n  uniqueConditions: string[];\n  maxPathLength: number;\n  minPathLength: number;\n  avgPathLength: number;\n}\n\nexport interface PathStatisticsOptions {\n  limitHit?: boolean;\n}\n\nexport function calculatePathStatistics(\n  paths: EffectPath[],\n  options?: PathStatisticsOptions,\n): PathStatistics {\n  if (paths.length === 0) {\n    return {\n      totalPaths: 0,\n      pathLimitHit: false,\n      pathsWithLoops: 0,\n      pathsWithUnresolvedRefs: 0,\n      uniqueConditions: [],\n      maxPathLength: 0,\n      minPathLength: 0,\n      avgPathLength: 0,\n    };\n  }\n\n  const conditions = new Set<string>();\n  let pathsWithLoops = 0;\n  let pathsWithUnresolvedRefs = 0;\n  let totalLength = 0;\n  let maxLength = 0;\n  let minLength = Infinity;\n\n  for (const path of paths) {\n    if (path.hasLoops) pathsWithLoops++;\n    if (path.hasUnresolvedRefs) pathsWithUnresolvedRefs++;\n    const length = path.steps.length;\n    totalLength += length;\n    maxLength = Math.max(maxLength, length);\n    minLength = Math.min(minLength, length);\n    for (const c of path.conditions) {\n      conditions.add(c.expression);\n    }\n  }\n\n  return {\n    totalPaths: paths.length,\n    pathLimitHit: options?.limitHit ?? false,\n    pathsWithLoops,\n    pathsWithUnresolvedRefs,\n    uniqueConditions: Array.from(conditions),\n    maxPathLength: maxLength,\n    minPathLength: minLength === Infinity ? 0 : minLength,\n    avgPathLength: totalLength / paths.length,\n  };\n}\n\n// =============================================================================\n// Path Filtering\n// =============================================================================\n\nexport function filterPaths(\n  paths: EffectPath[],\n  filter: {\n    mustIncludeStep?: string;\n    mustExcludeStep?: string;\n    conditionTrue?: string;\n    conditionFalse?: string;\n    noLoops?: boolean;\n    maxLength?: number;\n  },\n): EffectPath[] {\n  return paths.filter((path) => {\n    if (filter.mustIncludeStep) {\n      const has = path.steps.some(\n        (s) => s.name === filter.mustIncludeStep || s.nodeId === filter.mustIncludeStep,\n      );\n      if (!has) return false;\n    }\n    if (filter.mustExcludeStep) {\n      const has = path.steps.some(\n        (s) =>\n          s.name === filter.mustExcludeStep ||\n          s.nodeId === filter.mustExcludeStep,\n      );\n      if (has) return false;\n    }\n    if (filter.conditionTrue) {\n      const has = path.conditions.some(\n        (c) => c.expression === filter.conditionTrue && c.mustBe,\n      );\n      if (!has) return false;\n    }\n    if (filter.conditionFalse) {\n      const has = path.conditions.some(\n        (c) => c.expression === filter.conditionFalse && !c.mustBe,\n      );\n      if (!has) return false;\n    }\n    if (filter.noLoops && path.hasLoops) return false;\n    if (filter.maxLength !== undefined && path.steps.length > filter.maxLength)\n      return false;\n    return true;\n  });\n}\n","/**\n * Mermaid diagram generation for Effect IR\n *\n * Aligned with awaitly-analyze: Start/End nodes, explicit edges,\n * optional subgraphs for parallel/race, sequential flow for pipe/generator.\n */\n\nimport { Effect, Option } from 'effect';\nimport type {\n  ProjectServiceMap,\n  StaticEffectIR,\n  StaticFlowNode,\n  StaticFiberNode,\n  StaticRetryNode,\n  StaticEffectNode,\n  MermaidOptions,\n  MermaidStyles,\n  MermaidDetailLevel,\n  EffectPath,\n} from '../types';\nimport { getStaticChildren } from '../types';\nimport { buildDataFlowGraph } from '../data-flow';\nimport { analyzeErrorFlow, analyzeErrorPropagation } from '../error-flow';\nimport { DEFAULT_LABEL_MAX, truncateDisplayText, countMeaningfulNodes } from '../analysis-utils';\nimport type { RuntimeTrace, RuntimeSpanStatus } from '../runtime-trace';\nimport { indexIR, spanPathKey } from '../ir';\n\n// =============================================================================\n// Default styles (include start/end for Start/End nodes)\n// =============================================================================\n\nconst DEFAULT_STYLES: MermaidStyles = {\n  effect: 'fill:#90EE90,stroke:#333,stroke-width:2px',\n  generator: 'fill:#FFB6C1,stroke:#333,stroke-width:2px',\n  pipe: 'fill:#ADD8E6,stroke:#333,stroke-width:2px',\n  parallel: 'fill:#FFA500,stroke:#333,stroke-width:2px',\n  race: 'fill:#FF6347,stroke:#333,stroke-width:2px',\n  errorHandler: 'fill:#FFD700,stroke:#333,stroke-width:2px',\n  retry: 'fill:#EE82EE,stroke:#333,stroke-width:2px',\n  timeout: 'fill:#87CEEB,stroke:#333,stroke-width:2px',\n  resource: 'fill:#98FB98,stroke:#333,stroke-width:2px',\n  conditional: 'fill:#DDA0DD,stroke:#333,stroke-width:2px',\n  loop: 'fill:#F0E68C,stroke:#333,stroke-width:2px',\n  layer: 'fill:#E6E6FA,stroke:#333,stroke-width:2px',\n  stream: 'fill:#E0F7FA,stroke:#333,stroke-width:2px',\n  concurrencyPrimitive: 'fill:#B0E0E6,stroke:#333,stroke-width:2px',\n  fiber: 'fill:#DDA0DD,stroke:#333,stroke-width:2px',\n  decision: 'fill:#DDA0DD,stroke:#333,stroke-width:2px',\n  switch: 'fill:#FFD700,stroke:#333,stroke-width:2px',\n  tryCatch: 'fill:#FFE4B5,stroke:#333,stroke-width:2px',\n  terminal: 'fill:#FF6B6B,stroke:#333,stroke-width:2px',\n  opaque: 'fill:#FF9800,stroke:#333,stroke-width:2px',\n  unknown: 'fill:#D3D3D3,stroke:#333,stroke-width:1px',\n  start: 'fill:#c8e6c9,stroke:#2e7d32',\n  end: 'fill:#ffcdd2,stroke:#c62828',\n  cause: 'fill:#FF8A80,stroke:#D32F2F,stroke-width:2px',\n  exit: 'fill:#B39DDB,stroke:#512DA8,stroke-width:2px',\n  schedule: 'fill:#80DEEA,stroke:#00838F,stroke-width:2px',\n  match: 'fill:#FFE082,stroke:#F57F17,stroke-width:2px',\n  transform: 'fill:#A5D6A7,stroke:#388E3C,stroke-width:2px',\n  channel: 'fill:#90CAF9,stroke:#1565C0,stroke-width:2px',\n  sink: 'fill:#CE93D8,stroke:#7B1FA2,stroke-width:2px',\n  interruption: 'fill:#FFAB91,stroke:#BF360C,stroke-width:2px',\n};\n\nconst DEFAULT_OPTIONS: Required<\n  Omit<MermaidOptions, 'title' | 'includeTypeSignatures' | 'detail' | 'dataFlowOverlay' | 'errorFlowOverlay'>\n> & {\n  title?: string;\n  includeTypeSignatures?: boolean;\n  detail?: MermaidDetailLevel;\n  dataFlowOverlay?: boolean;\n  errorFlowOverlay?: boolean;\n} = {\n  direction: 'TB',\n  includeIds: false,\n  includeDescriptions: true,\n  styles: DEFAULT_STYLES,\n  compact: false,\n  includeTypeSignatures: true,\n  useSubgraphs: true,\n  showConditions: true,\n  detail: 'verbose',\n};\n\n// =============================================================================\n// Internal types (awaitly-style context and result)\n// =============================================================================\n\ninterface Edge {\n  from: string;\n  to: string;\n  label?: string;\n}\n\ninterface Subgraph {\n  id: string;\n  label: string;\n  content: string[];\n}\n\ninterface RenderContext {\n  opts: ResolvedMermaidOptions;\n  nodeCounter: number;\n  edges: Edge[];\n  subgraphs: Subgraph[];\n  styleClasses: Map<string, string>;\n  /** Map from IR node id to mermaid node ID (for enhanced overlay) */\n  nodeIdMap: Map<string, string>;\n  /** Optional label annotations per node id (for enhanced renderer) */\n  nodeLabelAnnotations?: Map<string, string[]> | undefined;\n}\n\n/** Options with defaults applied (all required fields set). */\ninterface ResolvedMermaidOptions {\n  direction: 'TB' | 'LR' | 'BT' | 'RL';\n  includeIds: boolean;\n  includeDescriptions: boolean;\n  styles: MermaidStyles;\n  compact: boolean;\n  useSubgraphs: boolean;\n  showConditions: boolean;\n  detail: MermaidDetailLevel;\n  title?: string | undefined;\n  includeTypeSignatures?: boolean | undefined;\n}\n\ninterface RenderResult {\n  firstNodeId: string | null;\n  lastNodeIds: string[];\n}\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\nfunction escapeLabel(label: string): string {\n  return label\n    .replace(/\\s+/g, ' ')\n    .replace(/\"/g, \"'\")\n    .replace(/\\[/g, '(')\n    .replace(/\\]/g, ')')\n    .replace(/\\{/g, '(')\n    .replace(/\\}/g, ')')\n    .replace(/#/g, '&num;')\n    .replace(/\\|/g, '&#124;');\n}\n\nfunction truncate(str: string, maxLength: number): string {\n  if (str.length <= maxLength) return str;\n  return str.slice(0, maxLength - 3) + '...';\n}\n\nfunction sanitizeId(id: string): string {\n  return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n// =============================================================================\n// Internal: render static Mermaid (sync) for reuse by static and enhanced\n// =============================================================================\n\nfunction renderStaticMermaidInternal(\n  ir: StaticEffectIR,\n  options?: Partial<MermaidOptions>,\n  nodeLabelAnnotations?: Map<string, string[]>,\n): { lines: string[]; context: RenderContext } {\n  const autoDetail = (): MermaidDetailLevel => {\n    const nodeCount = countMeaningfulNodes(ir.root.children);\n    if (nodeCount > 80) return 'compact';\n    if (nodeCount >= 30) return 'standard';\n    return 'verbose';\n  };\n\n  const opts: ResolvedMermaidOptions = {\n    ...DEFAULT_OPTIONS,\n    ...options,\n    useSubgraphs: options?.useSubgraphs ?? true,\n    showConditions: options?.showConditions ?? true,\n    detail: options?.detail ?? autoDetail(),\n  };\n  const context: RenderContext = {\n    opts,\n    nodeCounter: 0,\n    edges: [],\n    subgraphs: [],\n    styleClasses: new Map(),\n    nodeIdMap: new Map(),\n    nodeLabelAnnotations,\n  };\n\n  const lines: string[] = [];\n\n  lines.push(`flowchart ${opts.direction}`);\n  lines.push('');\n  lines.push(`  %% Program: ${ir.root.programName}`);\n  lines.push('');\n\n  const startId = 'start';\n  const endId = 'end_node';\n  lines.push(`  ${startId}((Start))`);\n  lines.push(`  ${endId}((End))`);\n  lines.push('');\n\n  const { firstNodeId, lastNodeIds } = renderNodes(\n    ir.root.children,\n    context,\n    lines,\n  );\n\n  if (firstNodeId) {\n    context.edges.push({ from: startId, to: firstNodeId });\n  }\n  for (const lastId of lastNodeIds) {\n    context.edges.push({ from: lastId, to: endId });\n  }\n\n  for (const subgraph of context.subgraphs) {\n    lines.push('');\n    lines.push(`  subgraph ${subgraph.id}[\"${subgraph.label}\"]`);\n    for (const line of subgraph.content) {\n      lines.push(`    ${line}`);\n    }\n    lines.push('  end');\n  }\n\n  lines.push('');\n  lines.push('  %% Edges');\n  for (const edge of context.edges) {\n    if (edge.label && opts.showConditions) {\n      lines.push(`  ${edge.from} -->|${escapeLabel(edge.label)}| ${edge.to}`);\n    } else {\n      lines.push(`  ${edge.from} --> ${edge.to}`);\n    }\n  }\n\n  const styles = { ...DEFAULT_STYLES, ...opts.styles };\n  lines.push('');\n  lines.push('  %% Styles');\n\n  // Collect which style keys are actually used by nodes in the diagram\n  const usedStyleKeys = new Set<string>(['start', 'end']);\n  for (const [, styleClass] of context.styleClasses) {\n    // styleClass values are like \"effectStyle\", \"decisionStyle\" — strip \"Style\" suffix to get the key\n    const key = styleClass.endsWith('Style') ? styleClass.slice(0, -5) : styleClass;\n    usedStyleKeys.add(key);\n  }\n\n  if (styles.start) {\n    lines.push(`  classDef startStyle ${styles.start}`);\n  }\n  if (styles.end) {\n    lines.push(`  classDef endStyle ${styles.end}`);\n  }\n  for (const [key, value] of Object.entries(styles)) {\n    if (value && key !== 'start' && key !== 'end' && usedStyleKeys.has(key)) {\n      lines.push(`  classDef ${key}Style ${value}`);\n    }\n  }\n  lines.push(`  class ${startId} startStyle`);\n  lines.push(`  class ${endId} endStyle`);\n  for (const [nodeId, styleClass] of context.styleClasses) {\n    lines.push(`  class ${nodeId} ${styleClass}`);\n  }\n\n  // Data-flow overlay: annotate edges with variable names and highlight warnings\n  if (options?.dataFlowOverlay) {\n    const dataFlow = buildDataFlowGraph(ir);\n\n    // Build IR-node-id → mermaid-node-id mapping for data-flow nodes\n    const irToMermaid = context.nodeIdMap;\n\n    // Annotate edges between nodes with variable name labels\n    lines.push('');\n    lines.push('  %% Data-flow variable annotations');\n    lines.push('  linkStyle default stroke:#999');\n    for (const dfEdge of dataFlow.edges) {\n      if (dfEdge.from === '__context__') continue;\n      const fromMermaid = irToMermaid.get(dfEdge.from);\n      const toMermaid = irToMermaid.get(dfEdge.to);\n      if (fromMermaid && toMermaid && dfEdge.key && dfEdge.key !== 'value') {\n        lines.push(`  ${fromMermaid} -.->|${dfEdge.key}| ${toMermaid}`);\n      }\n    }\n\n    // Highlight nodes with undefined reads\n    if (dataFlow.undefinedReads.length > 0) {\n      lines.push('');\n      lines.push('  %% Data-flow warnings');\n      lines.push('  classDef dataFlowWarning fill:#fff3cd,stroke:#856404,stroke-width:2px');\n      for (const read of dataFlow.undefinedReads) {\n        const mermaidId = irToMermaid.get(read.readerId);\n        if (mermaidId) {\n          lines.push(`  class ${mermaidId} dataFlowWarning`);\n        }\n      }\n    }\n\n    // Highlight nodes with duplicate writes\n    if (dataFlow.duplicateWrites.length > 0) {\n      lines.push('  classDef duplicateWrite fill:#f8d7da,stroke:#721c24,stroke-width:2px');\n      for (const dup of dataFlow.duplicateWrites) {\n        for (const writerId of dup.writerIds) {\n          const mermaidId = irToMermaid.get(writerId);\n          if (mermaidId) {\n            lines.push(`  class ${mermaidId} duplicateWrite`);\n          }\n        }\n      }\n    }\n  }\n\n  // Error-flow overlay: annotate nodes with error types and highlight unhandled errors\n  if (options?.errorFlowOverlay) {\n    const errorFlow = analyzeErrorFlow(ir);\n    const errorPropagation = analyzeErrorPropagation(ir);\n    const irToMermaid = context.nodeIdMap;\n\n    lines.push('');\n    lines.push('  %% Error-flow overlay');\n    lines.push('  classDef canFail fill:#FFECB3,stroke:#F57F17,stroke-width:2px');\n    lines.push('  classDef unhandledError fill:#FFCDD2,stroke:#C62828,stroke-width:3px');\n\n    // Tag nodes that can fail\n    for (const stepError of errorFlow.stepErrors) {\n      if (stepError.errors.length > 0) {\n        const mermaidId = irToMermaid.get(stepError.stepId);\n        if (mermaidId) {\n          lines.push(`  class ${mermaidId} canFail`);\n        }\n      }\n    }\n\n    // Tag nodes with unhandled error propagation (errors that reach the top without a handler)\n    for (const prop of errorPropagation.propagation) {\n      if (prop.possibleErrors.length > 0 && !prop.narrowedBy) {\n        const mermaidId = irToMermaid.get(prop.atNode);\n        if (mermaidId) {\n          lines.push(`  class ${mermaidId} unhandledError`);\n        }\n      }\n    }\n\n    // Annotate error-handler edges with narrowing info\n    for (const prop of errorPropagation.propagation) {\n      if (prop.narrowedBy && prop.narrowedBy.removedErrors.length > 0) {\n        const handlerMermaid = irToMermaid.get(prop.narrowedBy.handler);\n        const nodeMermaid = irToMermaid.get(prop.atNode);\n        if (handlerMermaid && nodeMermaid) {\n          const narrowed = prop.narrowedBy.removedErrors.join(', ');\n          lines.push(`  ${nodeMermaid} -.->|catches ${narrowed}| ${handlerMermaid}`);\n        }\n      }\n    }\n  }\n\n  return { lines, context };\n}\n\n// =============================================================================\n// Node rendering (sequential flow: firstNodeId, lastNodeIds)\n// =============================================================================\n\nfunction renderNodes(\n  nodes: readonly StaticFlowNode[],\n  context: RenderContext,\n  lines: string[],\n  depth = 0,\n): RenderResult {\n  if (nodes.length === 0) {\n    return { firstNodeId: null, lastNodeIds: [] };\n  }\n\n  let firstNodeId: string | null = null;\n  let prevLastNodeIds: string[] = [];\n\n  for (const node of nodes) {\n    const result = renderNode(node, context, lines, depth);\n    if (firstNodeId === null && result.firstNodeId) {\n      firstNodeId = result.firstNodeId;\n    }\n    if (result.firstNodeId) {\n      for (const prevId of prevLastNodeIds) {\n        context.edges.push({ from: prevId, to: result.firstNodeId });\n      }\n    }\n    prevLastNodeIds = result.lastNodeIds;\n  }\n\n  return { firstNodeId, lastNodeIds: prevLastNodeIds };\n}\n\nfunction getNodeId(node: StaticFlowNode, context: RenderContext): string {\n  const id =\n    context.opts.includeIds && 'id' in node\n      ? node.id\n      : `n${String(++context.nodeCounter)}`;\n  return sanitizeId(id);\n}\n\nfunction getNodeLabel(\n  node: StaticFlowNode,\n  opts: RenderContext['opts'],\n  annotations?: string[],\n): string {\n  if (!opts.includeDescriptions) {\n    return node.type;\n  }\n\n  // Base label (compact mode)\n  let label: string;\n  switch (node.type) {\n    case 'effect':\n      label = truncateDisplayText(node.callee || 'Effect', DEFAULT_LABEL_MAX);\n      break;\n    case 'generator':\n      label = `Generator (${node.yields.length} yields)`;\n      break;\n    case 'pipe':\n      label = `Pipe (${node.transformations.length + 1} steps)`;\n      break;\n    case 'parallel':\n      label = truncateDisplayText(\n        `${node.callee} (${node.children.length} effects)`,\n        DEFAULT_LABEL_MAX,\n      );\n      break;\n    case 'race':\n      label = truncateDisplayText(\n        `${node.callee} (${node.children.length} racing)`,\n        DEFAULT_LABEL_MAX,\n      );\n      break;\n    case 'error-handler':\n      label = node.handlerType;\n      break;\n    case 'retry':\n      label = `Retry${node.schedule ? `(${node.schedule})` : ''}`;\n      break;\n    case 'timeout':\n      label = `Timeout${node.duration ? `(${node.duration})` : ''}`;\n      break;\n    case 'resource':\n      label = 'Resource';\n      break;\n    case 'conditional':\n      label = `${node.conditionalType} (${truncate(node.condition, 20)})`;\n      break;\n    case 'loop':\n      label = node.iterSource\n        ? truncateDisplayText(\n            `${node.loopType}(${node.iterSource})`,\n            DEFAULT_LABEL_MAX,\n          )\n        : node.loopType;\n      break;\n    case 'layer':\n      label = `Layer${node.isMerged ? ' (merged)' : ''}`;\n      break;\n    case 'stream':\n      label = truncateDisplayText(\n        `Stream${node.pipeline.length > 0 ? `.${node.pipeline.map((p) => p.operation).join(' → ')}` : ''}${node.sink ? ` → ${node.sink}` : ''}`,\n        DEFAULT_LABEL_MAX,\n      );\n      break;\n    case 'concurrency-primitive':\n      label = `${node.primitive}.${node.operation}${node.strategy ? ` (${node.strategy})` : ''}`;\n      break;\n    case 'fiber':\n      label = `${node.operation}${node.isDaemon ? ' (daemon)' : ''}${node.isScoped ? ' (scoped)' : ''}`;\n      break;\n    case 'decision':\n      label = node.label || truncate(node.condition, 30);\n      break;\n    case 'switch':\n      label = `Switch: ${truncate(node.expression, 25)}`;\n      break;\n    case 'try-catch':\n      label = 'Try/Catch';\n      break;\n    case 'terminal':\n      label = node.terminalKind;\n      break;\n    case 'opaque':\n      label = `⚠ ${node.reason}`;\n      break;\n    case 'cause':\n      label = `Cause: ${node.causeOp}`;\n      break;\n    case 'exit':\n      label = `Exit: ${node.exitOp}`;\n      break;\n    case 'schedule':\n      label = `Schedule: ${node.scheduleOp}`;\n      break;\n    case 'match':\n      label = `Match: ${node.matchOp}${node.matchedTags?.length ? ` (${node.matchedTags.join(', ')})` : ''}`;\n      break;\n    case 'transform':\n      label = `${node.transformType}${node.isEffectful ? ' (effectful)' : ''}`;\n      break;\n    case 'channel':\n      label = `Channel${node.pipeline.length > 0 ? `.${node.pipeline.map(p => p.operation).join(' → ')}` : ''}`;\n      break;\n    case 'sink':\n      label = `Sink${node.pipeline.length > 0 ? `.${node.pipeline.map(p => p.operation).join(' → ')}` : ''}`;\n      break;\n    case 'interruption':\n      label = node.interruptionType;\n      break;\n    case 'unknown':\n      label = `Unknown: ${node.reason}`;\n      break;\n    default: {\n      const n = node as StaticFlowNode & { type: string };\n      label = n.type ?? 'unknown';\n      break;\n    }\n  }\n\n  // Standard/Verbose: use displayName if available\n  let usedDisplayName = false;\n  if (opts.detail !== 'compact' && node.displayName) {\n    label = node.displayName;\n    usedDisplayName = true;\n  }\n\n  // Verbose: append type signature and semantic role\n  // Skip inline type signature when annotations already carry one (enhanced renderer)\n  const annotationsHaveTypeSig = annotations?.some((a) => a.startsWith('<') && a.includes(','));\n  if (opts.detail === 'verbose') {\n    if (!annotationsHaveTypeSig && node.type === 'effect' && opts.includeTypeSignatures && node.typeSignature) {\n      const sig = node.typeSignature;\n      label += `\\n<${sig.successType}, ${sig.errorType}, ${sig.requirementsType}>`;\n    }\n    if (node.semanticRole && node.semanticRole !== 'unknown' && node.semanticRole !== 'constructor') {\n      label += `\\n(${node.semanticRole})`;\n    }\n  }\n\n  if (annotations?.length) {\n    // When displayName is used, skip type signature annotations to avoid duplication\n    const filteredAnnotations = usedDisplayName\n      ? annotations.filter((a) => !a.startsWith('<') || !a.includes(','))\n      : annotations;\n    if (filteredAnnotations.length) {\n      label += '\\n' + filteredAnnotations.join('\\n');\n    }\n  }\n  return label;\n}\n\nfunction getNodeStyleClass(node: StaticFlowNode): string {\n  if (node.type === 'concurrency-primitive') return 'concurrencyPrimitiveStyle';\n  if (node.type === 'try-catch') return 'tryCatchStyle';\n  if (node.type === 'error-handler') return 'errorHandlerStyle';\n  return `${node.type}Style`;\n}\n\nfunction renderNode(\n  node: StaticFlowNode,\n  context: RenderContext,\n  lines: string[],\n  depth = 0,\n): RenderResult {\n  const nodeId = getNodeId(node, context);\n  const annotations = context.nodeLabelAnnotations?.get(node.id);\n  const label = getNodeLabel(node, context.opts, annotations);\n  const styleClass = getNodeStyleClass(node);\n\n  // Skip the \"Generator (N yields)\" box so the diagram shows the actual yield steps (varName <- callee, types, etc.)\n  // Skip decision nodes too — the case 'decision' block creates its own diamond-shaped node.\n  if (node.type !== 'generator' && node.type !== 'decision') {\n    lines.push(`  ${nodeId}[\"${escapeLabel(label)}\"]`);\n    context.styleClasses.set(nodeId, styleClass);\n    context.nodeIdMap.set(node.id, nodeId);\n  }\n\n  // Compact mode: at depth > 0, render compound nodes as leaf nodes (don't recurse)\n  // This prevents deeply nested structures from exploding the diagram.\n  // Leaf types (effect, unknown) always render as-is regardless of depth.\n  const compactLeafTypes = new Set(['effect', 'unknown', 'opaque', 'terminal', 'exit', 'schedule']);\n  if (context.opts.detail === 'compact' && depth > 0 && !compactLeafTypes.has(node.type)) {\n    // For generators, emit the summary node (generator skips pre-emission above)\n    if (node.type === 'generator') {\n      const summaryName = node.name || node.displayName || 'Generator';\n      const summaryLabel = `${summaryName} (${node.yields.length} steps)`;\n      lines.push(`  ${nodeId}[\"${escapeLabel(summaryLabel)}\"]`);\n      context.styleClasses.set(nodeId, styleClass);\n      context.nodeIdMap.set(node.id, nodeId);\n    }\n    // All other compound types already have their node emitted above\n    return { firstNodeId: nodeId, lastNodeIds: [nodeId] };\n  }\n\n  switch (node.type) {\n    case 'effect':\n    case 'unknown':\n      return { firstNodeId: nodeId, lastNodeIds: [nodeId] };\n\n    case 'stream': {\n      const childResult = renderNode(node.source, context, lines, depth + 1);\n      if (childResult.firstNodeId) {\n        context.edges.push({ from: nodeId, to: childResult.firstNodeId });\n      }\n      return { firstNodeId: nodeId, lastNodeIds: childResult.lastNodeIds };\n    }\n\n    case 'concurrency-primitive': {\n      if (node.source) {\n        const childResult = renderNode(node.source, context, lines, depth + 1);\n        if (childResult.firstNodeId) {\n          context.edges.push({ from: nodeId, to: childResult.firstNodeId });\n        }\n        return { firstNodeId: nodeId, lastNodeIds: childResult.lastNodeIds };\n      }\n      return { firstNodeId: nodeId, lastNodeIds: [nodeId] };\n    }\n\n    case 'fiber': {\n      if (node.fiberSource) {\n        const childResult = renderNode(node.fiberSource, context, lines, depth + 1);\n        if (childResult.firstNodeId) {\n          context.edges.push({ from: nodeId, to: childResult.firstNodeId });\n        }\n        return { firstNodeId: nodeId, lastNodeIds: childResult.lastNodeIds };\n      }\n      return { firstNodeId: nodeId, lastNodeIds: [nodeId] };\n    }\n\n    case 'generator': {\n      // Sequential: yield1 -> yield2 -> ... (no \"Generator (N yields)\" box; show each yield's name/callee/types)\n      const children = node.yields.map((y) => y.effect);\n      const result = renderNodes(children, context, lines, depth + 1);\n      if (result.firstNodeId) {\n        return {\n          firstNodeId: result.firstNodeId,\n          lastNodeIds: result.lastNodeIds.length > 0 ? result.lastNodeIds : [result.firstNodeId],\n        };\n      }\n      // Empty generator: emit a single node so edges stay valid\n      lines.push(`  ${nodeId}[\"${escapeLabel(label)}\"]`);\n      context.styleClasses.set(nodeId, styleClass);\n      context.nodeIdMap.set(node.id, nodeId);\n      return { firstNodeId: nodeId, lastNodeIds: [nodeId] };\n    }\n\n    case 'pipe': {\n      // Sequential: initial -> t1 -> t2 -> ...\n      const chain = [node.initial, ...node.transformations];\n      const result = renderNodes(chain, context, lines, depth + 1);\n      if (result.firstNodeId) {\n        context.edges.push({ from: nodeId, to: result.firstNodeId });\n      }\n      return {\n        firstNodeId: nodeId,\n        lastNodeIds: result.lastNodeIds.length > 0 ? result.lastNodeIds : [nodeId],\n      };\n    }\n\n    case 'parallel': {\n      const forkId = `parallel_fork_${++context.nodeCounter}`;\n      const joinId = `parallel_join_${context.nodeCounter}`;\n      const modeLabel = node.mode === 'parallel' ? 'Parallel' : 'All';\n      lines.push(`  ${forkId}{{\"${modeLabel} (${node.children.length})\"}}`);\n      lines.push(`  ${joinId}{{\"Join\"}}`);\n      context.styleClasses.set(forkId, 'parallelStyle');\n      context.styleClasses.set(joinId, 'parallelStyle');\n      context.edges.push({ from: nodeId, to: forkId });\n\n      for (let i = 0; i < node.children.length; i++) {\n        const child = node.children[i];\n        if (!child) continue;\n        const branchResult = renderNode(child, context, lines, depth + 1);\n        if (branchResult.firstNodeId) {\n          context.edges.push({\n            from: forkId,\n            to: branchResult.firstNodeId,\n            label: node.branchLabels?.[i] ?? `branch ${i + 1}`,\n          });\n        }\n        for (const lastId of branchResult.lastNodeIds) {\n          context.edges.push({ from: lastId, to: joinId });\n        }\n      }\n      return { firstNodeId: nodeId, lastNodeIds: [joinId] };\n    }\n\n    case 'race': {\n      const forkId = `race_fork_${++context.nodeCounter}`;\n      const joinId = `race_join_${context.nodeCounter}`;\n      lines.push(`  ${forkId}{{{\"Race (${node.children.length})\"}}}`);\n      lines.push(`  ${joinId}{{{\"Winner\"}}}`);\n      context.styleClasses.set(forkId, 'raceStyle');\n      context.styleClasses.set(joinId, 'raceStyle');\n      context.edges.push({ from: nodeId, to: forkId });\n\n      for (let i = 0; i < node.children.length; i++) {\n        const child = node.children[i];\n        if (!child) continue;\n        const branchResult = renderNode(child, context, lines, depth + 1);\n        if (branchResult.firstNodeId) {\n          context.edges.push({\n            from: forkId,\n            to: branchResult.firstNodeId,\n            label: node.raceLabels?.[i] ?? `racer ${i + 1}`,\n          });\n        }\n        for (const lastId of branchResult.lastNodeIds) {\n          context.edges.push({ from: lastId, to: joinId });\n        }\n      }\n      return { firstNodeId: nodeId, lastNodeIds: [joinId] };\n    }\n\n    case 'error-handler': {\n      const sourceResult = renderNode(node.source, context, lines, depth + 1);\n      const handlerNodeId = `err_handler_${++context.nodeCounter}`;\n      lines.push(`  ${handlerNodeId}[\"${node.handlerType}\"]`);\n      context.styleClasses.set(handlerNodeId, 'errorHandlerStyle');\n      if (sourceResult.lastNodeIds.length > 0) {\n        context.edges.push({\n          from: sourceResult.lastNodeIds[0]!,\n          to: handlerNodeId,\n          label: node.errorEdgeLabel ?? 'on error',\n        });\n      }\n      let lastIds = [handlerNodeId];\n      if (node.handler) {\n        const handlerResult = renderNode(node.handler, context, lines, depth + 1);\n        if (handlerResult.firstNodeId) {\n          context.edges.push({ from: handlerNodeId, to: handlerResult.firstNodeId });\n        }\n        lastIds = handlerResult.lastNodeIds;\n      }\n      return {\n        firstNodeId: sourceResult.firstNodeId ?? nodeId,\n        lastNodeIds: lastIds,\n      };\n    }\n\n    case 'retry':\n    case 'timeout': {\n      const sourceResult = renderNode(node.source, context, lines, depth + 1);\n      const wrapperId = `${node.type}_${++context.nodeCounter}`;\n      const label =\n        node.type === 'retry'\n          ? `Retry${node.schedule ? `(${node.schedule})` : ''}`\n          : `Timeout${node.duration ? `(${node.duration})` : ''}`;\n      lines.push(`  ${wrapperId}[\"${label}\"]`);\n      context.styleClasses.set(wrapperId, `${node.type}Style`);\n      if (sourceResult.lastNodeIds.length > 0) {\n        context.edges.push({\n          from: sourceResult.lastNodeIds[0]!,\n          to: wrapperId,\n        });\n      }\n      return {\n        firstNodeId: sourceResult.firstNodeId ?? nodeId,\n        lastNodeIds: [wrapperId],\n      };\n    }\n\n    case 'resource': {\n      const acquireResult = renderNode(node.acquire, context, lines, depth + 1);\n      const resourceId = `resource_${++context.nodeCounter}`;\n      lines.push(`  ${resourceId}[\"Resource\"]`);\n      context.styleClasses.set(resourceId, 'resourceStyle');\n      if (acquireResult.lastNodeIds.length > 0) {\n        context.edges.push({\n          from: acquireResult.lastNodeIds[0]!,\n          to: resourceId,\n        });\n      }\n      let lastIds = [resourceId];\n      if (node.use) {\n        const useResult = renderNode(node.use, context, lines, depth + 1);\n        if (useResult.firstNodeId) {\n          context.edges.push({ from: resourceId, to: useResult.firstNodeId });\n        }\n        lastIds = useResult.lastNodeIds;\n      }\n      return {\n        firstNodeId: acquireResult.firstNodeId ?? nodeId,\n        lastNodeIds: lastIds,\n      };\n    }\n\n    case 'conditional': {\n      const decisionId = `cond_${++context.nodeCounter}`;\n      const condLabel = node.conditionLabel ?? truncate(node.condition, 25);\n      lines.push(`  ${decisionId}{\"${escapeLabel(condLabel)}\"}`);\n      context.styleClasses.set(decisionId, 'conditionalStyle');\n      context.edges.push({ from: nodeId, to: decisionId });\n\n      const onTrueResult = renderNode(node.onTrue, context, lines, depth + 1);\n      if (onTrueResult.firstNodeId) {\n        context.edges.push({\n          from: decisionId,\n          to: onTrueResult.firstNodeId,\n          label: node.trueEdgeLabel ?? 'true',\n        });\n      }\n      const lastNodeIds: string[] = [...onTrueResult.lastNodeIds];\n\n      if (node.onFalse) {\n        const onFalseResult = renderNode(node.onFalse, context, lines, depth + 1);\n        if (onFalseResult.firstNodeId) {\n          context.edges.push({\n            from: decisionId,\n            to: onFalseResult.firstNodeId,\n            label: node.falseEdgeLabel ?? 'false',\n          });\n        }\n        lastNodeIds.push(...onFalseResult.lastNodeIds);\n      } else {\n        lastNodeIds.push(decisionId);\n      }\n      return { firstNodeId: nodeId, lastNodeIds };\n    }\n\n    case 'loop': {\n      const loopId = `loop_${++context.nodeCounter}`;\n      const bodyLabel = node.iterSource\n        ? truncateDisplayText(\n            `${node.loopType}(${node.iterSource})`,\n            DEFAULT_LABEL_MAX,\n          )\n        : node.loopType;\n      lines.push(`  ${loopId}([\"${escapeLabel(bodyLabel)}\"])`);\n      context.styleClasses.set(loopId, 'loopStyle');\n      context.edges.push({ from: nodeId, to: loopId });\n\n      const bodyResult = renderNode(node.body, context, lines, depth + 1);\n      if (bodyResult.firstNodeId) {\n        context.edges.push({ from: loopId, to: bodyResult.firstNodeId, label: 'iterate' });\n      }\n      for (const lastId of bodyResult.lastNodeIds) {\n        context.edges.push({ from: lastId, to: loopId, label: 'next' });\n      }\n      return { firstNodeId: nodeId, lastNodeIds: [loopId] };\n    }\n\n    case 'layer': {\n      const result = renderNodes(node.operations, context, lines, depth + 1);\n      if (result.firstNodeId) {\n        context.edges.push({ from: nodeId, to: result.firstNodeId });\n      }\n      return {\n        firstNodeId: nodeId,\n        lastNodeIds: result.lastNodeIds.length > 0 ? result.lastNodeIds : [nodeId],\n      };\n    }\n\n    case 'decision': {\n      const decisionId = `decision_${++context.nodeCounter}`;\n      const condLabel = node.label || truncate(node.condition, 25);\n      lines.push(`  ${decisionId}{\"${escapeLabel(condLabel)}\"}`);\n      context.styleClasses.set(decisionId, 'decisionStyle');\n      context.nodeIdMap.set(node.id, decisionId);\n\n      // Render true branch\n      const trueResult = renderNodes(node.onTrue, context, lines, depth + 1);\n      if (trueResult.firstNodeId) {\n        context.edges.push({ from: decisionId, to: trueResult.firstNodeId, label: 'yes' });\n      }\n      const lastNodeIds: string[] = [...trueResult.lastNodeIds];\n\n      // Render false branch\n      if (node.onFalse && node.onFalse.length > 0) {\n        const falseResult = renderNodes(node.onFalse, context, lines, depth + 1);\n        if (falseResult.firstNodeId) {\n          context.edges.push({ from: decisionId, to: falseResult.firstNodeId, label: 'no' });\n        }\n        lastNodeIds.push(...falseResult.lastNodeIds);\n      } else {\n        lastNodeIds.push(decisionId);  // no false branch → continues from decision\n      }\n      return { firstNodeId: decisionId, lastNodeIds };\n    }\n\n    case 'switch': {\n      const switchId = `switch_${++context.nodeCounter}`;\n      const switchLabel = `Switch: ${truncate(node.expression, 20)}`;\n      lines.push(`  ${switchId}{\"${escapeLabel(switchLabel)}\"}`);\n      context.styleClasses.set(switchId, 'switchStyle');\n\n      const lastNodeIds: string[] = [];\n      for (const caseItem of node.cases) {\n        const caseLabel = caseItem.labels.join(' / ');\n        const caseResult = renderNodes(caseItem.body, context, lines, depth + 1);\n        if (caseResult.firstNodeId) {\n          context.edges.push({ from: switchId, to: caseResult.firstNodeId, label: caseLabel });\n        }\n        lastNodeIds.push(...caseResult.lastNodeIds);\n      }\n\n      // If hasFallthrough, add warning annotation\n      if (node.hasFallthrough) {\n        const warnId = `switchWarn_${++context.nodeCounter}`;\n        lines.push(`  ${warnId}{{\"⚠ fallthrough\"}}`);\n        context.styleClasses.set(warnId, 'opaqueStyle');\n        context.edges.push({ from: switchId, to: warnId, label: 'note' });\n      }\n\n      if (lastNodeIds.length === 0) lastNodeIds.push(switchId);\n      return { firstNodeId: switchId, lastNodeIds };\n    }\n\n    case 'try-catch': {\n      const tryResult = renderNodes(node.tryBody, context, lines, depth + 1);\n      const allLastIds: string[] = [...tryResult.lastNodeIds];\n\n      if (node.catchBody && node.catchBody.length > 0) {\n        const catchId = `catch_${++context.nodeCounter}`;\n        const catchLabel = node.catchVariable ? `Catch(${node.catchVariable})` : 'Catch';\n        lines.push(`  ${catchId}[\"${escapeLabel(catchLabel)}\"]`);\n        context.styleClasses.set(catchId, 'tryCatchStyle');\n\n        // Edge from try body to catch\n        for (const lastId of tryResult.lastNodeIds) {\n          context.edges.push({ from: lastId, to: catchId, label: 'on error' });\n        }\n\n        const catchResult = renderNodes(node.catchBody, context, lines, depth + 1);\n        if (catchResult.firstNodeId) {\n          context.edges.push({ from: catchId, to: catchResult.firstNodeId });\n        }\n        allLastIds.push(...catchResult.lastNodeIds);\n      }\n\n      if (node.finallyBody && node.finallyBody.length > 0) {\n        const finallyResult = renderNodes(node.finallyBody, context, lines, depth + 1);\n        if (finallyResult.firstNodeId) {\n          for (const lastId of allLastIds) {\n            context.edges.push({ from: lastId, to: finallyResult.firstNodeId, label: 'finally' });\n          }\n        }\n        return {\n          firstNodeId: tryResult.firstNodeId ?? nodeId,\n          lastNodeIds: finallyResult.lastNodeIds,\n        };\n      }\n\n      return {\n        firstNodeId: tryResult.firstNodeId ?? nodeId,\n        lastNodeIds: allLastIds.length > 0 ? allLastIds : [nodeId],\n      };\n    }\n\n    case 'terminal': {\n      const termId = `term_${++context.nodeCounter}`;\n      const termLabel = node.terminalKind;\n      lines.push(`  ${termId}([\"${escapeLabel(termLabel)}\"])`);\n      context.styleClasses.set(termId, 'terminalStyle');\n\n      // Render value (e.g., return yield* effect)\n      if (node.value && node.value.length > 0) {\n        const valueResult = renderNodes(node.value, context, lines, depth + 1);\n        if (valueResult.firstNodeId) {\n          context.edges.push({ from: nodeId, to: valueResult.firstNodeId });\n        }\n        // Value flows into terminal\n        for (const lastId of valueResult.lastNodeIds) {\n          context.edges.push({ from: lastId, to: termId });\n        }\n      }\n\n      return { firstNodeId: node.value?.length ? nodeId : termId, lastNodeIds: [] };\n    }\n\n    case 'opaque': {\n      const opaqueId = `opaque_${++context.nodeCounter}`;\n      const opaqueLabel =\n        node.reason === 'callback-body' || node.reason === 'predicate'\n          ? node.sourceText\n          : `⚠ ${node.reason}`;\n      lines.push(`  ${opaqueId}{{\"${escapeLabel(opaqueLabel)}\"}}`);\n      context.styleClasses.set(opaqueId, 'opaqueStyle');\n      return { firstNodeId: opaqueId, lastNodeIds: [opaqueId] };\n    }\n\n    case 'cause': {\n      // Hexagon shape for Cause nodes\n      const causeId = `cause_${++context.nodeCounter}`;\n      lines.push(`  ${causeId}{{\"${escapeLabel(label)}\"}}`);\n      context.styleClasses.set(causeId, 'causeStyle');\n      context.nodeIdMap.set(node.id, causeId);\n\n      if (node.children && node.children.length > 0) {\n        const childResult = renderNodes([...node.children], context, lines, depth + 1);\n        if (childResult.firstNodeId) {\n          context.edges.push({ from: causeId, to: childResult.firstNodeId });\n        }\n        return { firstNodeId: causeId, lastNodeIds: childResult.lastNodeIds.length > 0 ? childResult.lastNodeIds : [causeId] };\n      }\n      return { firstNodeId: causeId, lastNodeIds: [causeId] };\n    }\n\n    case 'exit': {\n      // Stadium shape for Exit nodes\n      const exitId = `exit_${++context.nodeCounter}`;\n      lines.push(`  ${exitId}([\"${escapeLabel(label)}\"])`);\n      context.styleClasses.set(exitId, 'exitStyle');\n      context.nodeIdMap.set(node.id, exitId);\n      return { firstNodeId: exitId, lastNodeIds: [exitId] };\n    }\n\n    case 'schedule': {\n      // Parallelogram shape for Schedule nodes\n      const schedId = `schedule_${++context.nodeCounter}`;\n      lines.push(`  ${schedId}[/\"${escapeLabel(label)}\"/]`);\n      context.styleClasses.set(schedId, 'scheduleStyle');\n      context.nodeIdMap.set(node.id, schedId);\n      return { firstNodeId: schedId, lastNodeIds: [schedId] };\n    }\n\n    case 'match': {\n      // Diamond shape for Match nodes (similar to switch)\n      const matchId = `match_${++context.nodeCounter}`;\n      lines.push(`  ${matchId}{\"${escapeLabel(label)}\"}`);\n      context.styleClasses.set(matchId, 'matchStyle');\n      context.nodeIdMap.set(node.id, matchId);\n\n      if (node.matchedTags && node.matchedTags.length > 0) {\n        // Render a branch per matched tag (similar to switch cases)\n        const lastNodeIds: string[] = [];\n        for (const tag of node.matchedTags) {\n          const tagNodeId = `match_tag_${++context.nodeCounter}`;\n          lines.push(`  ${tagNodeId}[\"${escapeLabel(tag)}\"]`);\n          context.styleClasses.set(tagNodeId, 'matchStyle');\n          context.edges.push({ from: matchId, to: tagNodeId, label: tag });\n          lastNodeIds.push(tagNodeId);\n        }\n        if (lastNodeIds.length === 0) lastNodeIds.push(matchId);\n        return { firstNodeId: matchId, lastNodeIds };\n      }\n      return { firstNodeId: matchId, lastNodeIds: [matchId] };\n    }\n\n    case 'transform': {\n      // Rectangle for Transform nodes — recurse into source child\n      if (node.source) {\n        const sourceResult = renderNode(node.source, context, lines, depth + 1);\n        if (sourceResult.lastNodeIds.length > 0) {\n          context.edges.push({ from: sourceResult.lastNodeIds[0]!, to: nodeId });\n        }\n        return { firstNodeId: sourceResult.firstNodeId ?? nodeId, lastNodeIds: [nodeId] };\n      }\n      return { firstNodeId: nodeId, lastNodeIds: [nodeId] };\n    }\n\n    case 'channel': {\n      // Subroutine shape for Channel nodes\n      const chanId = `channel_${++context.nodeCounter}`;\n      lines.push(`  ${chanId}[[\"${escapeLabel(label)}\"]]`);\n      context.styleClasses.set(chanId, 'channelStyle');\n      context.nodeIdMap.set(node.id, chanId);\n\n      if (node.source) {\n        const sourceResult = renderNode(node.source, context, lines, depth + 1);\n        if (sourceResult.lastNodeIds.length > 0) {\n          context.edges.push({ from: sourceResult.lastNodeIds[0]!, to: chanId });\n        }\n        return { firstNodeId: sourceResult.firstNodeId ?? chanId, lastNodeIds: [chanId] };\n      }\n      return { firstNodeId: chanId, lastNodeIds: [chanId] };\n    }\n\n    case 'sink': {\n      // Cylindrical shape for Sink nodes\n      const sinkId = `sink_${++context.nodeCounter}`;\n      lines.push(`  ${sinkId}[(\"${escapeLabel(label)}\")]`);\n      context.styleClasses.set(sinkId, 'sinkStyle');\n      context.nodeIdMap.set(node.id, sinkId);\n\n      if (node.source) {\n        const sourceResult = renderNode(node.source, context, lines, depth + 1);\n        if (sourceResult.lastNodeIds.length > 0) {\n          context.edges.push({ from: sourceResult.lastNodeIds[0]!, to: sinkId });\n        }\n        return { firstNodeId: sourceResult.firstNodeId ?? sinkId, lastNodeIds: [sinkId] };\n      }\n      return { firstNodeId: sinkId, lastNodeIds: [sinkId] };\n    }\n\n    case 'interruption': {\n      // Hexagon shape for Interruption nodes\n      const intId = `interruption_${++context.nodeCounter}`;\n      lines.push(`  ${intId}{{\"${escapeLabel(label)}\"}}`);\n      context.styleClasses.set(intId, 'interruptionStyle');\n      context.nodeIdMap.set(node.id, intId);\n\n      if (node.source) {\n        const sourceResult = renderNode(node.source, context, lines, depth + 1);\n        if (sourceResult.firstNodeId) {\n          context.edges.push({ from: intId, to: sourceResult.firstNodeId });\n        }\n        const lastIds = [...sourceResult.lastNodeIds];\n\n        if (node.handler) {\n          const handlerResult = renderNode(node.handler, context, lines, depth + 1);\n          if (sourceResult.lastNodeIds.length > 0 && handlerResult.firstNodeId) {\n            context.edges.push({ from: sourceResult.lastNodeIds[0]!, to: handlerResult.firstNodeId, label: 'on interrupt' });\n          }\n          lastIds.push(...handlerResult.lastNodeIds);\n        }\n        return { firstNodeId: intId, lastNodeIds: lastIds.length > 0 ? lastIds : [intId] };\n      }\n      return { firstNodeId: intId, lastNodeIds: [intId] };\n    }\n\n    default:\n      return { firstNodeId: nodeId, lastNodeIds: [nodeId] };\n  }\n}\n\n// =============================================================================\n// Public API: static Mermaid (sync) and renderMermaid (Effect)\n// =============================================================================\n\n/**\n * Generate a Mermaid flowchart from static Effect IR (sync).\n * Includes Start/End nodes, optional subgraphs, sequential flow.\n */\nexport function renderStaticMermaid(\n  ir: StaticEffectIR,\n  options?: Partial<MermaidOptions>,\n): string {\n  const { lines } = renderStaticMermaidInternal(ir, options);\n  return lines.join('\\n');\n}\n\nconst TRACE_STYLES: Record<RuntimeSpanStatus, string> = {\n  running: 'fill:#422006,stroke:#eab308,stroke-width:3px,color:#fef9c3',\n  success: 'fill:#052e16,stroke:#22c55e,stroke-width:3px,color:#dcfce7',\n  error: 'fill:#450a0a,stroke:#ef4444,stroke-width:3px,color:#fee2e2',\n};\n\nexport interface RuntimeOverlayResult {\n  readonly mermaid: string;\n  /** Span path matched a static node exactly, root segment included. */\n  readonly matchedSpanIds: readonly string[];\n  /**\n   * Span matched only after dropping leading path segments. Weaker evidence\n   * than an exact match, so it is reported apart from one.\n   */\n  readonly suffixMatchedSpanIds: readonly string[];\n  readonly unmatchedSpanIds: readonly string[];\n  readonly ambiguousSpanIds: readonly string[];\n}\n\n/** Render the full static program with one Effect v4 span trace overlaid. */\nexport function renderMermaidWithRuntimeTrace(\n  ir: StaticEffectIR,\n  trace: RuntimeTrace,\n  options?: Partial<MermaidOptions>,\n): RuntimeOverlayResult {\n  const { lines, context } = renderStaticMermaidInternal(ir, options);\n  const irIndex = indexIR(ir);\n  const matchedSpanIds: string[] = [];\n  const suffixMatchedSpanIds: string[] = [];\n  const unmatchedSpanIds: string[] = [];\n  const ambiguousSpanIds: string[] = [];\n  const usedStatuses = new Set<RuntimeSpanStatus>();\n  const assignments: string[] = [];\n\n  for (const span of trace.spans) {\n    // The IR of one program cannot contain spans opened above it — an HTTP\n    // handler, a job runner, the caller's own `withSpan` — but a real trace\n    // always carries them. Try the full path first, then progressively shorter\n    // suffixes, so an outer ancestor does not lose every span beneath it.\n    let staticIds: readonly string[] = [];\n    let exact = false;\n    for (let start = 0; start < span.path.length; start++) {\n      const ids = irIndex.idsBySpanPath.get(spanPathKey(span.path.slice(start)));\n      if (!ids || ids.length === 0) continue;\n      staticIds = ids;\n      exact = start === 0;\n      break;\n    }\n    if (staticIds.length === 0) {\n      unmatchedSpanIds.push(span.spanId);\n      continue;\n    }\n    if (staticIds.length > 1) {\n      ambiguousSpanIds.push(span.spanId);\n      continue;\n    }\n    const staticId = staticIds[0];\n    const mermaidId = staticId ? context.nodeIdMap.get(staticId) : undefined;\n    if (!mermaidId) {\n      unmatchedSpanIds.push(span.spanId);\n      continue;\n    }\n    (exact ? matchedSpanIds : suffixMatchedSpanIds).push(span.spanId);\n    usedStatuses.add(span.status);\n    assignments.push(`  class ${mermaidId} trace_${span.status}`);\n  }\n\n  if (assignments.length > 0) {\n    lines.push('', '  %% Runtime span overlay');\n    for (const status of usedStatuses) {\n      lines.push(`  classDef trace_${status} ${TRACE_STYLES[status]}`);\n    }\n    lines.push(...assignments);\n  }\n\n  return {\n    mermaid: lines.join('\\n'),\n    matchedSpanIds,\n    suffixMatchedSpanIds,\n    unmatchedSpanIds,\n    ambiguousSpanIds,\n  };\n}\n\n/**\n * Render Effect IR as Mermaid flowchart (Effect).\n * Same as renderStaticMermaid but returns Effect.Effect<string>.\n */\nexport const renderMermaid = (\n  ir: StaticEffectIR,\n  options?: Partial<MermaidOptions>,\n): Effect.Effect<string> =>\n  Effect.sync(() => renderStaticMermaid(ir, options));\n\n// =============================================================================\n// Path-based Mermaid\n// =============================================================================\n\nexport interface PathsMermaidOptions {\n  direction?: 'TB' | 'LR' | 'BT' | 'RL';\n  /** Collapse consecutive log-like steps into one summary node (default: true). */\n  collapseRepeatedLogs?: boolean;\n  /** Collapse consecutive pure-transform-like steps into one summary node (default: true). */\n  collapsePureTransforms?: boolean;\n  /** Collapse consecutive environment-acquisition-like steps (default: false, true in style-guide mode). */\n  collapseEnvironmentRuns?: boolean;\n  /** Apply summary-only readability heuristics (environment grouping + service boundary prefixes). */\n  styleGuide?: boolean;\n  /** Prefix the first service-like calls with \"svc:\" (default: false, true in style-guide mode). */\n  prefixServiceBoundaries?: boolean;\n}\n\nexport interface DisplayPathStep {\n  key: string;\n  name: string;\n}\n\nexport interface PathSummaryResult {\n  steps: readonly DisplayPathStep[];\n  collapsedGroups: number;\n}\n\nfunction isLogLikeStep(name: string): boolean {\n  const n = name.toLowerCase();\n  return (\n    n.includes('log') ||\n    n.includes('loginfo') ||\n    n.includes('logdebug') ||\n    n.includes('logwarning') ||\n    n.includes('logerror') ||\n    n.includes('taperror')\n  );\n}\n\nfunction isPureTransformLikeStep(name: string): boolean {\n  const n = name.toLowerCase();\n  return (\n    n.includes('map') ||\n    n.includes('flatmap') ||\n    n.includes('filter') ||\n    n.includes('transform') ||\n    n.includes('tap(') ||\n    n === 'tap' ||\n    n.includes('annotate') ||\n    n.includes('hsep') ||\n    n.includes('ansidoc.text')\n  );\n}\n\nfunction isEnvironmentLikeStep(name: string): boolean {\n  const n = name.trim();\n  if (/\\(environment\\)/i.test(n)) return true;\n  if (/^[A-Z][A-Za-z0-9_]+$/.test(n)) return true;\n  if (/^(Context\\.Tag|GenericTag|Effect\\.serviceOption|Effect\\.service)\\b/.test(n)) return true;\n  return false;\n}\n\nfunction isServiceBoundaryLikeStep(name: string): boolean {\n  const n = name.trim();\n  if (!/^[A-Za-z_$][\\w$]*\\.[A-Za-z_$][\\w$]*/.test(n)) return false;\n  const builtinPrefixes = [\n    'Effect.',\n    'Layer.',\n    'Stream.',\n    'Schema.',\n    'Schedule.',\n    'Option.',\n    'Either.',\n    'Duration.',\n    'Console.',\n    'Array.',\n    'String.',\n    'Number.',\n    'Boolean.',\n    'Math.',\n    'Object.',\n    'JSON.',\n    'Promise.',\n    'Date.',\n  ];\n  return !builtinPrefixes.some((prefix) => n.startsWith(prefix));\n}\n\nfunction applyServiceBoundaryPrefixes(\n  steps: readonly DisplayPathStep[],\n  options: PathsMermaidOptions,\n): DisplayPathStep[] {\n  const usePrefix = options.prefixServiceBoundaries ?? options.styleGuide ?? false;\n  if (!usePrefix) return [...steps];\n  const out = [...steps];\n  let prefixed = 0;\n  for (let i = 0; i < out.length; i++) {\n    if (prefixed >= 2) break;\n    const step = out[i];\n    if (!step) continue;\n    if (isServiceBoundaryLikeStep(step.name) && !step.name.startsWith('svc: ')) {\n      out[i] = { ...step, name: `svc: ${step.name}` };\n      prefixed++;\n    }\n  }\n  return out;\n}\n\nexport function summarizePathSteps(\n  path: EffectPath,\n  options: PathsMermaidOptions,\n): PathSummaryResult {\n  const collapseLogs = options.collapseRepeatedLogs ?? true;\n  const collapseTransforms = options.collapsePureTransforms ?? true;\n  const collapseEnvironment = options.collapseEnvironmentRuns ?? options.styleGuide ?? false;\n\n  const out: DisplayPathStep[] = [];\n  let collapsedGroups = 0;\n  let i = 0;\n  while (i < path.steps.length) {\n    const current = path.steps[i];\n    if (!current) break;\n    const currentName = current.name ?? current.nodeId;\n\n    if (collapseLogs && isLogLikeStep(currentName)) {\n      let j = i + 1;\n      while (j < path.steps.length) {\n        const next = path.steps[j];\n        if (!next) break;\n        const nextName = next.name ?? next.nodeId;\n        if (!isLogLikeStep(nextName)) break;\n        j++;\n      }\n      const count = j - i;\n      if (count > 1) {\n        out.push({\n          key: `${path.id}:logs:${i}`,\n          name: `log steps ×${String(count)}`,\n        });\n        collapsedGroups++;\n        i = j;\n        continue;\n      }\n    }\n\n    if (collapseTransforms && isPureTransformLikeStep(currentName)) {\n      let j = i + 1;\n      while (j < path.steps.length) {\n        const next = path.steps[j];\n        if (!next) break;\n        const nextName = next.name ?? next.nodeId;\n        if (!isPureTransformLikeStep(nextName)) break;\n        j++;\n      }\n      const count = j - i;\n      if (count > 1) {\n        out.push({\n          key: `${path.id}:transforms:${i}`,\n          name: `transform steps ×${String(count)}`,\n        });\n        collapsedGroups++;\n        i = j;\n        continue;\n      }\n    }\n\n    if (collapseEnvironment && isEnvironmentLikeStep(currentName)) {\n      let j = i + 1;\n      while (j < path.steps.length) {\n        const next = path.steps[j];\n        if (!next) break;\n        const nextName = next.name ?? next.nodeId;\n        if (!isEnvironmentLikeStep(nextName)) break;\n        j++;\n      }\n      const count = j - i;\n      if (count > 1) {\n        out.push({\n          key: `${path.id}:env:${i}`,\n          name: `environment ×${String(count)}`,\n        });\n        collapsedGroups++;\n        i = j;\n        continue;\n      }\n    }\n\n    out.push({ key: current.nodeId, name: currentName });\n    i++;\n  }\n\n  return {\n    steps: applyServiceBoundaryPrefixes(out, options),\n    collapsedGroups,\n  };\n}\n\n/**\n * Generate a simplified Mermaid diagram from execution paths.\n * Start -> step1 -> step2 -> ... -> End; nodes merged by nodeId.\n */\nexport function renderPathsMermaid(\n  paths: readonly EffectPath[],\n  options: PathsMermaidOptions = {},\n): string {\n  const direction = options.direction ?? 'TB';\n  const lines: string[] = [];\n\n  lines.push(`flowchart ${direction}`);\n  lines.push('');\n\n  const stepNodes = new Map<string, { id: string; name: string }>();\n  let nodeCounter = 0;\n\n  const displayPaths = paths.map((path) => summarizePathSteps(path, options).steps);\n\n  for (const displayPath of displayPaths) {\n    for (const step of displayPath) {\n      const key = step.key;\n      if (!stepNodes.has(key)) {\n        stepNodes.set(key, {\n          id: `step_${++nodeCounter}`,\n          name: step.name,\n        });\n      }\n    }\n  }\n\n  lines.push('  start((Start))');\n  lines.push('  end_node((End))');\n  lines.push('');\n\n  for (const [, stepInfo] of stepNodes) {\n    lines.push(`  ${stepInfo.id}[\"${escapeLabel(stepInfo.name)}\"]`);\n  }\n  lines.push('');\n\n  const edges = new Set<string>();\n  for (const displayPath of displayPaths) {\n    if (displayPath.length === 0) continue;\n    const firstStep = displayPath[0]!;\n    const firstInfo = stepNodes.get(firstStep.key)!;\n    edges.add(`start --> ${firstInfo.id}`);\n    for (let i = 0; i < displayPath.length - 1; i++) {\n      const cur = displayPath[i]!;\n      const next = displayPath[i + 1]!;\n      const curInfo = stepNodes.get(cur.key)!;\n      const nextInfo = stepNodes.get(next.key)!;\n      edges.add(`${curInfo.id} --> ${nextInfo.id}`);\n    }\n    const lastStep = displayPath[displayPath.length - 1]!;\n    const lastInfo = stepNodes.get(lastStep.key)!;\n    edges.add(`${lastInfo.id} --> end_node`);\n  }\n\n  lines.push('  %% Edges');\n  for (const edge of edges) {\n    lines.push(`  ${edge}`);\n  }\n\n  return lines.join('\\n');\n}\n\n// =============================================================================\n// Enhanced Mermaid (types / errors overlay)\n// =============================================================================\n\nexport interface EnhancedMermaidOptions extends Partial<MermaidOptions> {\n  showTypeSignatures?: boolean;\n  showRequiredServices?: boolean;\n  showErrorNodes?: boolean;\n}\n\nconst DEFAULT_ENHANCED_OPTIONS: EnhancedMermaidOptions = {\n  ...DEFAULT_OPTIONS,\n  showTypeSignatures: true,\n  showRequiredServices: true,\n  showErrorNodes: false,\n};\n\n/**\n * Collect type and service annotations from IR for overlay.\n */\nfunction collectEnhancedAnnotations(\n  ir: StaticEffectIR,\n  opts: EnhancedMermaidOptions,\n): Map<string, string[]> {\n  const map = new Map<string, string[]>();\n  const showTypes = opts.showTypeSignatures !== false;\n  const showServices = opts.showRequiredServices === true;\n\n  function visit(node: StaticFlowNode): void {\n    if (node.type === 'effect') {\n      const annotations: string[] = [];\n      if (showTypes && node.typeSignature) {\n        annotations.push(\n          `<${node.typeSignature.successType}, ${node.typeSignature.errorType}, ${node.typeSignature.requirementsType}>`,\n        );\n      }\n      if (showServices && node.requiredServices && node.requiredServices.length > 0) {\n        const services = node.requiredServices.map((s) => s.serviceId).join(', ');\n        annotations.push(`R: ${services}`);\n      }\n      if (annotations.length > 0) {\n        map.set(node.id, annotations);\n      }\n    }\n    switch (node.type) {\n      case 'generator':\n        for (const y of node.yields) {\n          visit(y.effect);\n        }\n        break;\n      case 'pipe':\n        visit(node.initial);\n        for (const t of node.transformations) {\n          visit(t);\n        }\n        break;\n      case 'parallel':\n      case 'race':\n        for (const c of node.children) {\n          visit(c);\n        }\n        break;\n      case 'error-handler':\n        visit(node.source);\n        if (node.handler) visit(node.handler);\n        break;\n      case 'retry':\n      case 'timeout':\n        visit(node.source);\n        break;\n      case 'resource':\n        visit(node.acquire);\n        visit(node.release);\n        if (node.use) visit(node.use);\n        break;\n      case 'conditional':\n        visit(node.onTrue);\n        if (node.onFalse) visit(node.onFalse);\n        break;\n      case 'loop':\n        visit(node.body);\n        break;\n      case 'layer':\n        for (const op of node.operations) {\n          visit(op);\n        }\n        break;\n      case 'decision':\n        for (const child of node.onTrue) visit(child);\n        if (node.onFalse) {\n          for (const child of node.onFalse) visit(child);\n        }\n        break;\n      case 'switch':\n        for (const caseItem of node.cases) {\n          for (const child of caseItem.body) visit(child);\n        }\n        break;\n      case 'try-catch':\n        for (const child of node.tryBody) visit(child);\n        if (node.catchBody) {\n          for (const child of node.catchBody) visit(child);\n        }\n        if (node.finallyBody) {\n          for (const child of node.finallyBody) visit(child);\n        }\n        break;\n      case 'terminal':\n        if (node.value) {\n          for (const child of node.value) visit(child);\n        }\n        break;\n      case 'opaque':\n        break;\n      default:\n        break;\n    }\n  }\n\n  for (const child of ir.root.children) {\n    visit(child);\n  }\n  return map;\n}\n\n/**\n * Generate enhanced Mermaid with type signatures and/or required services on nodes.\n */\nexport function renderEnhancedMermaid(\n  ir: StaticEffectIR,\n  options?: EnhancedMermaidOptions,\n): string {\n  const enhancedOpts = { ...DEFAULT_ENHANCED_OPTIONS, ...options };\n  const nodeLabelAnnotations = collectEnhancedAnnotations(ir, enhancedOpts);\n  // Pass original options' detail (if any) so auto-selection can kick in\n  const mermaidOpts: Partial<MermaidOptions> = { ...enhancedOpts };\n  if (!options?.detail) delete (mermaidOpts as Record<string, unknown>).detail;\n  const { lines } = renderStaticMermaidInternal(\n    ir,\n    mermaidOpts,\n    nodeLabelAnnotations,\n  );\n  return lines.join('\\n');\n}\n\n/**\n * Render enhanced Mermaid as Effect.\n */\nexport const renderEnhancedMermaidEffect = (\n  ir: StaticEffectIR,\n  options?: EnhancedMermaidOptions,\n): Effect.Effect<string> =>\n  Effect.sync(() => renderEnhancedMermaid(ir, options));\n\n// =============================================================================\n// Enhanced diagram types (GAP 21)\n// =============================================================================\n\nfunction collectFiberNodes(\n  nodes: readonly StaticFlowNode[],\n  result: StaticFiberNode[],\n): void {\n  for (const node of nodes) {\n    if (node.type === 'fiber') {\n      result.push(node);\n    }\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) collectFiberNodes(children, result);\n  }\n}\n\n/**\n * Generate a Mermaid sequence diagram for fiber fork/join (GAP 21).\n */\nexport function renderSequenceMermaid(ir: StaticEffectIR): string {\n  const fibers: StaticFiberNode[] = [];\n  collectFiberNodes(ir.root.children, fibers);\n  const forks = fibers.filter(\n    (f) => f.operation === 'fork' || f.operation === 'forkScoped' || f.operation === 'forkDaemon',\n  );\n  const joins = fibers.filter((f) => f.operation === 'join' || f.operation === 'await');\n  if (forks.length === 0 && joins.length === 0) {\n    return 'sequenceDiagram\\n  participant Main\\n  note over Main: No fiber operations detected';\n  }\n  const lines: string[] = ['sequenceDiagram', '  participant Main'];\n  forks.forEach((_f, i) => {\n    lines.push(`  participant Fiber${i + 1}`);\n  });\n  lines.push('');\n  forks.forEach((f, i) => {\n    const raw = f.fiberSource\n      ? (f.fiberSource as StaticEffectNode).callee ?? 'effect'\n      : 'effect';\n    const label = truncateDisplayText(raw, DEFAULT_LABEL_MAX);\n    lines.push(`  Main->>Fiber${i + 1}: fork(${label})`);\n  });\n  joins.forEach((_, i) => {\n    const fid = Math.min(i + 1, forks.length);\n    lines.push(`  Fiber${fid}-->>Main: join`);\n  });\n  return lines.join('\\n');\n}\n\nfunction collectRetryNodes(\n  nodes: readonly StaticFlowNode[],\n  result: StaticRetryNode[],\n): void {\n  for (const node of nodes) {\n    if (node.type === 'retry') {\n      result.push(node);\n    }\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) collectRetryNodes(children, result);\n  }\n}\n\n/**\n * Generate a Mermaid Gantt diagram for retry schedules (GAP 21).\n */\nexport function renderRetryGanttMermaid(ir: StaticEffectIR): string {\n  const retries: StaticRetryNode[] = [];\n  collectRetryNodes(ir.root.children, retries);\n  const withSchedule = retries.filter((r) => r.scheduleInfo);\n  if (withSchedule.length === 0) {\n    return 'gantt\\n  title Retry Schedule\\n  section Retries\\n  No retry schedules detected';\n  }\n  const lines: string[] = ['gantt', '  title Retry Schedule', '  section Attempts'];\n  withSchedule.forEach((r, idx) => {\n    const info = r.scheduleInfo!;\n    const max =\n      info.maxRetries === 'unlimited'\n        ? 5\n        : Math.min(\n            typeof info.maxRetries === 'string'\n              ? Number(info.maxRetries)\n              : (info.maxRetries ?? 3),\n            5,\n          );\n    for (let i = 0; i < max; i++) {\n      lines.push(`  Attempt ${i + 1}: a${idx}_${i}, ${i === 0 ? '0' : `after a${idx}_${i - 1}`}, 100ms`);\n      if (i < max - 1) {\n        lines.push(`  Wait: w${idx}_${i}, after a${idx}_${i}, 200ms`);\n      }\n    }\n  });\n  return lines.join('\\n');\n}\n\n// =============================================================================\n// Service Graph Mermaid\n// =============================================================================\n\n/**\n * Render a project-level service dependency graph as a Mermaid flowchart.\n * Services are hexagon-shaped nodes, with edges showing layer requirements.\n */\nexport function renderServiceGraphMermaid(\n  serviceMap: ProjectServiceMap,\n  options: { direction?: 'TB' | 'LR' | 'BT' | 'RL' } = {},\n): string {\n  const direction = options.direction ?? 'TB';\n  const sgLines: string[] = [];\n  const sanitize = (s: string) => s.replace(/[^a-zA-Z0-9_]/g, '_');\n\n  sgLines.push(`flowchart ${direction}`);\n  sgLines.push('');\n  sgLines.push('  %% Service Dependency Graph');\n  sgLines.push('');\n\n  // Service nodes (hexagon shape)\n  for (const [serviceId, artifact] of serviceMap.services) {\n    const id = sanitize(serviceId);\n    const methodCount = artifact.definition.methods.length;\n    const label = methodCount > 0\n      ? `${serviceId}\\\\n(${methodCount} method${methodCount === 1 ? '' : 's'})`\n      : serviceId;\n    sgLines.push(`  ${id}{{{\"${label}\"}}}`);\n  }\n\n  // Unresolved services (dashed)\n  for (const serviceId of serviceMap.unresolvedServices) {\n    const id = `unresolved_${sanitize(serviceId)}`;\n    sgLines.push(`  ${id}[\"? ${serviceId}\"]`);\n  }\n  sgLines.push('');\n\n  // Edges: service requires other services (via layers)\n  const edgesAdded = new Set<string>();\n  for (const [serviceId, artifact] of serviceMap.services) {\n    for (const layer of artifact.layerImplementations) {\n      for (const req of layer.requires) {\n        const edgeKey = `${serviceId}->${req}`;\n        if (edgesAdded.has(edgeKey)) continue;\n        edgesAdded.add(edgeKey);\n\n        const fromId = sanitize(serviceId);\n        const toId = serviceMap.services.has(req)\n          ? sanitize(req)\n          : `unresolved_${sanitize(req)}`;\n        sgLines.push(`  ${fromId} -->|\"${layer.name}\"| ${toId}`);\n      }\n    }\n  }\n  sgLines.push('');\n\n  // Styling\n  sgLines.push('  classDef service fill:#E3F2FD,stroke:#1565C0,stroke-width:2px');\n  sgLines.push('  classDef unresolved fill:#FFF3CD,stroke:#856404,stroke-dasharray:5');\n  for (const serviceId of serviceMap.services.keys()) {\n    sgLines.push(`  class ${sanitize(serviceId)} service`);\n  }\n  for (const serviceId of serviceMap.unresolvedServices) {\n    sgLines.push(`  class unresolved_${sanitize(serviceId)} unresolved`);\n  }\n\n  return sgLines.join('\\n');\n}\n","/**\n * Data Flow Analysis for Effect IR\n *\n * Builds a graph of value and service dependencies between effect nodes:\n * - Value flow: sequential edges from one effect to the next in execution order\n * - Service reads: effect nodes that require services from Context\n */\n\nimport type { StaticEffectIR, StaticFlowNode, StaticEffectNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface DataFlowNode {\n  id: string;\n  name?: string | undefined;\n  /** Success type this effect produces (writes) */\n  writes?: string | undefined;\n  /** Service IDs this effect reads from Context */\n  reads: string[];\n  location?: { line: number; column: number } | undefined;\n}\n\nexport interface DataFlowEdge {\n  from: string;\n  to: string;\n  key: string;\n}\n\nexport interface DataFlowGraph {\n  nodes: DataFlowNode[];\n  edges: DataFlowEdge[];\n  producedKeys: Set<string>;\n  undefinedReads: UndefinedRead[];\n  duplicateWrites: DuplicateWrite[];\n}\n\nexport interface UndefinedRead {\n  key: string;\n  readerId: string;\n  readerName?: string | undefined;\n}\n\nexport interface DuplicateWrite {\n  key: string;\n  writerIds: string[];\n}\n\n// =============================================================================\n// Execution-order collection (effect nodes only, sequential flow)\n// =============================================================================\n\nfunction collectEffectNodesInOrder(\n  nodes: readonly StaticFlowNode[],\n  result: StaticEffectNode[],\n): void {\n  for (const node of nodes) {\n    if (node.type === 'effect') {\n      result.push(node);\n    }\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) {\n      collectEffectNodesInOrder(children, result);\n    }\n  }\n}\n\n// =============================================================================\n// Graph Building\n// =============================================================================\n\nexport function buildDataFlowGraph(ir: StaticEffectIR): DataFlowGraph {\n  const nodes: DataFlowNode[] = [];\n  const edges: DataFlowEdge[] = [];\n  const producedKeys = new Set<string>();\n  const keyProducers = new Map<string, string[]>();\n  const effectNodesOrdered: StaticEffectNode[] = [];\n\n  collectEffectNodesInOrder(ir.root.children, effectNodesOrdered);\n\n  for (const eff of effectNodesOrdered) {\n    const writes = eff.typeSignature?.successType;\n    const reads = (eff.requiredServices ?? []).map((s) => s.serviceId);\n\n    if (writes) {\n      producedKeys.add(writes);\n      const producers = keyProducers.get(writes) ?? [];\n      producers.push(eff.id);\n      keyProducers.set(writes, producers);\n    }\n\n    nodes.push({\n      id: eff.id,\n      name: eff.callee,\n      writes,\n      reads,\n      location: eff.location\n        ? { line: eff.location.line, column: eff.location.column }\n        : undefined,\n    });\n  }\n\n  // Value-flow edges: consecutive effects in order\n  for (let i = 0; i < effectNodesOrdered.length - 1; i++) {\n    const from = effectNodesOrdered[i];\n    const to = effectNodesOrdered[i + 1];\n    if (from === undefined || to === undefined) continue;\n    const key = from.typeSignature?.successType ?? 'value';\n    edges.push({ from: from.id, to: to.id, key });\n  }\n\n  // Context -> effect for each required service (virtual \"context\" source)\n  const contextId = '__context__';\n  for (const node of nodes) {\n    for (const key of node.reads) {\n      edges.push({ from: contextId, to: node.id, key });\n    }\n  }\n\n  const undefinedReads: UndefinedRead[] = [];\n  for (const node of nodes) {\n    for (const key of node.reads) {\n      if (!producedKeys.has(key) && key !== contextId) {\n        undefinedReads.push({\n          key,\n          readerId: node.id,\n          readerName: node.name,\n        });\n      }\n    }\n  }\n\n  const duplicateWrites: DuplicateWrite[] = [];\n  for (const [key, writers] of keyProducers) {\n    if (writers.length > 1) {\n      duplicateWrites.push({ key, writerIds: writers });\n    }\n  }\n\n  return {\n    nodes,\n    edges,\n    producedKeys,\n    undefinedReads,\n    duplicateWrites,\n  };\n}\n\n// =============================================================================\n// Analysis Utilities\n// =============================================================================\n\nexport function getDataFlowOrder(\n  graph: DataFlowGraph,\n): string[] | undefined {\n  const inDegree = new Map<string, number>();\n  const adjacency = new Map<string, string[]>();\n\n  for (const node of graph.nodes) {\n    inDegree.set(node.id, 0);\n    adjacency.set(node.id, []);\n  }\n\n  for (const edge of graph.edges) {\n    if (edge.from === '__context__') continue;\n    const targets = adjacency.get(edge.from) ?? [];\n    targets.push(edge.to);\n    adjacency.set(edge.from, targets);\n    inDegree.set(edge.to, (inDegree.get(edge.to) ?? 0) + 1);\n  }\n\n  const queue: string[] = [];\n  for (const [id, degree] of inDegree) {\n    if (id !== '__context__' && degree === 0) {\n      queue.push(id);\n    }\n  }\n\n  const result: string[] = [];\n  while (queue.length > 0) {\n    const current = queue.shift();\n    if (current === undefined) break;\n    result.push(current);\n    for (const neighbor of adjacency.get(current) ?? []) {\n      const newDegree = (inDegree.get(neighbor) ?? 0) - 1;\n      inDegree.set(neighbor, newDegree);\n      if (newDegree === 0) {\n        queue.push(neighbor);\n      }\n    }\n  }\n\n  if (result.length !== graph.nodes.length) {\n    return undefined;\n  }\n  return result;\n}\n\nexport function getProducers(\n  graph: DataFlowGraph,\n  stepId: string,\n): DataFlowNode[] {\n  const producerIds = new Set<string>();\n  for (const edge of graph.edges) {\n    if (edge.to === stepId && edge.from !== '__context__') {\n      producerIds.add(edge.from);\n    }\n  }\n  return graph.nodes.filter((n) => producerIds.has(n.id));\n}\n\nexport function getConsumers(\n  graph: DataFlowGraph,\n  stepId: string,\n): DataFlowNode[] {\n  const consumerIds = new Set<string>();\n  for (const edge of graph.edges) {\n    if (edge.from === stepId) {\n      consumerIds.add(edge.to);\n    }\n  }\n  return graph.nodes.filter((n) => consumerIds.has(n.id));\n}\n\nexport function getTransitiveDependencies(\n  graph: DataFlowGraph,\n  stepId: string,\n): string[] {\n  const visited = new Set<string>();\n  const result: string[] = [];\n\n  function visit(id: string): void {\n    if (visited.has(id) || id === '__context__') return;\n    visited.add(id);\n    for (const edge of graph.edges) {\n      if (edge.to === id) {\n        result.push(edge.from);\n        visit(edge.from);\n      }\n    }\n  }\n\n  visit(stepId);\n  return result;\n}\n\nexport function findCycles(graph: DataFlowGraph): string[][] {\n  const cycles: string[][] = [];\n  const visited = new Set<string>();\n  const recStack = new Set<string>();\n  const adjacency = new Map<string, string[]>();\n\n  for (const node of graph.nodes) {\n    adjacency.set(node.id, []);\n  }\n  for (const edge of graph.edges) {\n    if (edge.from === '__context__') continue;\n    const targets = adjacency.get(edge.from) ?? [];\n    targets.push(edge.to);\n    adjacency.set(edge.from, targets);\n  }\n\n  function dfs(id: string, path: string[]): void {\n    visited.add(id);\n    recStack.add(id);\n    path.push(id);\n\n    for (const neighbor of adjacency.get(id) ?? []) {\n      if (!visited.has(neighbor)) {\n        dfs(neighbor, path);\n      } else if (recStack.has(neighbor)) {\n        const cycleStart = path.indexOf(neighbor);\n        cycles.push(path.slice(cycleStart));\n      }\n    }\n\n    path.pop();\n    recStack.delete(id);\n  }\n\n  for (const node of graph.nodes) {\n    if (!visited.has(node.id)) {\n      dfs(node.id, []);\n    }\n  }\n\n  return cycles;\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\nexport interface DataFlowValidation {\n  valid: boolean;\n  issues: DataFlowIssue[];\n}\n\nexport interface DataFlowIssue {\n  severity: 'error' | 'warning';\n  type: 'undefined-read' | 'duplicate-write' | 'cycle';\n  message: string;\n  stepIds: string[];\n  key?: string;\n}\n\nexport function validateDataFlow(graph: DataFlowGraph): DataFlowValidation {\n  const issues: DataFlowIssue[] = [];\n\n  for (const read of graph.undefinedReads) {\n    issues.push({\n      severity: 'warning',\n      type: 'undefined-read',\n      message: `Effect \"${read.readerName ?? read.readerId}\" reads \"${read.key}\" which is never produced`,\n      stepIds: [read.readerId],\n      key: read.key,\n    });\n  }\n\n  for (const write of graph.duplicateWrites) {\n    issues.push({\n      severity: 'warning',\n      type: 'duplicate-write',\n      message: `Key \"${write.key}\" is written by multiple effects: ${write.writerIds.join(', ')}`,\n      stepIds: write.writerIds,\n      key: write.key,\n    });\n  }\n\n  const cycles = findCycles(graph);\n  for (const cycle of cycles) {\n    issues.push({\n      severity: 'error',\n      type: 'cycle',\n      message: `Circular data dependency: ${cycle.join(' -> ')}`,\n      stepIds: cycle,\n    });\n  }\n\n  return {\n    valid: issues.length === 0,\n    issues,\n  };\n}\n\n// =============================================================================\n// Rendering\n// =============================================================================\n\nfunction sanitizeId(id: string): string {\n  return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nexport function renderDataFlowMermaid(graph: DataFlowGraph): string {\n  const lines: string[] = [];\n\n  lines.push('flowchart LR');\n  lines.push('');\n  lines.push('  %% Data Flow Graph');\n  lines.push('');\n\n  for (const node of graph.nodes) {\n    const label = node.name ?? node.id;\n    const writes = node.writes ? ` [out: ${node.writes}]` : '';\n    lines.push(`  ${sanitizeId(node.id)}[\"${label}${writes}\"]`);\n  }\n\n  lines.push('');\n\n  for (const edge of graph.edges) {\n    if (edge.from === '__context__') continue;\n    lines.push(\n      `  ${sanitizeId(edge.from)} -->|${edge.key}| ${sanitizeId(edge.to)}`,\n    );\n  }\n\n  if (graph.undefinedReads.length > 0) {\n    lines.push('');\n    lines.push('  %% Undefined Reads (warnings)');\n    for (const read of graph.undefinedReads) {\n      const warningId = `undefined_${sanitizeId(read.key)}`;\n      lines.push(`  ${warningId}[/\"${read.key} (undefined)\"/]`);\n      lines.push(`  ${warningId} -.-> ${sanitizeId(read.readerId)}`);\n    }\n    lines.push('');\n    lines.push('  classDef warning fill:#fff3cd,stroke:#856404');\n    for (const read of graph.undefinedReads) {\n      lines.push(`  class undefined_${sanitizeId(read.key)} warning`);\n    }\n  }\n\n  return lines.join('\\n');\n}\n","/**\n * Error Flow Analysis for Effect IR\n *\n * Aggregates error types from effect nodes (typeSignature.errorType) and\n * error-handler nodes (catchTag, etc.) to build an error propagation view.\n */\n\nimport type {\n  StaticEffectIR,\n  StaticFlowNode,\n  StaticCauseNode,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { splitTopLevelUnion } from './type-extractor';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface StepErrorInfo {\n  stepId: string;\n  stepName?: string | undefined;\n  errors: string[];\n  location?: { line: number; column: number } | undefined;\n}\n\n/** Per-node error propagation: errors at this point and how handlers narrow (GAP 4) */\nexport interface ErrorPropagation {\n  atNode: string;\n  possibleErrors: string[];\n  narrowedBy?: {\n    handler: string;\n    removedErrors: string[];\n    addedErrors: string[];\n  };\n  defects: string[];\n  interruptible: boolean;\n}\n\nexport interface ErrorPropagationAnalysis {\n  propagation: ErrorPropagation[];\n  byNodeId: Map<string, ErrorPropagation>;\n}\n\nexport interface ErrorFlowAnalysis {\n  /**\n   * Every error type raised somewhere in the body, not the declared error\n   * channel of the program's signature. A step that raises `SchemaError` and\n   * maps it to `ValidationError` before returning is reported as `SchemaError`;\n   * for the channel, use `analyzeErrorChannels`.\n   */\n  allErrors: string[];\n  stepErrors: StepErrorInfo[];\n  errorToSteps: Map<string, string[]>;\n  stepsWithoutErrors: string[];\n  allStepsDeclareErrors: boolean;\n}\n\nexport interface ErrorFlowEdge {\n  stepId: string;\n  error: string;\n}\n\nexport interface ErrorValidation {\n  valid: boolean;\n  unusedDeclared: string[];\n  undeclaredErrors: string[];\n  computedErrors: string[];\n}\n\n// =============================================================================\n// Helpers: parse error type string (e.g. \"A | B\" or \"never\")\n// =============================================================================\n\nfunction parseErrorTypes(errorType: string): string[] {\n  const t = errorType.trim();\n  if (t === 'never' || t === 'unknown') {\n    return [];\n  }\n  return splitTopLevelUnion(t);\n}\n\n// =============================================================================\n// Collection\n// =============================================================================\n\nfunction collectEffectErrors(\n  nodes: readonly StaticFlowNode[],\n  result: StepErrorInfo[],\n): void {\n  for (const node of nodes) {\n    if (node.type === 'effect') {\n      const eff = node;\n      const errors = eff.typeSignature?.errorType\n        ? parseErrorTypes(eff.typeSignature.errorType)\n        : [];\n      result.push({\n        stepId: eff.id,\n        stepName: eff.callee,\n        errors,\n        location: eff.location\n          ? { line: eff.location.line, column: eff.location.column }\n          : undefined,\n      });\n    }\n\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) {\n      collectEffectErrors(children, result);\n    }\n  }\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport function analyzeErrorFlow(ir: StaticEffectIR): ErrorFlowAnalysis {\n  const stepErrors: StepErrorInfo[] = [];\n  const allErrorsSet = new Set<string>();\n  const errorToSteps = new Map<string, string[]>();\n  const stepsWithoutErrors: string[] = [];\n\n  collectEffectErrors(ir.root.children, stepErrors);\n\n  for (const step of stepErrors) {\n    if (step.errors.length === 0) {\n      stepsWithoutErrors.push(step.stepId);\n    }\n    for (const error of step.errors) {\n      allErrorsSet.add(error);\n      const steps = errorToSteps.get(error) ?? [];\n      steps.push(step.stepId);\n      errorToSteps.set(error, steps);\n    }\n  }\n\n  return {\n    allErrors: Array.from(allErrorsSet).sort(),\n    stepErrors,\n    errorToSteps,\n    stepsWithoutErrors,\n    allStepsDeclareErrors:\n      stepsWithoutErrors.length === 0 && stepErrors.length > 0,\n  };\n}\n\n// =============================================================================\n// Error Propagation & Narrowing (GAP 4)\n// =============================================================================\n\nfunction unionErrors(a: string[], b: string[]): string[] {\n  return Array.from(new Set([...a, ...b])).sort();\n}\n\nfunction withoutErrors(current: string[], removed: string[]): string[] {\n  const set = new Set(removed);\n  return current.filter((e) => !set.has(e));\n}\n\n/** Collect error types from a subtree (effect nodes only). */\nfunction collectErrorsFromSubtree(node: StaticFlowNode): string[] {\n  const out: string[] = [];\n  const visit = (n: StaticFlowNode) => {\n    if (n.type === 'effect') {\n      const err = (n).typeSignature?.errorType;\n      if (err) out.push(...parseErrorTypes(err));\n    }\n    const children = Option.getOrElse(getStaticChildren(n), () => []);\n    children.forEach(visit);\n  };\n  visit(node);\n  return unionErrors([], out);\n}\n\n/** Find the causeKind of the first cause node in a subtree (for cause-aware mapped-error placeholders). */\nfunction findCauseKindInSubtree(node: StaticFlowNode): StaticCauseNode['causeKind'] | undefined {\n  if (node.type === 'cause') return (node).causeKind;\n  const children = Option.getOrElse(getStaticChildren(node), () => []);\n  for (const child of children) {\n    const result = findCauseKindInSubtree(child);\n    if (result) return result;\n  }\n  return undefined;\n}\n\n/**\n * Walk IR in execution order, propagating error types and applying narrowing at handlers.\n */\nfunction walkPropagation(\n  nodes: readonly StaticFlowNode[],\n  errorsIn: string[],\n  result: ErrorPropagation[],\n): string[] {\n  let current = [...errorsIn];\n  for (const node of nodes) {\n    if (node.type === 'effect') {\n      const eff = node;\n      const own = eff.typeSignature?.errorType\n        ? parseErrorTypes(eff.typeSignature.errorType)\n        : [];\n      current = unionErrors(current, own);\n      result.push({\n        atNode: eff.id,\n        possibleErrors: [...current],\n        defects: [],\n        interruptible: false,\n      });\n      const children = Option.getOrElse(getStaticChildren(node), () => []);\n      if (children.length > 0) {\n        current = walkPropagation(children, current, result);\n      }\n    } else if (node.type === 'error-handler') {\n      const handler = node;\n      current = walkPropagation([handler.source], current, result);\n      const sourceErrors = [...current];\n      const removed: string[] = [];\n      if (handler.handlerType === 'catchTag' && handler.errorTag) {\n        removed.push(handler.errorTag);\n      } else if (handler.handlerType === 'catchTags') {\n        // Object-form catchTags: use extracted tag keys if available, otherwise\n        // fall back to heuristic (names ending in Error or starting with uppercase).\n        if (handler.errorTags && handler.errorTags.length > 0) {\n          removed.push(\n            ...sourceErrors.filter((e) =>\n              handler.errorTags ? handler.errorTags.includes(e) : false,\n            ),\n          );\n        } else {\n          removed.push(...sourceErrors.filter((e) => /Error$|^[A-Z]/.test(e)));\n        }\n      } else if (\n        handler.handlerType === 'catchIf' ||\n        handler.handlerType === 'catchSome' ||\n        handler.handlerType === 'catchSomeCause' ||\n        handler.handlerType === 'catchSomeDefect'\n      ) {\n        // Predicate/selective catches remove a subset we cannot fully infer.\n        removed.push(...sourceErrors.slice(0, Math.ceil(sourceErrors.length / 2)));\n      } else if (\n        handler.handlerType === 'catch' ||\n        handler.handlerType === 'catchCause' ||\n        handler.handlerType === 'catchDefect' ||\n        handler.handlerType === 'orElse' ||\n        handler.handlerType === 'orDie' ||\n        handler.handlerType === 'orDieWith'\n      ) {\n        removed.push(...sourceErrors);\n      } else if (\n        handler.handlerType === 'mapError' ||\n        handler.handlerType === 'mapErrorCause' ||\n        handler.handlerType === 'mapBoth'\n      ) {\n        // Error type is transformed — remove original errors, add a placeholder\n        // since we can't statically determine the mapped-to type without full inference.\n        removed.push(...sourceErrors);\n      } else if (\n        handler.handlerType === 'sandbox'\n      ) {\n        // sandbox wraps error + defects into Cause — remove typed errors (they become Cause)\n        removed.push(...sourceErrors);\n      } else if (\n        handler.handlerType === 'ignore' ||\n        handler.handlerType === 'ignoreLogged'\n      ) {\n        // ignore silences all errors\n        removed.push(...sourceErrors);\n      } else if (\n        handler.handlerType === 'orElseFail' ||\n        handler.handlerType === 'orElseSucceed'\n      ) {\n        // orElseFail replaces all errors with a new error; orElseSucceed silences them\n        removed.push(...sourceErrors);\n      } else if (\n        handler.handlerType === 'filterOrDie' ||\n        handler.handlerType === 'filterOrDieMessage'\n      ) {\n        // filter predicates that fail convert to defects — remove typed errors\n        removed.push(...sourceErrors);\n      }\n      const afterNarrow = withoutErrors(current, removed);\n      let handlerErrors = handler.handler\n        ? collectErrorsFromSubtree(handler.handler)\n        : [];\n      // For mapping transforms: errors are replaced, not eliminated — mark as transformed.\n      // When the source includes a cause node with a known causeKind, use a more specific placeholder.\n      if (\n        (handler.handlerType === 'mapError' ||\n          handler.handlerType === 'mapErrorCause' ||\n          handler.handlerType === 'mapBoth') &&\n        removed.length > 0 &&\n        handlerErrors.length === 0\n      ) {\n        const causeKind = findCauseKindInSubtree(handler.source);\n        if (causeKind === 'fail') handlerErrors = ['<mapped-fail>'];\n        else if (causeKind === 'die') handlerErrors = ['<mapped-defect>'];\n        else handlerErrors = ['<mapped-error>'];\n      }\n      current = unionErrors(afterNarrow, handlerErrors);\n      result.push({\n        atNode: handler.id,\n        possibleErrors: [...current],\n        narrowedBy: {\n          handler: handler.handlerType,\n          removedErrors: removed,\n          addedErrors: handlerErrors,\n        },\n        defects: [],\n        interruptible: false,\n      });\n      if (handler.handler) {\n        current = walkPropagation([handler.handler], current, result);\n      }\n    } else if (node.type === 'parallel' || node.type === 'race') {\n      const children = Option.getOrElse(getStaticChildren(node), () => []);\n      let branchErrors: string[] = [];\n      for (const child of children) {\n        const fromChild = walkPropagation([child], current, result);\n        branchErrors = unionErrors(branchErrors, fromChild);\n      }\n      current = branchErrors;\n    } else {\n      const children = Option.getOrElse(getStaticChildren(node), () => []);\n      if (children.length > 0) {\n        current = walkPropagation(children, current, result);\n      }\n    }\n  }\n  return current;\n}\n\nexport function analyzeErrorPropagation(ir: StaticEffectIR): ErrorPropagationAnalysis {\n  const propagation: ErrorPropagation[] = [];\n  walkPropagation(ir.root.children, [], propagation);\n  const byNodeId = new Map<string, ErrorPropagation>();\n  for (const p of propagation) {\n    byNodeId.set(p.atNode, p);\n  }\n  return { propagation, byNodeId };\n}\n\n// =============================================================================\n// Error Propagation\n// =============================================================================\n\nexport function getErrorsAtPoint(\n  analysis: ErrorFlowAnalysis,\n  afterStepId: string,\n): string[] {\n  const errors = new Set<string>();\n  let found = false;\n\n  for (const step of analysis.stepErrors) {\n    for (const error of step.errors) {\n      errors.add(error);\n    }\n    if (step.stepId === afterStepId) {\n      found = true;\n      break;\n    }\n  }\n\n  if (!found) {\n    return analysis.allErrors;\n  }\n  return Array.from(errors).sort();\n}\n\nexport function getErrorProducers(\n  analysis: ErrorFlowAnalysis,\n  errorTag: string,\n): StepErrorInfo[] {\n  const stepIds = analysis.errorToSteps.get(errorTag) ?? [];\n  return analysis.stepErrors.filter((s) => stepIds.includes(s.stepId));\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\nexport function validateWorkflowErrors(\n  analysis: ErrorFlowAnalysis,\n  declaredErrors: string[],\n): ErrorValidation {\n  const declaredSet = new Set(declaredErrors);\n  const computedSet = new Set(analysis.allErrors);\n\n  const unusedDeclared = declaredErrors.filter((e) => !computedSet.has(e));\n  const undeclaredErrors = analysis.allErrors.filter((e) => !declaredSet.has(e));\n\n  return {\n    valid:\n      unusedDeclared.length === 0 && undeclaredErrors.length === 0,\n    unusedDeclared,\n    undeclaredErrors,\n    computedErrors: analysis.allErrors,\n  };\n}\n\n// =============================================================================\n// Rendering\n// =============================================================================\n\nfunction sanitizeId(id: string): string {\n  return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nexport function renderErrorFlowMermaid(analysis: ErrorFlowAnalysis): string {\n  const lines: string[] = [];\n\n  lines.push('flowchart LR');\n  lines.push('');\n  lines.push('  %% Error Flow Graph');\n  lines.push('');\n\n  lines.push('  subgraph Steps');\n  for (const step of analysis.stepErrors) {\n    const label = step.stepName ?? step.stepId;\n    lines.push(`    ${sanitizeId(step.stepId)}[\"${label}\"]`);\n  }\n  lines.push('  end');\n  lines.push('');\n\n  if (analysis.allErrors.length > 0) {\n    lines.push('  subgraph Errors');\n    for (const error of analysis.allErrors) {\n      lines.push(`    err_${sanitizeId(error)}([\"${error}\"])`);\n    }\n    lines.push('  end');\n    lines.push('');\n\n    for (const step of analysis.stepErrors) {\n      for (const error of step.errors) {\n        lines.push(\n          `  ${sanitizeId(step.stepId)} -.->|throws| err_${sanitizeId(error)}`,\n        );\n      }\n    }\n  }\n\n  lines.push('');\n  lines.push('  classDef error fill:#ffcdd2,stroke:#c62828');\n  for (const error of analysis.allErrors) {\n    lines.push(`  class err_${sanitizeId(error)} error`);\n  }\n\n  if (analysis.stepsWithoutErrors.length > 0) {\n    lines.push('');\n    lines.push('  classDef noErrors fill:#fff3cd,stroke:#856404');\n    for (const stepId of analysis.stepsWithoutErrors) {\n      lines.push(`  class ${sanitizeId(stepId)} noErrors`);\n    }\n  }\n\n  return lines.join('\\n');\n}\n\nexport function formatErrorSummary(analysis: ErrorFlowAnalysis): string {\n  const lines: string[] = [];\n\n  lines.push('## Error Flow Summary');\n  lines.push('');\n\n  lines.push(`**Total Effects:** ${analysis.stepErrors.length}`);\n  lines.push(`**Total Error Types:** ${analysis.allErrors.length}`);\n  lines.push(\n    `**Effects Without Declared Errors:** ${analysis.stepsWithoutErrors.length}`,\n  );\n  lines.push('');\n\n  if (analysis.allErrors.length > 0) {\n    lines.push('### Error Types');\n    lines.push('');\n    for (const error of analysis.allErrors) {\n      const producers = analysis.errorToSteps.get(error) ?? [];\n      lines.push(`- \\`${error}\\` - produced by: ${producers.join(', ')}`);\n    }\n    lines.push('');\n  }\n\n  if (analysis.stepsWithoutErrors.length > 0) {\n    lines.push('### Effects Without Declared Errors');\n    lines.push('');\n    lines.push(\n      'The following effects do not declare their error type (typeSignature.errorType):',\n    );\n    lines.push('');\n    for (const stepId of analysis.stepsWithoutErrors) {\n      lines.push(`- ${stepId}`);\n    }\n    lines.push('');\n  }\n\n  lines.push('### Effect Error Details');\n  lines.push('');\n  lines.push('| Effect | Errors |');\n  lines.push('|--------|--------|');\n  for (const step of analysis.stepErrors) {\n    const name = step.stepName ?? step.stepId;\n    const errors =\n      step.errors.length > 0\n        ? step.errors.map((e) => `\\`${e}\\``).join(', ')\n        : '_none_';\n    lines.push(`| ${name} | ${errors} |`);\n  }\n\n  return lines.join('\\n');\n}\n","/** Normalize Effect v4 and OpenTelemetry spans for static diagram overlays. */\n\nimport { Exit, Option } from 'effect';\nimport type * as Tracer from 'effect/Tracer';\n\nexport type RuntimeSpanStatus = 'running' | 'success' | 'error';\n\nexport interface RuntimeTraceSpan {\n  readonly spanId: string;\n  readonly parentSpanId?: string | undefined;\n  readonly name: string;\n  readonly path: readonly string[];\n  readonly status: RuntimeSpanStatus;\n  readonly durationMs?: number | undefined;\n}\n\nexport interface RuntimeTrace {\n  readonly spans: readonly RuntimeTraceSpan[];\n}\n\ninterface FlatSpan {\n  readonly spanId: string;\n  readonly parentSpanId?: string | undefined;\n  readonly name: string;\n  readonly status: RuntimeSpanStatus;\n  readonly durationMs?: number | undefined;\n}\n\nconst addPaths = (spans: readonly FlatSpan[]): RuntimeTrace => {\n  const byId = new Map(spans.map((span) => [span.spanId, span] as const));\n  const pathFor = (span: FlatSpan, seen = new Set<string>()): readonly string[] => {\n    if (!span.parentSpanId || seen.has(span.spanId)) return [span.name];\n    const parent = byId.get(span.parentSpanId);\n    if (!parent) return [span.name];\n    seen.add(span.spanId);\n    return [...pathFor(parent, seen), span.name];\n  };\n  return {\n    spans: spans.map((span) => ({ ...span, path: pathFor(span) })),\n  };\n};\n\n/** Adapter for Effect v4 native/devtools span values. */\nexport const traceFromEffectSpans = (\n  spans: readonly Tracer.Span[],\n): RuntimeTrace => addPaths(spans.map((span) => {\n  const parent = Option.getOrUndefined(span.parent);\n  const ended = span.status._tag === 'Ended';\n  return {\n    spanId: span.spanId,\n    ...(parent ? { parentSpanId: parent.spanId } : {}),\n    name: span.name,\n    status: ended\n      ? Exit.isSuccess(span.status.exit) ? 'success' as const : 'error' as const\n      : 'running' as const,\n    ...(ended\n      ? { durationMs: Number(span.status.endTime - span.status.startTime) / 1_000_000 }\n      : {}),\n  };\n}));\n\nexport interface OpenTelemetryReadableSpan {\n  readonly name: string;\n  readonly spanContext: () => { readonly spanId: string };\n  readonly parentSpanContext?: { readonly spanId: string } | undefined;\n  readonly status?: { readonly code: number } | undefined;\n  readonly startTime?: readonly [number, number] | undefined;\n  readonly endTime?: readonly [number, number] | undefined;\n}\n\nconst hrDurationMs = (\n  start: readonly [number, number] | undefined,\n  end: readonly [number, number] | undefined,\n): number | undefined => {\n  if (!start || !end) return undefined;\n  return (end[0] - start[0]) * 1_000 + (end[1] - start[1]) / 1_000_000;\n};\n\n/** Adapter for OpenTelemetry ReadableSpan-shaped exports. */\nexport const traceFromOpenTelemetry = (\n  spans: readonly OpenTelemetryReadableSpan[],\n): RuntimeTrace => addPaths(spans.map((span) => ({\n  spanId: span.spanContext().spanId,\n  ...(span.parentSpanContext ? { parentSpanId: span.parentSpanContext.spanId } : {}),\n  name: span.name,\n  status: span.status?.code === 2 ? 'error' : 'success',\n  ...(() => {\n    const durationMs = hrDurationMs(span.startTime, span.endTime);\n    return durationMs === undefined ? {} : { durationMs };\n  })(),\n})));\n\n/** One node of a nested span-tree JSON export. */\nexport interface SpanTreeNode {\n  readonly spanId: string;\n  readonly name: string;\n  readonly status: 'ok' | 'error' | 'unset';\n  readonly durationMs?: number | null | undefined;\n  readonly running?: boolean | undefined;\n  readonly children?: readonly SpanTreeNode[] | undefined;\n}\n\nexport interface SpanTree {\n  readonly spans: readonly SpanTreeNode[];\n}\n\n/** Adapter for tracing tools that export a trace as a nested span tree. */\nexport const traceFromSpanTree = (trace: SpanTree): RuntimeTrace => {\n  const flat: FlatSpan[] = [];\n  const walk = (node: SpanTreeNode, parentSpanId?: string): void => {\n    flat.push({\n      spanId: node.spanId,\n      ...(parentSpanId ? { parentSpanId } : {}),\n      name: node.name,\n      status: node.running === true\n        ? 'running'\n        : node.status === 'error'\n          ? 'error'\n          : 'success',\n      ...(typeof node.durationMs === 'number' ? { durationMs: node.durationMs } : {}),\n    });\n    for (const child of node.children ?? []) walk(child, node.spanId);\n  };\n  for (const root of trace.spans) walk(root);\n  return addPaths(flat);\n};\n","import { Option } from 'effect';\nimport {\n  getStaticChildren,\n  type StaticEffectIR,\n  type StaticEffectProgram,\n  type StaticFlowNode,\n} from '../types';\nimport type {\n  ProgramDiff,\n  DiffOptions,\n  StepDiffEntry,\n  StructuralChange,\n  DiffSummary,\n} from './types';\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface StepContext {\n  stepId: string;\n  callee: string;\n  containerType: string;\n  index: number;\n  /** Content-based fingerprint for stable matching */\n  fingerprint: string;\n}\n\nconst CONTAINER_TYPES = new Set([\n  'parallel',\n  'race',\n  'conditional',\n  'decision',\n  'switch',\n  'loop',\n  'error-handler',\n  'retry',\n  'generator',\n  'pipe',\n  'stream',\n  'fiber',\n]);\n\nfunction computeFingerprint(node: StaticFlowNode): string {\n  if (node.type === 'effect') {\n    // Use displayName (includes variable name, e.g. \"config <- succeed\")\n    // to disambiguate repeated callees; fall back to callee alone\n    return node.displayName ?? node.callee;\n  }\n  return `${node.type}:${node.displayName ?? node.id}`;\n}\n\n// ---------------------------------------------------------------------------\n// Tree walkers\n// ---------------------------------------------------------------------------\n\nfunction collectStepsWithContext(\n  node: StaticFlowNode | StaticEffectProgram,\n  containerType = 'root',\n  index = 0,\n): StepContext[] {\n  const results: StepContext[] = [];\n\n  if (node.type === 'effect') {\n    results.push({\n      stepId: node.id,\n      callee: node.callee,\n      containerType,\n      index,\n      fingerprint: computeFingerprint(node),\n    });\n    // Still recurse into callbackBody via getStaticChildren\n  }\n\n  const children = Option.getOrElse(getStaticChildren(node), () => [] as readonly StaticFlowNode[]);\n  const nextContainer = CONTAINER_TYPES.has(node.type) ? node.type : containerType;\n\n  let childIdx = 0;\n  for (const child of children) {\n    // For effect nodes at this level, the container is the current node type\n    const childResults = collectStepsWithContext(child, nextContainer, childIdx);\n    results.push(...childResults);\n    childIdx++;\n  }\n\n  return results;\n}\n\nfunction countContainerTypes(node: StaticFlowNode | StaticEffectProgram): Map<string, number> {\n  const counts = new Map<string, number>();\n\n  function walk(n: StaticFlowNode | StaticEffectProgram): void {\n    if (CONTAINER_TYPES.has(n.type)) {\n      counts.set(n.type, (counts.get(n.type) ?? 0) + 1);\n    }\n    const children = Option.getOrElse(getStaticChildren(n), () => [] as readonly StaticFlowNode[]);\n    for (const child of children) {\n      walk(child);\n    }\n  }\n\n  walk(node);\n  return counts;\n}\n\n// ---------------------------------------------------------------------------\n// Diff algorithm\n// ---------------------------------------------------------------------------\n\nexport function diffPrograms(\n  before: StaticEffectIR,\n  after: StaticEffectIR,\n  options?: DiffOptions,\n): ProgramDiff {\n  const detectRenames = options?.detectRenames ?? true;\n  const regressionMode = options?.regressionMode ?? false;\n\n  const beforeSteps = collectStepsWithContext(before.root);\n  const afterSteps = collectStepsWithContext(after.root);\n\n  const matchedBeforeIdx = new Set<number>();\n  const matchedAfterIdx = new Set<number>();\n  const entries: StepDiffEntry[] = [];\n\n  // Pass 1: Match by fingerprint (content-based, stable across analysis runs)\n  // Sub-pass 1a: match same-container fingerprints first to avoid cross-container\n  // matches stealing candidates when duplicates exist.\n  function matchByFingerprint(requireSameContainer: boolean): void {\n    for (let bIdx = 0; bIdx < beforeSteps.length; bIdx++) {\n      if (matchedBeforeIdx.has(bIdx)) continue;\n      const beforeStep = beforeSteps[bIdx];\n      if (!beforeStep) continue;\n\n      // Collect unmatched after-step candidates with the same fingerprint\n      const candidates: number[] = [];\n      for (let aIdx = 0; aIdx < afterSteps.length; aIdx++) {\n        if (!matchedAfterIdx.has(aIdx) && afterSteps[aIdx]?.fingerprint === beforeStep.fingerprint) {\n          const afterCandidate = afterSteps[aIdx];\n          if (requireSameContainer && afterCandidate && afterCandidate.containerType !== beforeStep.containerType) continue;\n          candidates.push(aIdx);\n        }\n      }\n      if (candidates.length === 0) continue;\n\n      // Pick best candidate by closest index\n      let bestIdx = candidates[0] ?? 0;\n      let bestDist = Math.abs((afterSteps[bestIdx]?.index ?? 0) - beforeStep.index);\n      for (let i = 1; i < candidates.length; i++) {\n        const aIdx = candidates[i] ?? 0;\n        const dist = Math.abs((afterSteps[aIdx]?.index ?? 0) - beforeStep.index);\n        if (dist < bestDist) {\n          bestIdx = aIdx;\n          bestDist = dist;\n        }\n      }\n\n      const afterStep = afterSteps[bestIdx];\n      if (!afterStep) continue;\n      matchedBeforeIdx.add(bIdx);\n      matchedAfterIdx.add(bestIdx);\n\n      if (beforeStep.containerType !== afterStep.containerType) {\n        entries.push({\n          kind: 'moved',\n          stepId: afterStep.stepId,\n          callee: afterStep.callee,\n          containerBefore: beforeStep.containerType,\n          containerAfter: afterStep.containerType,\n        });\n      } else {\n        entries.push({\n          kind: 'unchanged',\n          stepId: afterStep.stepId,\n          callee: afterStep.callee,\n        });\n      }\n    }\n  }\n  // First match within same container, then allow cross-container moves\n  matchByFingerprint(true);\n  matchByFingerprint(false);\n\n  // Pass 2: Rename detection — match unmatched by callee\n  if (detectRenames) {\n    for (let aIdx = 0; aIdx < afterSteps.length; aIdx++) {\n      if (matchedAfterIdx.has(aIdx)) continue;\n      const afterStep = afterSteps[aIdx];\n      if (!afterStep) continue;\n      // Find first unmatched before-step with same callee\n      const bIdx = beforeSteps.findIndex(\n        (bStep, bi) => !matchedBeforeIdx.has(bi) && bStep.callee === afterStep.callee,\n      );\n      if (bIdx >= 0) {\n        const matchedBefore = beforeSteps[bIdx];\n        if (!matchedBefore) continue;\n        matchedBeforeIdx.add(bIdx);\n        matchedAfterIdx.add(aIdx);\n        entries.push({\n          kind: 'renamed',\n          stepId: afterStep.stepId,\n          previousStepId: matchedBefore.stepId,\n          callee: afterStep.callee,\n        });\n      }\n    }\n  }\n\n  // Pass 3: Remaining unmatched → removed / added\n  for (let bIdx = 0; bIdx < beforeSteps.length; bIdx++) {\n    if (!matchedBeforeIdx.has(bIdx)) {\n      const bs = beforeSteps[bIdx];\n      if (!bs) continue;\n      entries.push({\n        kind: 'removed',\n        stepId: bs.stepId,\n        callee: bs.callee,\n      });\n    }\n  }\n  for (let aIdx = 0; aIdx < afterSteps.length; aIdx++) {\n    if (!matchedAfterIdx.has(aIdx)) {\n      const as2 = afterSteps[aIdx];\n      if (!as2) continue;\n      entries.push({\n        kind: 'added',\n        stepId: as2.stepId,\n        callee: as2.callee,\n      });\n    }\n  }\n\n  // Structural changes — compare container counts\n  const structuralChanges: StructuralChange[] = [];\n  const beforeContainers = countContainerTypes(before.root);\n  const afterContainers = countContainerTypes(after.root);\n\n  const allContainerKeys = new Set([...beforeContainers.keys(), ...afterContainers.keys()]);\n  for (const key of allContainerKeys) {\n    const bCount = beforeContainers.get(key) ?? 0;\n    const aCount = afterContainers.get(key) ?? 0;\n    if (aCount > bCount) {\n      for (let i = 0; i < aCount - bCount; i++) {\n        structuralChanges.push({\n          kind: 'added',\n          nodeType: key,\n          description: `${key} block added`,\n        });\n      }\n    } else if (bCount > aCount) {\n      for (let i = 0; i < bCount - aCount; i++) {\n        structuralChanges.push({\n          kind: 'removed',\n          nodeType: key,\n          description: `${key} block removed`,\n        });\n      }\n    }\n  }\n\n  // Summary\n  const summary: DiffSummary = {\n    stepsAdded: entries.filter((e) => e.kind === 'added').length,\n    stepsRemoved: entries.filter((e) => e.kind === 'removed').length,\n    stepsRenamed: entries.filter((e) => e.kind === 'renamed').length,\n    stepsMoved: entries.filter((e) => e.kind === 'moved').length,\n    stepsUnchanged: entries.filter((e) => e.kind === 'unchanged').length,\n    structuralChanges: structuralChanges.length,\n    hasRegressions: regressionMode\n      ? entries.some((e) => e.kind === 'removed') || structuralChanges.some((sc) => sc.kind === 'removed')\n      : false,\n  };\n\n  return {\n    beforeName: before.root.programName,\n    afterName: after.root.programName,\n    diffedAt: Date.now(),\n    steps: entries,\n    structuralChanges,\n    summary,\n  };\n}\n","import type { ProgramDiff, DiffMarkdownOptions, StepDiffEntry } from './types';\n\nconst KIND_ICONS: Record<string, string> = {\n  added: '+',\n  removed: '-',\n  unchanged: ' ',\n  renamed: '~',\n  moved: '>',\n};\n\nfunction formatStepLine(entry: StepDiffEntry): string {\n  const icon = KIND_ICONS[entry.kind] ?? '?';\n  const callee = entry.callee ?? entry.stepId;\n\n  switch (entry.kind) {\n    case 'renamed':\n      return `${icon} **${callee}** (renamed from \\`${entry.previousStepId}\\` → \\`${entry.stepId}\\`)`;\n    case 'moved':\n      return `${icon} **${callee}** (moved from \\`${entry.containerBefore}\\` → \\`${entry.containerAfter}\\`)`;\n    case 'added':\n      return `${icon} **${callee}** (added, id: \\`${entry.stepId}\\`)`;\n    case 'removed':\n      return `${icon} **${callee}** (removed, id: \\`${entry.stepId}\\`)`;\n    default:\n      return `${icon} ${callee}`;\n  }\n}\n\nexport function renderDiffMarkdown(\n  diff: ProgramDiff,\n  options?: DiffMarkdownOptions,\n): string {\n  const showUnchanged = options?.showUnchanged ?? false;\n  const title =\n    options?.title ?? `Effect Program Diff: ${diff.beforeName} → ${diff.afterName}`;\n\n  const lines: string[] = [];\n\n  lines.push(`# ${title}`);\n  lines.push('');\n\n  // Summary table\n  lines.push('## Summary');\n  lines.push('');\n  lines.push('| Metric | Count |');\n  lines.push('|--------|-------|');\n  lines.push(`| Added | ${diff.summary.stepsAdded} |`);\n  lines.push(`| Removed | ${diff.summary.stepsRemoved} |`);\n  lines.push(`| Renamed | ${diff.summary.stepsRenamed} |`);\n  lines.push(`| Moved | ${diff.summary.stepsMoved} |`);\n  lines.push(`| Unchanged | ${diff.summary.stepsUnchanged} |`);\n  lines.push(`| Structural changes | ${diff.summary.structuralChanges} |`);\n  if (diff.summary.hasRegressions) {\n    lines.push(`| **Regressions** | **Yes** |`);\n  }\n  lines.push('');\n\n  // Step changes\n  const visibleSteps = showUnchanged\n    ? diff.steps\n    : diff.steps.filter((s) => s.kind !== 'unchanged');\n\n  if (visibleSteps.length > 0) {\n    lines.push('## Step Changes');\n    lines.push('');\n    lines.push('```diff');\n    for (const entry of visibleSteps) {\n      lines.push(formatStepLine(entry));\n    }\n    lines.push('```');\n    lines.push('');\n  }\n\n  // Structural changes\n  if (diff.structuralChanges.length > 0) {\n    lines.push('## Structural Changes');\n    lines.push('');\n    for (const sc of diff.structuralChanges) {\n      const prefix = sc.kind === 'added' ? '+' : '-';\n      lines.push(`- ${prefix} ${sc.description}`);\n    }\n    lines.push('');\n  }\n\n  return lines.join('\\n');\n}\n","import type { ProgramDiff } from './types';\n\nexport function renderDiffJSON(\n  diff: ProgramDiff,\n  options?: { pretty?: boolean },\n): string {\n  const pretty = options?.pretty ?? true;\n  return pretty ? JSON.stringify(diff, null, 2) : JSON.stringify(diff);\n}\n","import type { StaticEffectIR } from '../types';\nimport { renderStaticMermaid } from '../output/mermaid';\nimport type { ProgramDiff, DiffMermaidOptions } from './types';\n\n/**\n * Build a mapping from step id → mermaid node id by parsing the rendered\n * mermaid output. The effect-analyzer renderer uses `n1`, `n2`, etc.\n */\nfunction buildStepIdMap(mermaidOutput: string): Map<string, string> {\n  const map = new Map<string, string>();\n  // Match lines like:  n2[\"Effect.succeed\"]\n  const nodePattern = /^\\s*(n\\d+)\\[\"[^\"]*\"\\]/gm;\n  let match: RegExpExecArray | null;\n  while ((match = nodePattern.exec(mermaidOutput)) !== null) {\n    const id = match[1] ?? '';\n    // The mermaid node id is e.g. \"n2\"\n    // We store the raw mermaid id — callers will correlate via position\n    map.set(id, id);\n  }\n  return map;\n}\n\n/**\n * Render a mermaid diagram of the \"after\" IR with diff annotations overlaid\n * (style classes for added, removed, moved, renamed steps).\n */\nexport function renderDiffMermaid(\n  after: StaticEffectIR,\n  diff: ProgramDiff,\n  options?: DiffMermaidOptions,\n): string {\n  const direction = options?.direction ?? 'TB';\n  const showRemoved = options?.showRemovedSteps ?? false;\n\n  // Render the base mermaid for the \"after\" IR\n  const baseMermaid = renderStaticMermaid(after, { direction });\n\n  const _stepIdMap = buildStepIdMap(baseMermaid);\n\n  // Collect step ids by kind for styling\n  const addedIds = new Set(diff.steps.filter((s) => s.kind === 'added').map((s) => s.stepId));\n  const _removedIds = new Set(diff.steps.filter((s) => s.kind === 'removed').map((s) => s.stepId));\n  const movedIds = new Set(diff.steps.filter((s) => s.kind === 'moved').map((s) => s.stepId));\n  const renamedIds = new Set(diff.steps.filter((s) => s.kind === 'renamed').map((s) => s.stepId));\n\n  // Walk the \"after\" IR to build ir-id → mermaid-id mapping\n  // We parse the mermaid output to find which mermaid node id corresponds to which IR node id\n  const irToMermaid = new Map<string, string>();\n  const lines = baseMermaid.split('\\n');\n\n  // The renderer assigns mermaid ids in traversal order. We need to correlate\n  // them with IR node ids. The simplest approach: scan for node definitions\n  // and use the rendered mermaid output's nodeIdMap if available, otherwise\n  // try to match based on label content.\n  // Since renderStaticMermaid doesn't expose the nodeIdMap, we annotate by\n  // scanning each diff step's callee in the mermaid output.\n\n  // Build annotation lines\n  const styleLines: string[] = [];\n\n  // For each line that defines a node, try to match it to a diff entry\n  for (const line of lines) {\n    const nodeMatch = /^\\s*(n\\d+)\\[\"([^\"]*)\"\\]/.exec(line);\n    if (!nodeMatch) continue;\n    const mermaidId = nodeMatch[1] ?? '';\n    const label = nodeMatch[2] ?? '';\n\n    // Try matching by callee or displayName in the label\n    for (const step of diff.steps) {\n      if (step.callee && label.includes(step.callee)) {\n        irToMermaid.set(step.stepId, mermaidId);\n        break;\n      }\n    }\n  }\n\n  // Apply style classes\n  for (const [irId, mermaidId] of irToMermaid) {\n    if (addedIds.has(irId)) {\n      styleLines.push(`  style ${mermaidId} fill:#d4edda,stroke:#28a745,stroke-width:2px`);\n    } else if (movedIds.has(irId)) {\n      styleLines.push(`  style ${mermaidId} fill:#fff3cd,stroke:#ffc107,stroke-width:2px`);\n    } else if (renamedIds.has(irId)) {\n      styleLines.push(`  style ${mermaidId} fill:#cce5ff,stroke:#007bff,stroke-width:2px`);\n    }\n  }\n\n  // For removed steps, optionally add phantom nodes\n  if (showRemoved) {\n    for (const step of diff.steps) {\n      if (step.kind === 'removed') {\n        const phantomId = `removed_${step.stepId.replace(/[^a-zA-Z0-9]/g, '_')}`;\n        styleLines.push(`  ${phantomId}[\"❌ ${step.callee ?? step.stepId}\"]`);\n        styleLines.push(\n          `  style ${phantomId} fill:#f8d7da,stroke:#dc3545,stroke-width:2px,stroke-dasharray: 5 5`,\n        );\n      }\n    }\n  }\n\n  if (styleLines.length === 0) {\n    return baseMermaid;\n  }\n\n  // Insert style lines before the closing of the diagram\n  // The base mermaid ends with classDef/class lines or just edges.\n  // We append our style lines at the end.\n  return baseMermaid.trimEnd() + '\\n' + styleLines.join('\\n') + '\\n';\n}\n","import { execSync } from 'node:child_process';\n\n/**\n * Parse a source argument that can be:\n * - A file path (./src/foo.ts)\n * - A git ref:path combo (HEAD~1:src/foo.ts or main:src/foo.ts)\n * - A PR URL (https://github.com/org/repo/pull/123)\n */\nexport function parseSourceArg(arg: string): {\n  kind: 'file' | 'git-ref' | 'github-pr';\n  filePath?: string;\n  ref?: string;\n  prUrl?: string;\n} {\n  // GitHub PR URL\n  if (/^https?:\\/\\/github\\.com\\/.+\\/pull\\/\\d+/.test(arg)) {\n    return { kind: 'github-pr', prUrl: arg };\n  }\n\n  // Git ref:path format (e.g. HEAD~1:src/foo.ts, main:src/foo.ts)\n  // Exclude Windows absolute paths (C:\\..., D:\\...) — single letter before colon followed by backslash\n  const gitRefMatch = /^([^:]+):(.+)$/.exec(arg);\n  if (gitRefMatch?.[1] && gitRefMatch[2] && !arg.startsWith('/') && !arg.startsWith('.')) {\n    const isWindowsPath = /^[A-Za-z]$/.test(gitRefMatch[1]) && gitRefMatch[2].startsWith('\\\\');\n    if (!isWindowsPath) {\n      return { kind: 'git-ref', ref: gitRefMatch[1], filePath: gitRefMatch[2] };\n    }\n  }\n\n  // Plain file path\n  return { kind: 'file', filePath: arg };\n}\n\n/**\n * Resolve a git ref:path to the file contents from that commit.\n * Returns the source text of the file at the given ref.\n */\nexport function resolveGitSource(ref: string, filePath: string, cwd?: string): string {\n  try {\n    const result = execSync(`git show ${ref}:${filePath}`, {\n      cwd: cwd ?? process.cwd(),\n      encoding: 'utf-8',\n      stdio: ['pipe', 'pipe', 'pipe'],\n    });\n    return result;\n  } catch (error) {\n    const msg = error instanceof Error ? error.message : String(error);\n    throw new Error(`Failed to resolve git source ${ref}:${filePath}: ${msg}`, { cause: error });\n  }\n}\n\n/**\n * Resolve a GitHub PR URL to the base and head refs.\n * Requires `gh` CLI to be installed and authenticated.\n */\nexport function resolveGitHubPR(\n  prUrl: string,\n): { baseRef: string; headRef: string; baseBranch: string; headBranch: string } {\n  try {\n    const result = execSync(\n      `gh pr view \"${prUrl}\" --json baseRefName,headRefName,baseRefOid,headRefOid`,\n      {\n        encoding: 'utf-8',\n        stdio: ['pipe', 'pipe', 'pipe'],\n      },\n    );\n    const data = JSON.parse(result) as {\n      baseRefName: string;\n      headRefName: string;\n      baseRefOid: string;\n      headRefOid: string;\n    };\n    return {\n      baseRef: data.baseRefOid,\n      headRef: data.headRefOid,\n      baseBranch: data.baseRefName,\n      headBranch: data.headRefName,\n    };\n  } catch (error) {\n    const msg = error instanceof Error ? error.message : String(error);\n    throw new Error(`Failed to resolve GitHub PR ${prUrl}: ${msg}`, { cause: error });\n  }\n}\n","import { Option } from 'effect';\nimport { DEFAULT_LABEL_MAX, escapeMermaidLabel as escapeLabel, truncateDisplayText } from '../analysis-utils';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { splitTopLevelUnion } from '../type-extractor';\n\ninterface RailwayStep {\n  readonly label: string;\n  readonly errorTypes: readonly string[];\n}\n\ninterface RailwayOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n/** Generate a short node ID: A–Z, then A1–Z1, A2–Z2, etc. */\nfunction stepId(index: number): string {\n  const letter = String.fromCharCode(65 + (index % 26));\n  const cycle = Math.floor(index / 26);\n  return cycle === 0 ? letter : `${letter}${cycle}`;\n}\n\n/** Strip trailing \"Error\" or \"Exception\" suffix from a type name. */\nfunction stripErrorSuffix(name: string): string {\n  return name.replace(/(Error|Exception)$/, '');\n}\n\n/** Extract error types string from a node, split into individual type names. */\nfunction extractErrorTypes(node: StaticFlowNode): readonly string[] {\n  let raw: string | undefined;\n\n  if (node.type === 'effect') {\n    raw = node.typeSignature?.errorType ?? node.errorType;\n  } else if ('typeSignature' in node && node.typeSignature) {\n    raw = (node.typeSignature as { errorType?: string }).errorType;\n  }\n\n  if (!raw || raw === 'never' || raw.trim() === '') return [];\n\n  return splitTopLevelUnion(raw)\n    .filter(s => s !== 'never');\n}\n\n/** Recursively collect error types from a node and its descendants. */\nfunction collectErrorTypes(node: StaticFlowNode): readonly string[] {\n  const seen = new Set<string>();\n  const errors: string[] = [];\n\n  const visit = (current: StaticFlowNode): void => {\n    for (const errorType of extractErrorTypes(current)) {\n      if (!seen.has(errorType)) {\n        seen.add(errorType);\n        errors.push(errorType);\n      }\n    }\n\n    const children = Option.getOrElse(getStaticChildren(current), () => []);\n    for (const child of children) {\n      visit(child);\n    }\n  };\n\n  visit(node);\n  return errors;\n}\n\n/**\n * Compute a display label for a flow node. `binding` is the generator variable\n * the step's result was yielded into — it lives on the yield, not on the node,\n * so it has to be threaded in.\n */\nfunction computeLabel(node: StaticFlowNode, binding?: string): string {\n  const raw = ((): string => {\n    if (node.displayName) return node.displayName;\n    if (node.type === 'effect') {\n      if (node.name) {\n        const stripped = node.name.replace(/^Effect\\./, '');\n        return stripped.charAt(0).toUpperCase() + stripped.slice(1);\n      }\n      return node.callee.replace(/^Effect\\./, '');\n    }\n    if (node.name) return node.name;\n    if (node.type === 'parallel') return 'Effect.all';\n    if (node.type === 'race') return 'Effect.race';\n    if (node.type === 'error-handler') return 'Error Handler';\n    if (node.type === 'retry') return 'Retry';\n    if (node.type === 'conditional') return 'Conditional';\n    return node.type;\n  })();\n  const labelled = binding === undefined ? raw : `${binding} <- ${raw}`;\n  return truncateDisplayText(labelled, DEFAULT_LABEL_MAX);\n}\n\n/** Transparent: recurse into children, don't show this node itself. */\nfunction isTransparentRailwayNode(node: StaticFlowNode): boolean {\n  switch (node.type) {\n    case 'generator':\n    case 'pipe':\n      return true;\n    default:\n      return false;\n  }\n}\n\n/** Show as a single labeled step — don't recurse into children. */\nfunction isOpaqueRailwayStep(node: StaticFlowNode): boolean {\n  switch (node.type) {\n    case 'loop':\n    case 'conditional':\n    case 'decision':\n    case 'switch':\n    case 'parallel':\n    case 'race':\n    case 'retry':\n    case 'timeout':\n    case 'resource':\n      return true;\n    default:\n      return false;\n  }\n}\n\n/** Skip entirely — don't show, don't recurse. Shown in other views. */\nfunction isSkippedRailwayNode(node: StaticFlowNode): boolean {\n  switch (node.type) {\n    case 'error-handler':\n    case 'transform':\n    case 'stream':\n    case 'channel':\n    case 'sink':\n    case 'concurrency-primitive':\n    case 'fiber':\n    case 'interruption':\n    case 'try-catch':\n    case 'terminal':\n      return true;\n    default:\n      return false;\n  }\n}\n\n/**\n * A declaration rather than a step: a service method definition or a type\n * declaration. Never appears in the railway however it was reached.\n */\nfunction isDefinitionNode(node: StaticFlowNode): boolean {\n  if (node.type !== 'effect') return false;\n  const callee = (node as { callee?: string }).callee ?? '';\n  return (\n    callee === 'Effect.fn' ||\n    callee.startsWith('Effect.fn(') ||\n    callee.startsWith('Schema.') ||\n    callee.startsWith('Data.')\n  );\n}\n\n/**\n * An effect node the source never named — no display name and no variable. On\n * its own that is setup plumbing, not a step the reader cares about.\n */\nfunction isAnonymousEffect(node: StaticFlowNode): boolean {\n  if (node.type !== 'effect') return false;\n  const name = node.displayName ?? node.name ?? '';\n  return !name || name === node.type;\n}\n\n/**\n * How the walk reached a node. A generator `yield*` is the program awaiting a\n * step, so it counts whether or not its result was bound to a name; anything\n * else is only a step if the source named it.\n */\ntype Arrival =\n  | { readonly kind: 'yielded'; readonly binding: string | undefined }\n  | { readonly kind: 'nested' };\n\nconst NESTED: Arrival = { kind: 'nested' };\n\nconst bindingOf = (arrival: Arrival): string | undefined =>\n  arrival.kind === 'yielded' ? arrival.binding : undefined;\n\n/** A concrete railway step and the generator binding that named it, if any. */\ninterface FlatStep {\n  readonly node: StaticFlowNode;\n  readonly binding?: string;\n}\n\n/** Flatten IR children to a linear list of concrete steps for the railway diagram. */\nfunction flattenNodesToSteps(nodes: readonly StaticFlowNode[]): readonly FlatStep[] {\n  const steps: FlatStep[] = [];\n\n  const visit = (node: StaticFlowNode, arrival: Arrival): void => {\n    // A generator's bindings live on its yields, so recurse over those directly\n    // rather than through `getStaticChildren`, which drops the variable name.\n    if (node.type === 'generator') {\n      for (const yielded of node.yields) {\n        visit(yielded.effect, { kind: 'yielded', binding: yielded.variableName });\n      }\n      return;\n    }\n\n    // Transparent: recurse into children (pipe wrappers). The arrival belongs to\n    // the pipe's subject — its first child — not to its transformations.\n    if (isTransparentRailwayNode(node)) {\n      const children = Option.getOrElse(getStaticChildren(node), () => []);\n      children.forEach((child, index) => {\n        visit(child, index === 0 ? arrival : NESTED);\n      });\n      return;\n    }\n\n    // Skip entirely: error handlers, transforms, streams, etc.\n    if (isSkippedRailwayNode(node)) return;\n\n    const binding = bindingOf(arrival);\n    const push = (): void => {\n      steps.push({ node, ...(binding !== undefined ? { binding } : {}) });\n    };\n\n    // Opaque: shown as a single box, never recursed into (loops, conditionals,\n    // parallel, race, retry, timeout, resource).\n    if (isOpaqueRailwayStep(node)) {\n      push();\n      return;\n    }\n\n    // Declarations are never steps; unnamed effects are steps only when a\n    // generator awaited them.\n    if (isDefinitionNode(node)) return;\n    if (arrival.kind === 'nested' && isAnonymousEffect(node)) return;\n\n    push();\n  };\n\n  for (const node of nodes) {\n    visit(node, NESTED);\n  }\n\n  return steps;\n}\n\n/** Build railway step descriptors from flow nodes. */\nfunction buildSteps(flat: readonly FlatStep[]): readonly RailwayStep[] {\n  return flat.map(({ node, binding }) => ({\n    label: computeLabel(node, binding),\n    errorTypes: collectErrorTypes(node),\n  }));\n}\n\n/**\n * Render a railway-oriented Mermaid flowchart from an Effect IR.\n *\n * Happy path flows left-to-right with `-->|ok|` edges.\n * Steps with typed errors get `-->|err|` branches to error nodes.\n */\nexport function renderRailwayMermaid(\n  ir: StaticEffectIR,\n  options: RailwayOptions = {},\n): string {\n  const direction = options.direction ?? 'LR';\n  const nodes = flattenNodesToSteps(ir.root.children);\n  const steps = buildSteps(nodes);\n\n  if (steps.length === 0) {\n    return `flowchart ${direction}\\n  Empty((No steps))`;\n  }\n\n  const lines: string[] = [`flowchart ${direction}`];\n  const errorLines: string[] = [];\n\n  const hasPerStepErrors = steps.some(s => s.errorTypes.length > 0);\n\n  for (let i = 0; i < steps.length; i++) {\n    const currentStep = steps[i];\n    if (!currentStep) continue;\n    const id = stepId(i);\n    const label = escapeLabel(currentStep.label);\n\n    if (i < steps.length - 1) {\n      const nextStep = steps[i + 1];\n      if (!nextStep) continue;\n      const nextId = stepId(i + 1);\n      const nextLabel = escapeLabel(nextStep.label);\n      if (i === 0) {\n        lines.push(`  ${id}[\"${label}\"] -->|ok| ${nextId}[\"${nextLabel}\"]`);\n      } else {\n        lines.push(`  ${id} -->|ok| ${nextId}[\"${nextLabel}\"]`);\n      }\n    } else {\n      if (i === 0) {\n        lines.push(`  ${id}[\"${label}\"] -->|ok| Done((Success))`);\n      } else {\n        lines.push(`  ${id} -->|ok| Done((Success))`);\n      }\n    }\n  }\n\n  if (hasPerStepErrors) {\n    for (let i = 0; i < steps.length; i++) {\n      const currentStep = steps[i];\n      if (!currentStep) continue;\n      const { errorTypes } = currentStep;\n      if (errorTypes.length === 0) continue;\n\n      const id = stepId(i);\n      const errId = `${id}E`;\n      const errLabel = escapeLabel(\n        errorTypes.map(stripErrorSuffix).join(' / ')\n      );\n      errorLines.push(`  ${id} -->|err| ${errId}[\"${errLabel}\"]`);\n    }\n  } else if (ir.root.errorTypes.length > 0) {\n    const lastId = stepId(steps.length - 1);\n    const errLabel = escapeLabel(\n      ir.root.errorTypes.map(stripErrorSuffix).join(' / ')\n    );\n    errorLines.push(`  ${lastId} -->|err| Errors[\"${errLabel}\"]`);\n  }\n\n  return [...lines, ...errorLines].join('\\n');\n}\n","/**\n * Service (R) Flow Analysis (GAP 3)\n *\n * Tracks which services each effect requires, where they are provided,\n * and where R is still unsatisfied.\n */\n\nimport type {\n  StaticEffectIR,\n  StaticFlowNode,\n  StaticEffectNode,\n  ServiceRequirement,\n  SourceLocation,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ServiceProvision {\n  nodeId: string;\n  serviceId: string;\n  location?: SourceLocation;\n}\n\nexport interface UnsatisfiedService {\n  nodeId: string;\n  serviceId: string;\n  serviceType?: string;\n  location?: SourceLocation;\n}\n\nexport interface ServiceLifecycleEntry {\n  createdAt: string;\n  consumedAt: string[];\n  releasedAt?: string;\n}\n\nexport interface ServiceFlowAnalysis {\n  requiredServices: ServiceRequirement[];\n  providedServices: ServiceProvision[];\n  unsatisfiedAt: UnsatisfiedService[];\n  serviceLifecycle: Map<string, ServiceLifecycleEntry>;\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction collectRequiredFromNode(\n  node: StaticFlowNode,\n  result: ServiceRequirement[],\n): void {\n  if (node.type === 'effect') {\n    const eff = node;\n    const reqs = eff.requiredServices ?? [];\n    for (const r of reqs) {\n      if (!result.some((x) => x.serviceId === r.serviceId)) {\n        result.push(r);\n      }\n    }\n  }\n  const children = Option.getOrElse(getStaticChildren(node), () => []);\n  for (const c of children) collectRequiredFromNode(c, result);\n}\n\n/** Heuristic: detect provide/provideService from effect callee and first arg. */\nfunction getProvidedServiceId(\n  node: StaticEffectNode,\n  getFirstArgText: (node: StaticEffectNode) => string | undefined,\n): string | undefined {\n  const callee = node.callee;\n  if (callee.includes('provideService') || callee.includes('provide')) {\n    return getFirstArgText(node);\n  }\n  return undefined;\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\n/**\n * Build service flow analysis from IR.\n * Tracks required vs provided services and unsatisfied requirements at each node.\n */\nexport function analyzeServiceFlow(\n  ir: StaticEffectIR,\n  options?: {\n    /** Optional: resolve effect node to its AST to read first arg (for provideService). */\n    getFirstArgText?: (effectNode: StaticEffectNode) => string | undefined;\n  },\n): ServiceFlowAnalysis {\n  const requiredServices: ServiceRequirement[] = [];\n  for (const child of ir.root.children) {\n    collectRequiredFromNode(child, requiredServices);\n  }\n  const dedupedRequired = Array.from(\n    new Map(requiredServices.map((r) => [r.serviceId, r])).values(),\n  );\n\n  const providedServices: ServiceProvision[] = [];\n  const unsatisfiedAt: UnsatisfiedService[] = [];\n  const consumedBy = new Map<string, string[]>();\n\n  const available = new Set<string>();\n  const getFirstArg = options?.getFirstArgText;\n\n  function walk(nodes: readonly StaticFlowNode[]) {\n    for (const node of nodes) {\n      if (node.type === 'effect') {\n        const eff = node;\n        const providedId = getFirstArg ? getProvidedServiceId(eff, getFirstArg) : undefined;\n        if (providedId) {\n          available.add(providedId);\n          const prov: ServiceProvision = { nodeId: eff.id, serviceId: providedId };\n          if (eff.location) prov.location = eff.location;\n          providedServices.push(prov);\n        }\n        const reqs = eff.requiredServices ?? [];\n        for (const r of reqs) {\n          const list = consumedBy.get(r.serviceId) ?? [];\n          list.push(eff.id);\n          consumedBy.set(r.serviceId, list);\n          if (!available.has(r.serviceId)) {\n            const u: UnsatisfiedService = { nodeId: eff.id, serviceId: r.serviceId };\n            if (r.serviceType !== undefined) u.serviceType = r.serviceType;\n            if (r.requiredAt !== undefined) u.location = r.requiredAt;\n            unsatisfiedAt.push(u);\n          }\n        }\n      }\n      const children = Option.getOrElse(getStaticChildren(node), () => []);\n      if (children.length > 0) walk(children);\n    }\n  }\n  walk(ir.root.children);\n\n  const serviceLifecycle = new Map<string, ServiceLifecycleEntry>();\n  for (const p of providedServices) {\n    serviceLifecycle.set(p.serviceId, {\n      createdAt: p.nodeId,\n      consumedAt: consumedBy.get(p.serviceId) ?? [],\n    });\n  }\n  for (const r of dedupedRequired) {\n    if (!serviceLifecycle.has(r.serviceId)) {\n      serviceLifecycle.set(r.serviceId, {\n        createdAt: '',\n        consumedAt: consumedBy.get(r.serviceId) ?? [],\n      });\n    }\n  }\n\n  return {\n    requiredServices: dedupedRequired,\n    providedServices,\n    unsatisfiedAt,\n    serviceLifecycle,\n  };\n}\n","/**\n * Mermaid renderer for the R channel (service/dependency) graph.\n *\n * Two modes:\n * - Single-file: `renderServicesMermaid(ir)` — shows required vs provided services for one program.\n * - Project-wide: `renderServicesMermaidFromMap(serviceMap)` — shows the full service dependency graph.\n */\n\nimport type { StaticEffectIR, ProjectServiceMap } from '../types';\nimport { analyzeServiceFlow } from '../service-flow';\nimport { escapeMermaidLabel as escapeLabel } from '../analysis-utils';\n\ninterface ServicesOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\nfunction sanitizeId(text: string): string {\n  return text.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n/**\n * Render a Mermaid flowchart showing the R channel for a single IR.\n *\n * - Program node as a rectangle\n * - Required services as blue hexagons with `requires` edges\n * - Provided services as green hexagons with `provides` edges\n */\nexport function renderServicesMermaid(\n  ir: StaticEffectIR,\n  options: ServicesOptions = {},\n): string {\n  const direction = options.direction ?? 'LR';\n  const { requiredServices, providedServices } = analyzeServiceFlow(ir);\n\n  // Also collect dependencies from the IR root (includes environment yields)\n  const depsFromIR = ir.root.dependencies;\n  const allServiceIds = new Set<string>();\n  for (const req of requiredServices) allServiceIds.add(req.serviceId);\n  for (const dep of depsFromIR) allServiceIds.add(dep.name);\n\n  if (allServiceIds.size === 0 && providedServices.length === 0) {\n    return `flowchart ${direction}\\n  NoServices((No services))`;\n  }\n\n  const lines: string[] = [`flowchart ${direction}`];\n  const programName = escapeLabel(ir.root.programName);\n\n  lines.push(`  prog[\"${programName}\"]`);\n  lines.push('');\n\n  // Required services — hexagon nodes with requires edges\n  // Combine from analyzeServiceFlow and IR root dependencies\n  for (const serviceId of allServiceIds) {\n    const id = `svc_${sanitizeId(serviceId)}`;\n    const label = escapeLabel(serviceId);\n    lines.push(`  ${id}{{\"${label}\"}}`);\n    lines.push(`  prog -->|requires| ${id}`);\n  }\n\n  // Provided services — hexagon nodes with provides edges\n  for (const prov of providedServices) {\n    const id = `prov_${sanitizeId(prov.serviceId)}`;\n    const label = escapeLabel(prov.serviceId);\n    lines.push(`  ${id}{{\"${label}\"}}`);\n    lines.push(`  ${id} -->|provides| prog`);\n  }\n\n  lines.push('');\n\n  // Styling\n  lines.push('  classDef required fill:#E3F2FD,stroke:#1565C0,stroke-width:2px');\n  lines.push('  classDef provided fill:#E8F5E9,stroke:#2E7D32,stroke-width:2px');\n  for (const req of requiredServices) {\n    lines.push(`  class svc_${sanitizeId(req.serviceId)} required`);\n  }\n  for (const prov of providedServices) {\n    lines.push(`  class prov_${sanitizeId(prov.serviceId)} provided`);\n  }\n\n  return lines.join('\\n');\n}\n\n/**\n * Render a Mermaid flowchart for a project-wide service dependency graph.\n *\n * - Each service is a hexagon node\n * - Edges show layer dependencies\n * - Unresolved services are dashed\n */\nexport function renderServicesMermaidFromMap(\n  serviceMap: ProjectServiceMap,\n  options: ServicesOptions = {},\n): string {\n  const direction = options.direction ?? 'TB';\n  const lines: string[] = [`flowchart ${direction}`];\n  lines.push('');\n  lines.push('  %% Service Dependency Graph');\n  lines.push('');\n\n  // Service nodes (hexagon shape)\n  for (const [serviceId, artifact] of serviceMap.services) {\n    const id = sanitizeId(serviceId);\n    const methodCount = artifact.definition.methods.length;\n    const label =\n      methodCount > 0\n        ? `${serviceId}\\\\n(${methodCount} method${methodCount === 1 ? '' : 's'})`\n        : serviceId;\n    lines.push(`  ${id}{{\"${label}\"}}`);\n  }\n\n  // Unresolved services (dashed)\n  for (const serviceId of serviceMap.unresolvedServices) {\n    const id = `unresolved_${sanitizeId(serviceId)}`;\n    lines.push(`  ${id}[\"? ${serviceId}\"]`);\n  }\n  lines.push('');\n\n  // Edges: service requires other services (via layers)\n  const edgesAdded = new Set<string>();\n  for (const [serviceId, artifact] of serviceMap.services) {\n    for (const layer of artifact.layerImplementations) {\n      for (const req of layer.requires) {\n        const edgeKey = `${serviceId}->${req}`;\n        if (edgesAdded.has(edgeKey)) continue;\n        edgesAdded.add(edgeKey);\n\n        const fromId = sanitizeId(serviceId);\n        const toId = serviceMap.services.has(req)\n          ? sanitizeId(req)\n          : `unresolved_${sanitizeId(req)}`;\n        lines.push(`  ${fromId} -->|\"${layer.name}\"| ${toId}`);\n      }\n    }\n  }\n  lines.push('');\n\n  // Styling\n  lines.push('  classDef service fill:#E3F2FD,stroke:#1565C0,stroke-width:2px');\n  lines.push('  classDef unresolved fill:#FFF3CD,stroke:#856404,stroke-dasharray:5');\n  for (const serviceId of serviceMap.services.keys()) {\n    lines.push(`  class ${sanitizeId(serviceId)} service`);\n  }\n  for (const serviceId of serviceMap.unresolvedServices) {\n    lines.push(`  class unresolved_${sanitizeId(serviceId)} unresolved`);\n  }\n\n  return lines.join('\\n');\n}\n","import type { StaticEffectIR } from '../types';\nimport { analyzeErrorFlow } from '../error-flow';\nimport { analyzeErrorPropagation } from '../error-flow';\nimport { escapeMermaidLabel as escapeLabel } from '../analysis-utils';\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\n/** Replace non-alphanumeric characters with underscores for Mermaid node IDs. */\nfunction sanitizeId(text: string): string {\n  return text.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n/** Strip trailing \"Error\" or \"Exception\" suffix from a type name. */\nfunction stripErrorSuffix(name: string): string {\n  return name.replace(/(Error|Exception)$/, '');\n}\n\n// =============================================================================\n// Options\n// =============================================================================\n\ninterface MermaidErrorsOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n// =============================================================================\n// Renderer\n// =============================================================================\n\n/**\n * Render a Mermaid flowchart showing error propagation:\n * - Steps (left): which steps produce errors\n * - Error types (middle): the error type nodes\n * - Handlers (right): which handlers catch which errors\n * - Unhandled: errors that are never caught\n */\nexport function renderErrorsMermaid(\n  ir: StaticEffectIR,\n  options: MermaidErrorsOptions = {},\n): string {\n  const direction = options.direction ?? 'LR';\n  const errorFlow = analyzeErrorFlow(ir);\n  const propagation = analyzeErrorPropagation(ir);\n\n  // No errors at all → simple empty output\n  if (errorFlow.allErrors.length === 0) {\n    return `flowchart ${direction}\\n  NoErrors((No errors))`;\n  }\n\n  const lines: string[] = [`flowchart ${direction}`];\n\n  // Collect handler info from propagation analysis\n  const handlerNodes: { id: string; label: string; removedErrors: string[] }[] = [];\n  const handledErrors = new Set<string>();\n\n  for (const p of propagation.propagation) {\n    if (p.narrowedBy && p.narrowedBy.removedErrors.length > 0) {\n      const handlerId = `handler_${sanitizeId(p.atNode)}`;\n      handlerNodes.push({\n        id: handlerId,\n        label: p.narrowedBy.handler,\n        removedErrors: p.narrowedBy.removedErrors,\n      });\n      for (const err of p.narrowedBy.removedErrors) {\n        handledErrors.add(err);\n      }\n    }\n  }\n\n  // Determine unhandled errors\n  const unhandledErrors = errorFlow.allErrors.filter(e => !handledErrors.has(e));\n\n  // --- Steps subgraph (left column) ---\n  const stepsWithErrors = errorFlow.stepErrors.filter(s => s.errors.length > 0);\n  if (stepsWithErrors.length > 0) {\n    lines.push('');\n    lines.push('  subgraph Steps');\n    for (const step of stepsWithErrors) {\n      const label = escapeLabel(step.stepName ?? step.stepId);\n      lines.push(`    step_${sanitizeId(step.stepId)}[\"${label}\"]`);\n    }\n    lines.push('  end');\n  }\n\n  // --- Error types subgraph (middle column) ---\n  lines.push('');\n  lines.push('  subgraph Errors');\n  for (const error of errorFlow.allErrors) {\n    const label = escapeLabel(stripErrorSuffix(error));\n    lines.push(`    err_${sanitizeId(error)}(\"${label}\")`);\n  }\n  lines.push('  end');\n\n  // --- Handlers subgraph (right column) ---\n  if (handlerNodes.length > 0) {\n    lines.push('');\n    lines.push('  subgraph Handlers');\n    for (const handler of handlerNodes) {\n      const label = escapeLabel(handler.label);\n      lines.push(`    ${handler.id}[\"${label}\"]`);\n    }\n    lines.push('  end');\n  }\n\n  // --- Unhandled node ---\n  if (unhandledErrors.length > 0) {\n    lines.push('');\n    lines.push('  UNHANDLED[\"UNHANDLED\"]');\n  }\n\n  // --- Edges: step --produces--> error ---\n  lines.push('');\n  for (const step of stepsWithErrors) {\n    for (const error of step.errors) {\n      lines.push(`  step_${sanitizeId(step.stepId)} --produces--> err_${sanitizeId(error)}`);\n    }\n  }\n\n  // --- Edges: error --caught by--> handler ---\n  for (const handler of handlerNodes) {\n    for (const error of handler.removedErrors) {\n      if (errorFlow.allErrors.includes(error)) {\n        lines.push(`  err_${sanitizeId(error)} --caught by--> ${handler.id}`);\n      }\n    }\n  }\n\n  // --- Edges: unhandled errors --> UNHANDLED ---\n  for (const error of unhandledErrors) {\n    lines.push(`  err_${sanitizeId(error)} --unhandled--> UNHANDLED`);\n  }\n\n  // --- Styling ---\n  lines.push('');\n  lines.push('  classDef stepStyle fill:#BBDEFB');\n  lines.push('  classDef errorStyle fill:#FFE0B2');\n  lines.push('  classDef handlerStyle fill:#C8E6C9');\n  lines.push('  classDef unhandledStyle fill:#FFCDD2');\n\n  // Apply styles\n  for (const step of stepsWithErrors) {\n    lines.push(`  class step_${sanitizeId(step.stepId)} stepStyle`);\n  }\n  for (const error of errorFlow.allErrors) {\n    lines.push(`  class err_${sanitizeId(error)} errorStyle`);\n  }\n  for (const handler of handlerNodes) {\n    lines.push(`  class ${handler.id} handlerStyle`);\n  }\n  if (unhandledErrors.length > 0) {\n    lines.push('  class UNHANDLED unhandledStyle');\n  }\n\n  return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { escapeMermaidLabel as escapeLabel } from '../analysis-utils';\n\ninterface DecisionsOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\nconst DECISION_TYPES = new Set(['conditional', 'decision', 'switch', 'match']);\n\n/** Truncate text to a maximum length, appending ellipsis if needed. */\nfunction truncate(text: string, max = 40): string {\n  return text.length > max ? text.slice(0, max - 3) + '...' : text;\n}\n\n/** Compute a display label for a flow node. */\nfunction nodeLabel(node: StaticFlowNode): string {\n  if (node.displayName) return node.displayName;\n  if (node.name) return node.name;\n  if (node.type === 'effect') return node.callee;\n  return node.type;\n}\n\ninterface DecisionInfo {\n  readonly node: StaticFlowNode;\n  readonly nodeId: string;\n}\n\n/** Recursively collect all decision-type nodes from the IR tree. */\nfunction collectDecisionNodes(nodes: readonly StaticFlowNode[]): DecisionInfo[] {\n  const result: DecisionInfo[] = [];\n  let counter = 0;\n\n  const visit = (node: StaticFlowNode): void => {\n    if (DECISION_TYPES.has(node.type)) {\n      result.push({ node, nodeId: `D${counter++}` });\n    }\n\n    // Walk into children from getStaticChildren\n    const children = Option.getOrElse(getStaticChildren(node), () => [] as readonly StaticFlowNode[]);\n    for (const child of children) {\n      visit(child);\n    }\n\n    // Also walk into branch-specific children not covered by getStaticChildren\n    if (node.type === 'conditional') {\n      const cond = node;\n      visit(cond.onTrue);\n      if (cond.onFalse) visit(cond.onFalse);\n    } else if (node.type === 'decision') {\n      const dec = node;\n      for (const child of dec.onTrue) visit(child);\n      if (dec.onFalse) for (const child of dec.onFalse) visit(child);\n    } else if (node.type === 'switch') {\n      const sw = node;\n      for (const c of sw.cases) {\n        for (const child of c.body) visit(child);\n      }\n    }\n  };\n\n  for (const node of nodes) {\n    visit(node);\n  }\n\n  return result;\n}\n\n/** Find a decision info entry by node reference. */\nfunction findDecisionInfo(decisions: DecisionInfo[], node: StaticFlowNode): DecisionInfo | undefined {\n  return decisions.find(d => d.node === node);\n}\n\n/** Find the first decision node in a list of nodes. */\nfunction findFirstDecision(decisions: DecisionInfo[], nodes: readonly StaticFlowNode[]): DecisionInfo | undefined {\n  for (const node of nodes) {\n    const found = findDecisionInfo(decisions, node);\n    if (found) return found;\n  }\n  return undefined;\n}\n\n/** Render a terminal node ID and its definition line for a branch target. */\nfunction renderBranchTarget(\n  node: StaticFlowNode | undefined,\n  decisions: DecisionInfo[],\n  terminalCounter: { value: number },\n): { targetId: string; extraLine?: string } {\n  if (!node) {\n    const tId = `T${terminalCounter.value++}`;\n    return { targetId: tId, extraLine: `  ${tId}[\"...\"]` };\n  }\n\n  const decInfo = findDecisionInfo(decisions, node);\n  if (decInfo) {\n    return { targetId: decInfo.nodeId };\n  }\n\n  const label = escapeLabel(nodeLabel(node));\n  const tId = `T${terminalCounter.value++}`;\n  return { targetId: tId, extraLine: `  ${tId}[\"${label}\"]` };\n}\n\n/** Render a branch target from an array of nodes. */\nfunction renderArrayBranchTarget(\n  nodes: readonly StaticFlowNode[] | undefined,\n  decisions: DecisionInfo[],\n  terminalCounter: { value: number },\n): { targetId: string; extraLine?: string } {\n  if (!nodes || nodes.length === 0) {\n    const tId = `T${terminalCounter.value++}`;\n    return { targetId: tId, extraLine: `  ${tId}[\"...\"]` };\n  }\n\n  // Check if any node in the array is a decision node\n  const dec = findFirstDecision(decisions, nodes);\n  if (dec) {\n    return { targetId: dec.nodeId };\n  }\n\n  const firstNode = nodes[0];\n  if (!firstNode) {\n    const tId = `T${terminalCounter.value++}`;\n    return { targetId: tId, extraLine: `  ${tId}[\"...\"]` };\n  }\n  const label = escapeLabel(nodeLabel(firstNode));\n  const tId = `T${terminalCounter.value++}`;\n  return { targetId: tId, extraLine: `  ${tId}[\"${label}\"]` };\n}\n\n/**\n * Render a decision-tree Mermaid flowchart from an Effect IR.\n *\n * Decision nodes (conditional, decision, switch, match) are rendered as\n * diamond-shaped nodes with labeled edges to their branches.\n */\nexport function renderDecisionsMermaid(\n  ir: StaticEffectIR,\n  options: DecisionsOptions = {},\n): string {\n  const direction = options.direction ?? 'TB';\n  const decisions = collectDecisionNodes(ir.root.children);\n\n  if (decisions.length === 0) {\n    return `flowchart ${direction}\\n  NoDec((No decisions))`;\n  }\n\n  const lines: string[] = [`flowchart ${direction}`];\n  const terminalCounter = { value: 0 };\n\n  for (const { node, nodeId } of decisions) {\n    switch (node.type) {\n      case 'conditional': {\n        const cond = node;\n        const condText = escapeLabel(truncate(cond.condition));\n        lines.push(`  ${nodeId}{${condText}}`);\n\n        const trueLabel = cond.trueEdgeLabel ?? 'true';\n        const falseLabel = cond.falseEdgeLabel ?? 'false';\n\n        const trueBranch = renderBranchTarget(cond.onTrue, decisions, terminalCounter);\n        if (trueBranch.extraLine) lines.push(trueBranch.extraLine);\n        lines.push(`  ${nodeId} -->|${trueLabel}| ${trueBranch.targetId}`);\n\n        if (cond.onFalse) {\n          const falseBranch = renderBranchTarget(cond.onFalse, decisions, terminalCounter);\n          if (falseBranch.extraLine) lines.push(falseBranch.extraLine);\n          lines.push(`  ${nodeId} -->|${falseLabel}| ${falseBranch.targetId}`);\n        }\n        break;\n      }\n\n      case 'decision': {\n        const dec = node;\n        const condText = escapeLabel(truncate(dec.condition));\n        lines.push(`  ${nodeId}{${condText}}`);\n\n        const trueBranch = renderArrayBranchTarget(dec.onTrue, decisions, terminalCounter);\n        if (trueBranch.extraLine) lines.push(trueBranch.extraLine);\n        lines.push(`  ${nodeId} -->|true| ${trueBranch.targetId}`);\n\n        if (dec.onFalse) {\n          const falseBranch = renderArrayBranchTarget(dec.onFalse, decisions, terminalCounter);\n          if (falseBranch.extraLine) lines.push(falseBranch.extraLine);\n          lines.push(`  ${nodeId} -->|false| ${falseBranch.targetId}`);\n        }\n        break;\n      }\n\n      case 'switch': {\n        const sw = node;\n        const exprText = escapeLabel(truncate(sw.expression));\n        lines.push(`  ${nodeId}{${exprText}}`);\n\n        for (const c of sw.cases) {\n          const caseLabel = c.isDefault ? 'default' : c.labels.join(', ');\n          const caseBranch = renderArrayBranchTarget(c.body, decisions, terminalCounter);\n          if (caseBranch.extraLine) lines.push(caseBranch.extraLine);\n          lines.push(`  ${nodeId} -->|${caseLabel}| ${caseBranch.targetId}`);\n        }\n        break;\n      }\n\n      case 'match': {\n        const m = node;\n        const matchLabel = escapeLabel(`Match.${m.matchOp}`);\n        lines.push(`  ${nodeId}{${matchLabel}}`);\n\n        if (m.matchedTags && m.matchedTags.length > 0) {\n          for (const tag of m.matchedTags) {\n            const tId = `T${terminalCounter.value++}`;\n            lines.push(`  ${tId}[\"${escapeLabel(tag)}\"]`);\n            lines.push(`  ${nodeId} -->|${escapeLabel(tag)}| ${tId}`);\n          }\n        } else {\n          const tId = `T${terminalCounter.value++}`;\n          lines.push(`  ${tId}[\"...\"]`);\n          lines.push(`  ${nodeId} -->|match| ${tId}`);\n        }\n        break;\n      }\n    }\n  }\n\n  return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { DEFAULT_LABEL_MAX, escapeMermaidLabel as escapeLabel, truncateDisplayText } from '../analysis-utils';\n\ninterface CausesOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n/** Replace non-alphanumeric characters with underscores for Mermaid node IDs. */\nfunction sanitizeId(text: string): string {\n  return text.replace(/[^a-zA-Z0-9]/g, '_');\n}\n\n/** Failure patterns for Effect callee matching. */\nconst EFFECT_FAILURE_CALLEES = new Set(['Effect.fail', 'Effect.die', 'Effect.interrupt']);\n\ninterface FailureNode {\n  readonly id: string;\n  readonly kind: 'fail' | 'die' | 'interrupt' | 'parallel' | 'sequential';\n  readonly label: string;\n  readonly children: readonly FailureNode[];\n}\n\n/** Extract error type label from an effect node. */\nfunction getErrorTypeLabel(node: StaticFlowNode): string | undefined {\n  if (node.type === 'effect') {\n    const raw = node.typeSignature?.errorType ?? node.errorType;\n    if (raw && raw !== 'never' && raw.trim() !== '') return raw;\n  }\n  return undefined;\n}\n\n/** Determine failure kind from an Effect callee. */\nfunction calleeToKind(callee: string): 'fail' | 'die' | 'interrupt' {\n  if (callee === 'Effect.die') return 'die';\n  if (callee === 'Effect.interrupt') return 'interrupt';\n  return 'fail';\n}\n\n/** Recursively collect failure-related nodes from the IR tree. */\nfunction collectFailureNodes(node: StaticFlowNode): readonly FailureNode[] {\n  const results: FailureNode[] = [];\n\n  // Check if this node is a failure source\n  if (node.type === 'cause' && node.isConstructor) {\n    const op = node.causeOp;\n\n    if (op === 'parallel' || op === 'sequential') {\n      // Composite cause: collect children recursively\n      const childFailures: FailureNode[] = [];\n      const children = node.children ?? [];\n      for (const child of children) {\n        childFailures.push(...collectFailureNodes(child));\n      }\n      results.push({\n        id: sanitizeId(node.id),\n        kind: op,\n        label: `Cause.${op}`,\n        children: childFailures,\n      });\n      return results;\n    }\n\n    if (op === 'fail' || op === 'die' || op === 'interrupt') {\n      results.push({\n        id: sanitizeId(node.id),\n        kind: op,\n        label: `Cause.${op}`,\n        children: [],\n      });\n      return results;\n    }\n  }\n\n  if (node.type === 'exit' && node.isConstructor) {\n    const op = node.exitOp;\n    if (op === 'fail' || op === 'die' || op === 'interrupt') {\n      results.push({\n        id: sanitizeId(node.id),\n        kind: op === 'fail' ? 'fail' : op === 'die' ? 'die' : 'interrupt',\n        label: `Exit.${op}`,\n        children: [],\n      });\n      return results;\n    }\n  }\n\n  if (node.type === 'effect' && EFFECT_FAILURE_CALLEES.has(node.callee)) {\n    const kind = calleeToKind(node.callee);\n    const errorType = getErrorTypeLabel(node);\n    const label = truncateDisplayText(\n      errorType ? `${node.callee}: ${errorType}` : node.callee,\n      DEFAULT_LABEL_MAX,\n    );\n    results.push({\n      id: sanitizeId(node.id),\n      kind,\n      label,\n      children: [],\n    });\n    return results;\n  }\n\n  // Recurse into children for non-failure nodes\n  const children = Option.getOrElse(getStaticChildren(node), () => []);\n  for (const child of children) {\n    results.push(...collectFailureNodes(child));\n  }\n\n  return results;\n}\n\n/** Render a single failure node and its edges into Mermaid lines. */\nfunction renderFailureNode(\n  node: FailureNode,\n  parentId: string | undefined,\n  edgeLabel: string | undefined,\n  lines: string[],\n  styledNodes: Map<string, 'fail' | 'die' | 'interrupt' | 'composite'>,\n  counter: { value: number },\n): void {\n  const nodeId = `N${counter.value++}`;\n  const escaped = escapeLabel(node.label);\n\n  if (node.kind === 'parallel' || node.kind === 'sequential') {\n    // Composite node — light blue styling\n    lines.push(`  ${nodeId}[${escaped}]`);\n    styledNodes.set(nodeId, 'composite');\n\n    if (parentId) {\n      const edge = edgeLabel ? ` -->|${edgeLabel}| ` : ' --> ';\n      lines.push(`  ${parentId}${edge}${nodeId}`);\n    }\n\n    const childEdgeLabel = node.kind === 'parallel' ? 'parallel' : 'then';\n    for (const child of node.children) {\n      renderFailureNode(child, nodeId, childEdgeLabel, lines, styledNodes, counter);\n    }\n  } else {\n    // Leaf failure node\n    if (node.kind === 'die') {\n      lines.push(`  ${nodeId}[${escaped}]`);\n      styledNodes.set(nodeId, 'die');\n    } else if (node.kind === 'interrupt') {\n      lines.push(`  ${nodeId}[${escaped}]`);\n      styledNodes.set(nodeId, 'interrupt');\n    } else {\n      // fail — rounded rect\n      lines.push(`  ${nodeId}(${escaped})`);\n      styledNodes.set(nodeId, 'fail');\n    }\n\n    if (parentId) {\n      const edge = edgeLabel ? ` -->|${edgeLabel}| ` : ' --> ';\n      lines.push(`  ${parentId}${edge}${nodeId}`);\n    }\n  }\n}\n\n/**\n * Render a Cause-tree Mermaid flowchart from an Effect IR.\n *\n * Shows how errors compose: parallel failures, sequential failures,\n * defects vs expected errors.\n */\nexport function renderCausesMermaid(\n  ir: StaticEffectIR,\n  options: CausesOptions = {},\n): string {\n  const direction = options.direction ?? 'TB';\n\n  // Collect all failure nodes from the IR\n  const failureNodes: FailureNode[] = [];\n  for (const child of ir.root.children) {\n    failureNodes.push(...collectFailureNodes(child));\n  }\n\n  if (failureNodes.length === 0) {\n    return `flowchart ${direction}\\n  NoCauses((No failure causes))`;\n  }\n\n  const lines: string[] = [`flowchart ${direction}`];\n  const styledNodes = new Map<string, 'fail' | 'die' | 'interrupt' | 'composite'>();\n  const counter = { value: 0 };\n\n  // Root node\n  const rootId = 'Root';\n  const programName = escapeLabel(ir.root.programName);\n  lines.push(`  ${rootId}((${programName}))`);\n\n  // Render each top-level failure node\n  for (const node of failureNodes) {\n    renderFailureNode(node, rootId, undefined, lines, styledNodes, counter);\n  }\n\n  // Style definitions\n  lines.push('');\n  lines.push('  classDef failStyle fill:#FFCDD2,stroke:#C62828');\n  lines.push('  classDef dieStyle fill:#B71C1C,color:#fff');\n  lines.push('  classDef interruptStyle fill:#FFE0B2,stroke:#E65100');\n  lines.push('  classDef compositeStyle fill:#E3F2FD');\n\n  // Apply styles\n  const styleGroups: { failStyle: string[]; dieStyle: string[]; interruptStyle: string[]; compositeStyle: string[] } = {\n    failStyle: [],\n    dieStyle: [],\n    interruptStyle: [],\n    compositeStyle: [],\n  };\n\n  for (const [nodeId, kind] of styledNodes) {\n    if (kind === 'fail') styleGroups.failStyle.push(nodeId);\n    else if (kind === 'die') styleGroups.dieStyle.push(nodeId);\n    else if (kind === 'interrupt') styleGroups.interruptStyle.push(nodeId);\n    else styleGroups.compositeStyle.push(nodeId);\n  }\n\n  for (const [className, nodeIds] of Object.entries(styleGroups)) {\n    if (nodeIds.length > 0) {\n      lines.push(`  class ${nodeIds.join(',')} ${className}`);\n    }\n  }\n\n  return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { DEFAULT_LABEL_MAX, escapeMermaidLabel as escapeLabel, truncateDisplayText } from '../analysis-utils';\n\ninterface ConcurrencyOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\ntype ConcurrencyNode =\n  | { kind: 'parallel'; node: Extract<StaticFlowNode, { type: 'parallel' }> }\n  | { kind: 'race'; node: Extract<StaticFlowNode, { type: 'race' }> }\n  | { kind: 'fiber'; node: Extract<StaticFlowNode, { type: 'fiber' }> }\n  | { kind: 'primitive'; node: Extract<StaticFlowNode, { type: 'concurrency-primitive' }> };\n\n/** Generate a short node ID. */\nfunction nodeId(prefix: string, index: number): string {\n  return `${prefix}${index}`;\n}\n\n/** Compute a display label for a child flow node. */\nfunction childLabel(node: StaticFlowNode, index: number): string {\n  const t = (s: string) => truncateDisplayText(s, DEFAULT_LABEL_MAX);\n  if (node.displayName) return t(node.displayName);\n  if (node.name) return t(node.name);\n  if (node.type === 'effect') return t(node.callee);\n  return `child_${index}`;\n}\n\n/** Capitalize a primitive name. */\nfunction capitalize(s: string): string {\n  return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/** Recursively collect concurrency-related nodes from the IR. */\nfunction collectConcurrencyNodes(nodes: readonly StaticFlowNode[]): ConcurrencyNode[] {\n  const result: ConcurrencyNode[] = [];\n\n  const visit = (node: StaticFlowNode): void => {\n    switch (node.type) {\n      case 'parallel':\n        result.push({ kind: 'parallel', node });\n        break;\n      case 'race':\n        result.push({ kind: 'race', node });\n        break;\n      case 'fiber':\n        result.push({ kind: 'fiber', node });\n        break;\n      case 'concurrency-primitive':\n        result.push({ kind: 'primitive', node });\n        break;\n    }\n\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    for (const child of children) {\n      visit(child);\n    }\n  };\n\n  for (const node of nodes) {\n    visit(node);\n  }\n\n  return result;\n}\n\n/**\n * Render a concurrency-focused Mermaid flowchart from an Effect IR.\n *\n * Shows parallel execution, races, fiber forks/joins, and concurrency primitives.\n */\nexport function renderConcurrencyMermaid(\n  ir: StaticEffectIR,\n  options: ConcurrencyOptions = {},\n): string {\n  const direction = options.direction ?? 'TB';\n  const collected = collectConcurrencyNodes(ir.root.children);\n\n  if (collected.length === 0) {\n    return `flowchart ${direction}\\n  NoConcurrency((No concurrency))`;\n  }\n\n  const lines: string[] = [`flowchart ${direction}`];\n  const styleLines: string[] = [];\n  let globalIdx = 0;\n\n  // Track node IDs for execution-order connections\n  const orderedIds: string[] = [];\n\n  for (const entry of collected) {\n    switch (entry.kind) {\n      case 'parallel': {\n        const pNode = entry.node;\n        const pId = nodeId('P', globalIdx++);\n        const count = pNode.children.length;\n        const modeLabel = pNode.mode === 'parallel' ? 'parallel' : 'sequential';\n        const label = escapeLabel(\n          truncateDisplayText(\n            `${pNode.callee} #lpar;${count} effects, ${modeLabel}#rpar;`,\n            DEFAULT_LABEL_MAX,\n          ),\n        );\n        lines.push(`  ${pId}[${label}]`);\n        styleLines.push(`  style ${pId} fill:#E3F2FD`);\n\n        // Fork to children\n        const joinId = nodeId('PJ', globalIdx++);\n        for (let i = 0; i < pNode.children.length; i++) {\n          const child = pNode.children[i];\n          if (!child) continue;\n          const cId = nodeId('PC', globalIdx++);\n          const cLabel = escapeLabel(\n            pNode.branchLabels?.[i] ?? childLabel(child, i),\n          );\n          const branchLabel = pNode.branchLabels?.[i];\n          const edgeLabel = branchLabel\n            ? escapeLabel(branchLabel)\n            : undefined;\n          lines.push(`  ${cId}[${cLabel}]`);\n          if (edgeLabel) {\n            lines.push(`  ${pId} -->|${edgeLabel}| ${cId}`);\n          } else {\n            lines.push(`  ${pId} --> ${cId}`);\n          }\n          lines.push(`  ${cId} --> ${joinId}`);\n        }\n\n        lines.push(`  ${joinId}([Join])`);\n        styleLines.push(`  style ${joinId} fill:#E3F2FD`);\n        orderedIds.push(pId);\n        orderedIds.push(joinId);\n        break;\n      }\n\n      case 'race': {\n        const rNode = entry.node;\n        const rId = nodeId('R', globalIdx++);\n        lines.push(`  ${rId}{Race}`);\n        styleLines.push(`  style ${rId} fill:#FFF3E0`);\n\n        const winnerId = nodeId('RW', globalIdx++);\n        for (let i = 0; i < rNode.children.length; i++) {\n          const child = rNode.children[i];\n          if (!child) continue;\n          const cId = nodeId('RC', globalIdx++);\n          const cLabel = escapeLabel(\n            rNode.raceLabels?.[i] ?? childLabel(child, i),\n          );\n          lines.push(`  ${cId}[${cLabel}]`);\n          lines.push(`  ${rId} -->|competes| ${cId}`);\n          lines.push(`  ${cId} -.->|winner?| ${winnerId}`);\n        }\n\n        lines.push(`  ${winnerId}([First to complete])`);\n        styleLines.push(`  style ${winnerId} fill:#FFF3E0`);\n        orderedIds.push(rId);\n        orderedIds.push(winnerId);\n        break;\n      }\n\n      case 'fiber': {\n        const fNode = entry.node;\n        const fId = nodeId('F', globalIdx++);\n        const op = fNode.operation;\n\n        if (op === 'fork' || op === 'forkScoped' || op === 'forkDaemon' || op === 'forkAll' || op === 'forkIn' || op === 'forkWithErrorHandler') {\n          const sourceLabel = fNode.fiberSource?.displayName ?? fNode.fiberSource?.name ?? 'effect';\n          const label = escapeLabel(`${op}#lpar;${sourceLabel}#rpar;`);\n          lines.push(`  ${fId}[${label}]`);\n\n          if (op === 'forkScoped') {\n            styleLines.push(`  style ${fId} fill:#C8E6C9`);\n          } else if (op === 'forkDaemon') {\n            styleLines.push(`  style ${fId} fill:#FFE0B2`);\n          } else {\n            styleLines.push(`  style ${fId} fill:#FFF9C4`);\n          }\n        } else if (op === 'join' || op === 'await') {\n          const label = escapeLabel(op);\n          lines.push(`  ${fId}[${label}]`);\n          styleLines.push(`  style ${fId} fill:#BBDEFB`);\n        } else {\n          const label = escapeLabel(`Fiber.${op}`);\n          lines.push(`  ${fId}[${label}]`);\n          styleLines.push(`  style ${fId} fill:#BBDEFB`);\n        }\n\n        orderedIds.push(fId);\n        break;\n      }\n\n      case 'primitive': {\n        const cpNode = entry.node;\n        const cpId = nodeId('CP', globalIdx++);\n        const primName = capitalize(cpNode.primitive);\n        const label = escapeLabel(`${primName}.${cpNode.operation}`);\n        // Hexagon shape: {{...}}\n        lines.push(`  ${cpId}{{${label}}}`);\n        styleLines.push(`  style ${cpId} fill:#F3E5F5`);\n        orderedIds.push(cpId);\n        break;\n      }\n    }\n  }\n\n  // Connect nodes in execution order\n  for (let i = 0; i < orderedIds.length - 1; i++) {\n    const from = orderedIds[i];\n    const to = orderedIds[i + 1];\n    if (!from || !to) continue;\n    lines.push(`  ${from} --> ${to}`);\n  }\n\n  return [...lines, ...styleLines].join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { DEFAULT_LABEL_MAX, truncateDisplayText } from '../analysis-utils';\n\ninterface TimelineStep {\n  readonly kind: 'service-call' | 'effect-constructor' | 'retry' | 'timeout' | 'parallel';\n  readonly node: StaticFlowNode;\n}\n\n/** Collect steps in execution order from an IR tree. */\nfunction collectSteps(nodes: readonly StaticFlowNode[]): readonly TimelineStep[] {\n  const steps: TimelineStep[] = [];\n\n  const visit = (node: StaticFlowNode): void => {\n    if (node.type === 'parallel') {\n      steps.push({ kind: 'parallel', node });\n      return;\n    }\n\n    if (node.type === 'retry') {\n      steps.push({ kind: 'retry', node });\n      // Also visit the source effect inside the retry\n      visit(node.source);\n      return;\n    }\n\n    if (node.type === 'timeout') {\n      steps.push({ kind: 'timeout', node });\n      visit(node.source);\n      return;\n    }\n\n    if (node.type === 'effect') {\n      const callee = node.callee;\n      // Skip noise: Effect.fn definitions, anonymous constructors, Schema/Data\n      if (callee === 'Effect.fn' || callee.startsWith('Effect.fn(')) return;\n      if (callee.startsWith('Schema.') || callee.startsWith('Data.')) return;\n      const displayName = node.displayName ?? '';\n      const hasExplicitName = displayName && displayName !== callee && displayName !== node.type;\n      if (!hasExplicitName && (callee.startsWith('Effect.') || callee === 'Effect')) return;\n\n      if (node.serviceCall) {\n        steps.push({ kind: 'service-call', node });\n      } else {\n        steps.push({ kind: 'effect-constructor', node });\n      }\n      return;\n    }\n\n    // For structural nodes (generator, pipe, error-handler, etc.), recurse into children\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    for (const child of children) {\n      visit(child);\n    }\n  };\n\n  for (const node of nodes) {\n    visit(node);\n  }\n\n  return steps;\n}\n\n/** Collect all unique service types from steps. */\nfunction collectParticipants(steps: readonly TimelineStep[]): readonly string[] {\n  const seen = new Set<string>();\n  const participants: string[] = [];\n\n  const visitStep = (step: TimelineStep): void => {\n    if (step.kind === 'service-call' && step.node.type === 'effect' && step.node.serviceCall) {\n      const svc = step.node.serviceCall.serviceType;\n      if (!seen.has(svc)) {\n        seen.add(svc);\n        participants.push(svc);\n      }\n    } else if (step.kind === 'parallel') {\n      // Look into parallel children for service calls\n      const children = Option.getOrElse(getStaticChildren(step.node), () => []);\n      for (const child of children) {\n        if (child.type === 'effect' && child.serviceCall) {\n          const svc = child.serviceCall.serviceType;\n          if (!seen.has(svc)) {\n            seen.add(svc);\n            participants.push(svc);\n          }\n        }\n      }\n    }\n  };\n\n  for (const step of steps) {\n    visitStep(step);\n  }\n\n  return participants;\n}\n\n/** Render a parallel node as par/and/end block. */\nfunction renderParallelBlock(node: StaticFlowNode, lines: string[], indent: string): void {\n  const children = Option.getOrElse(getStaticChildren(node), () => []);\n  if (children.length === 0) return;\n\n  lines.push(`${indent}par Parallel`);\n  for (let i = 0; i < children.length; i++) {\n    if (i > 0) {\n      lines.push(`${indent}and`);\n    }\n    const child = children[i];\n    if (!child) continue;\n    if (child.type === 'effect' && child.serviceCall) {\n      lines.push(`${indent}  Program->>${child.serviceCall.serviceType}: ${child.serviceCall.methodName}()`);\n      lines.push(`${indent}  ${child.serviceCall.serviceType}-->>Program: result`);\n    } else if (child.type === 'effect') {\n      lines.push(\n        `${indent}  Note over Program: ${truncateDisplayText(child.callee, DEFAULT_LABEL_MAX)}`,\n      );\n    } else {\n      const rawLabel =\n        child.displayName ?? child.name ?? (typeof child.type === 'string' ? child.type : 'node');\n      const label = truncateDisplayText(rawLabel, DEFAULT_LABEL_MAX);\n      lines.push(`${indent}  Note over Program: ${label}`);\n    }\n  }\n  lines.push(`${indent}end`);\n}\n\n/**\n * Render a Mermaid sequence diagram from an Effect IR showing\n * execution order with service calls and timing info.\n */\nexport function renderTimelineMermaid(ir: StaticEffectIR): string {\n  const steps = collectSteps(ir.root.children);\n\n  if (steps.length === 0) {\n    return 'sequenceDiagram\\n  participant Program\\n  Note over Program: Empty program';\n  }\n\n  const participants = collectParticipants(steps);\n  const lines: string[] = ['sequenceDiagram'];\n  lines.push('  participant Program');\n  for (const p of participants) {\n    lines.push(`  participant ${p}`);\n  }\n\n  for (const step of steps) {\n    switch (step.kind) {\n      case 'service-call': {\n        const node = step.node;\n        if (node.type === 'effect' && node.serviceCall) {\n          const svc = node.serviceCall.serviceType;\n          const method = node.serviceCall.methodName;\n          lines.push(`  Program->>${svc}: ${method}()`);\n          lines.push(`  ${svc}-->>Program: result`);\n        }\n        break;\n      }\n      case 'effect-constructor': {\n        const node = step.node;\n        if (node.type === 'effect') {\n          lines.push(\n            `  Note over Program: ${truncateDisplayText(node.callee, DEFAULT_LABEL_MAX)}`,\n          );\n        }\n        break;\n      }\n      case 'retry': {\n        const node = step.node;\n        if (node.type === 'retry') {\n          const info = node.scheduleInfo;\n          if (info) {\n            const retries = info.maxRetries !== undefined ? `${info.maxRetries}x` : 'unlimited';\n            lines.push(\n              `  Note over Program: ${truncateDisplayText(`retry (${retries}, ${info.baseStrategy})`, DEFAULT_LABEL_MAX)}`,\n            );\n          } else if (node.schedule) {\n            lines.push(\n              `  Note over Program: ${truncateDisplayText(`retry (${node.schedule})`, DEFAULT_LABEL_MAX)}`,\n            );\n          } else {\n            lines.push(`  Note over Program: retry`);\n          }\n        }\n        break;\n      }\n      case 'timeout': {\n        const node = step.node;\n        if (node.type === 'timeout') {\n          const dur = node.duration ?? 'unknown';\n          lines.push(`  Note over Program: timeout(${dur})`);\n        }\n        break;\n      }\n      case 'parallel': {\n        renderParallelBlock(step.node, lines, '  ');\n        break;\n      }\n    }\n  }\n\n  return lines.join('\\n');\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","import type { StaticEffectIR } from '../types';\nimport { buildLayerDependencyGraph } from '../layer-graph';\n\ninterface LayersOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n/** Sanitize an ID for use as a Mermaid node identifier. */\nfunction sanitizeId(id: string): string {\n  return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n/**\n * Render a layered architecture Mermaid flowchart from an Effect IR.\n *\n * Shows which layers provide which services and their dependencies.\n * - Layer nodes are rectangles with name and lifecycle info.\n * - Service nodes are hexagons.\n * - Provides edges are solid green arrows.\n * - Requires edges are dashed blue arrows.\n * - Merge edges are gray arrows.\n */\nexport function renderLayersMermaid(\n  ir: StaticEffectIR,\n  options: LayersOptions = {},\n): string {\n  const direction = options.direction ?? 'TB';\n  const graph = buildLayerDependencyGraph(ir);\n\n  if (graph.layers.length === 0) {\n    return `flowchart ${direction}\\n  NoLayers((No layers))`;\n  }\n\n  const lines: string[] = [`flowchart ${direction}`];\n\n  // Collect all unique services\n  const allServices = new Set<string>();\n  for (const layer of graph.layers) {\n    for (const svc of layer.provides) allServices.add(svc);\n    for (const req of layer.requires) allServices.add(req);\n  }\n\n  // Track merged layers for styling\n  const mergedLayerIds = new Set<string>();\n\n  // Layer nodes: rectangles with label\n  for (const layer of graph.layers) {\n    const label = layer.name ?? layer.id;\n    const lifecycle = layer.lifecycle !== 'default' ? ` (${layer.lifecycle})` : '';\n    const nodeId = sanitizeId(layer.id);\n    lines.push(`  ${nodeId}[\"${label}${lifecycle}\"]`);\n    if (layer.isMerged) mergedLayerIds.add(nodeId);\n  }\n\n  // Service nodes: hexagons\n  for (const svc of allServices) {\n    lines.push(`  ${sanitizeId(svc)}{{\"${svc}\"}}`);\n  }\n\n  // Edges\n  for (const edge of graph.edges) {\n    const from = sanitizeId(edge.from);\n    const to = sanitizeId(edge.to);\n    if (edge.kind === 'provides') {\n      lines.push(`  ${from} -->|provides| ${to}`);\n    } else if (edge.kind === 'requires') {\n      lines.push(`  ${from} -.->|requires| ${to}`);\n    } else {\n      lines.push(`  ${from} -->|merge| ${to}`);\n    }\n  }\n\n  // Styling\n  lines.push('');\n  lines.push('  classDef layerStyle fill:#E8EAF6,stroke:#3F51B5');\n  lines.push('  classDef serviceStyle fill:#E3F2FD,stroke:#1E88E5');\n  lines.push('  classDef mergedStyle fill:#F3E5F5,stroke:#8E24AA');\n\n  // Apply layer styles\n  for (const layer of graph.layers) {\n    const nodeId = sanitizeId(layer.id);\n    if (mergedLayerIds.has(nodeId)) {\n      lines.push(`  class ${nodeId} mergedStyle`);\n    } else {\n      lines.push(`  class ${nodeId} layerStyle`);\n    }\n  }\n\n  // Apply service styles\n  for (const svc of allServices) {\n    lines.push(`  class ${sanitizeId(svc)} serviceStyle`);\n  }\n\n  return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode, type StaticRetryNode, type StaticTimeoutNode } from '../types';\nimport { escapeMermaidLabel as escapeLabel } from '../analysis-utils';\n\ninterface RetryOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\ninterface ResilienceNode {\n  readonly node: StaticFlowNode;\n  readonly index: number;\n}\n\n/** Recursively collect retry and timeout nodes from the IR. */\nfunction collectResilienceNodes(\n  nodes: readonly StaticFlowNode[],\n  result: ResilienceNode[],\n): void {\n  for (const node of nodes) {\n    if (node.type === 'retry' || node.type === 'timeout') {\n      result.push({ node, index: result.length });\n    }\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) collectResilienceNodes(children, result);\n  }\n}\n\n/** Build a retry strategy label from scheduleInfo. */\nfunction buildRetryLabel(node: StaticFlowNode): string {\n  if (node.type !== 'retry') return '';\n  const info = (node).scheduleInfo;\n  if (!info) return 'retry';\n\n  const parts: string[] = [info.baseStrategy];\n  if (info.maxRetries !== undefined && info.maxRetries !== 'unlimited') {\n    parts.push(`${info.maxRetries}x`);\n  }\n  if (info.initialDelay) {\n    parts.push(info.initialDelay);\n  }\n  if (info.maxDelay) {\n    parts.push(`max ${info.maxDelay}`);\n  }\n  if (info.jittered) {\n    parts.push('+jitter');\n  }\n  return parts.join(' ');\n}\n\n/** Compute display name for the operation being retried/timed-out. */\nfunction operationLabel(node: StaticFlowNode): string {\n  const source = (node as StaticRetryNode | StaticTimeoutNode).source as\n    | StaticFlowNode\n    | undefined;\n  if (source === undefined) return 'Operation';\n  if (source.displayName) return source.displayName;\n  if (source.name) return source.name;\n  return 'Operation';\n}\n\n/**\n * Render a Mermaid flowchart showing retry and timeout resilience patterns.\n */\nexport function renderRetryMermaid(\n  ir: StaticEffectIR,\n  options: RetryOptions = {},\n): string {\n  const direction = options.direction ?? 'LR';\n  const collected: ResilienceNode[] = [];\n  collectResilienceNodes(ir.root.children, collected);\n\n  if (collected.length === 0) {\n    return `flowchart ${direction}\\n  NoRetry((No retry/timeout patterns))`;\n  }\n\n  const lines: string[] = [`flowchart ${direction}`];\n\n  for (const { node, index } of collected) {\n    const prefix = `N${index}`;\n    const opLabel = escapeLabel(operationLabel(node));\n\n    if (node.type === 'retry') {\n      const retryNode = node;\n      const retryLabel = escapeLabel(buildRetryLabel(node));\n\n      lines.push(`  ${prefix}_Op[${opLabel}] -->|fail| ${prefix}_R{Retry}`);\n      lines.push(`  ${prefix}_R -->|\"${retryLabel}\"| ${prefix}_Op`);\n\n      if (retryNode.hasFallback) {\n        lines.push(`  ${prefix}_R -->|exhausted| ${prefix}_F[Fallback]`);\n      } else {\n        lines.push(`  ${prefix}_R -->|exhausted| ${prefix}_Fail((Failure))`);\n      }\n\n      // Styles\n      lines.push(`  style ${prefix}_R fill:#9b59b6,stroke:#8e44ad,color:#fff`);\n      if (retryNode.hasFallback) {\n        lines.push(`  style ${prefix}_F fill:#2ecc71,stroke:#27ae60,color:#fff`);\n      } else {\n        lines.push(`  style ${prefix}_Fail fill:#e74c3c,stroke:#c0392b,color:#fff`);\n      }\n    } else if (node.type === 'timeout') {\n      const timeoutNode = node;\n      const duration = timeoutNode.duration ?? '?';\n      const timeoutLabel = escapeLabel(`timeout: ${duration}ms`);\n\n      lines.push(`  ${prefix}_Op[${opLabel}] -->|within| ${prefix}_T[${timeoutLabel}]`);\n\n      if (timeoutNode.hasFallback) {\n        lines.push(`  ${prefix}_T -->|exceeded| ${prefix}_F[Fallback]`);\n      } else {\n        lines.push(`  ${prefix}_T -->|exceeded| ${prefix}_Fail((Timeout))`);\n      }\n\n      // Styles\n      lines.push(`  style ${prefix}_T fill:#e67e22,stroke:#d35400,color:#fff`);\n      if (timeoutNode.hasFallback) {\n        lines.push(`  style ${prefix}_F fill:#2ecc71,stroke:#27ae60,color:#fff`);\n      } else {\n        lines.push(`  style ${prefix}_Fail fill:#e74c3c,stroke:#c0392b,color:#fff`);\n      }\n    }\n  }\n\n  return lines.join('\\n');\n}\n","import type { StaticEffectIR } from '../types';\n\ninterface TestabilityOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n/**\n * Render a testability-focused Mermaid flowchart from an Effect IR.\n *\n * Shows what needs mocking for testing: required services, isolation boundaries,\n * and mock complexity (easy leaf services vs hard infrastructure/layer services).\n */\nexport function renderTestabilityMermaid(\n  ir: StaticEffectIR,\n  options: TestabilityOptions = {},\n): string {\n  const direction = options.direction ?? 'LR';\n  const services = ir.root.requiredServices ?? [];\n  const deps = ir.root.dependencies;\n\n  if (services.length === 0) {\n    return `flowchart ${direction}\\n  NoMocks((No services to mock - pure computation))`;\n  }\n\n  // Build a set of layer dependency names for classification\n  const layerNames = new Set(deps.filter(d => d.isLayer).map(d => d.name));\n\n  const lines: string[] = [`flowchart ${direction}`];\n  const easyIds: string[] = [];\n  const hardIds: string[] = [];\n\n  for (let i = 0; i < services.length; i++) {\n    const sid = `S${i}`;\n    const service = services[i];\n    if (!service) continue;\n    lines.push(`  Prog[${ir.root.programName}] -->|needs mock| ${sid}{{\"${service.serviceId}\"}}`);\n\n    if (layerNames.has(service.serviceId)) {\n      hardIds.push(sid);\n    } else {\n      easyIds.push(sid);\n    }\n  }\n\n  // Add class definitions\n  lines.push('');\n  lines.push('  classDef easy fill:#C8E6C9');\n  lines.push('  classDef hard fill:#FFE0B2');\n\n  if (easyIds.length > 0) {\n    lines.push(`  class ${easyIds.join(',')} easy`);\n  }\n  if (hardIds.length > 0) {\n    lines.push(`  class ${hardIds.join(',')} hard`);\n  }\n\n  // Summary note\n  const mockWord = services.length === 1 ? 'mock' : 'mocks';\n  lines.push('');\n  lines.push(`  Note[Requires ${services.length} service ${mockWord}]`);\n\n  return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { escapeMermaidLabel as escapeLabel } from '../analysis-utils';\n\ninterface DataflowOptions {\n  readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\ninterface DataflowStep {\n  readonly successType: string;\n  readonly errorType: string;\n  readonly transformLabel?: string | undefined;\n  readonly isEffectful: boolean;\n}\n\n/** Generate a short node ID: S0, S1, S2, ... */\nfunction stepId(index: number): string {\n  return `S${index}`;\n}\n\n/**\n * Extract pipe chains from IR, collecting transformation steps with type info.\n */\nfunction collectPipeSteps(node: StaticFlowNode): DataflowStep[][] {\n  const chains: DataflowStep[][] = [];\n\n  if (node.type === 'pipe') {\n    const pipeNode = node as {\n      initial: StaticFlowNode;\n      transformations: readonly StaticFlowNode[];\n      typeFlow?: readonly { successType: string; errorType: string }[];\n    };\n\n    const steps: DataflowStep[] = [];\n\n    // Initial step type from initial node's typeSignature or typeFlow[0]\n    const initialSig =\n      pipeNode.typeFlow?.[0] ??\n      ('typeSignature' in pipeNode.initial\n        ? (pipeNode.initial as { typeSignature?: { successType: string; errorType: string } }).typeSignature\n        : undefined);\n\n    if (initialSig) {\n      steps.push({\n        successType: initialSig.successType,\n        errorType: initialSig.errorType,\n        isEffectful: false,\n      });\n    }\n\n    for (let i = 0; i < pipeNode.transformations.length; i++) {\n      const t = pipeNode.transformations[i];\n      if (!t) continue;\n      const transformType =\n        t.type === 'transform'\n          ? (t as { transformType: string }).transformType\n          : t.name ?? t.type;\n      const isEffectful =\n        t.type === 'transform'\n          ? (t as { isEffectful: boolean }).isEffectful\n          : false;\n\n      // Type from typeFlow (index i+1) or from outputType on the transform\n      const sig =\n        pipeNode.typeFlow?.[i + 1] ??\n        (t.type === 'transform'\n          ? (t as { outputType?: { successType: string; errorType: string } }).outputType\n          : undefined);\n\n      if (sig) {\n        steps.push({\n          successType: sig.successType,\n          errorType: sig.errorType,\n          transformLabel: transformType,\n          isEffectful,\n        });\n      } else {\n        steps.push({\n          successType: 'unknown',\n          errorType: 'unknown',\n          transformLabel: transformType,\n          isEffectful,\n        });\n      }\n    }\n\n    if (steps.length > 0) {\n      chains.push(steps);\n    }\n  }\n\n  // Recurse into children\n  const children = Option.getOrElse(getStaticChildren(node), () => []);\n  for (const child of children) {\n    chains.push(...collectPipeSteps(child));\n  }\n\n  return chains;\n}\n\n/**\n * Extract generator yield steps as a dataflow chain.\n */\nfunction collectGeneratorSteps(node: StaticFlowNode): DataflowStep[][] {\n  const chains: DataflowStep[][] = [];\n\n  if (node.type === 'generator') {\n    const genNode = node as {\n      yields: readonly { variableName?: string; effect: StaticFlowNode }[];\n    };\n\n    const steps: DataflowStep[] = [];\n    for (const y of genNode.yields) {\n      const sig =\n        'typeSignature' in y.effect\n          ? (y.effect as { typeSignature?: { successType: string; errorType: string } }).typeSignature\n          : undefined;\n\n      if (sig) {\n        steps.push({\n          successType: sig.successType,\n          errorType: sig.errorType,\n          transformLabel: y.variableName ?? y.effect.name,\n          isEffectful: true,\n        });\n      } else {\n        steps.push({\n          successType: 'unknown',\n          errorType: 'unknown',\n          transformLabel: y.variableName ?? y.effect.name,\n          isEffectful: true,\n        });\n      }\n    }\n\n    if (steps.length > 0) {\n      chains.push(steps);\n    }\n  }\n\n  // Recurse into children\n  const children = Option.getOrElse(getStaticChildren(node), () => []);\n  for (const child of children) {\n    chains.push(...collectGeneratorSteps(child));\n  }\n\n  return chains;\n}\n\n/**\n * Render a dataflow Mermaid flowchart from an Effect IR.\n *\n * Shows data transformation pipelines: how types evolve through pipe chains\n * and generator yield sequences.\n */\nexport function renderDataflowMermaid(\n  ir: StaticEffectIR,\n  options: DataflowOptions = {},\n): string {\n  const direction = options.direction ?? 'LR';\n\n  // Collect all chains from IR\n  const allChains: DataflowStep[][] = [];\n  for (const child of ir.root.children) {\n    allChains.push(...collectPipeSteps(child));\n    allChains.push(...collectGeneratorSteps(child));\n  }\n\n  if (allChains.length === 0) {\n    return `flowchart ${direction}\\n  NoData((No data transformations))`;\n  }\n\n  const lines: string[] = [`flowchart ${direction}`];\n  const styleLines: string[] = [];\n  let globalIdx = 0;\n\n  for (const steps of allChains) {\n    const baseIdx = globalIdx;\n\n    for (let i = 0; i < steps.length; i++) {\n      const step = steps[i];\n      if (!step) continue;\n      const id = stepId(baseIdx + i);\n      const label = escapeLabel(step.successType);\n\n      // Track node for styling\n      if (step.successType === 'unknown') {\n        styleLines.push(`  style ${id} fill:#EEEEEE`);\n      } else {\n        styleLines.push(`  style ${id} fill:#E8F5E9`);\n      }\n\n      if (i < steps.length - 1) {\n        const nextStep = steps[i + 1];\n        if (!nextStep) continue;\n        const nextId = stepId(baseIdx + i + 1);\n        const nextLabel = escapeLabel(nextStep.successType);\n\n        // Build edge label\n        let edgeLabel = nextStep.transformLabel ?? '';\n\n        // Annotate error type changes\n        const prevError = step.errorType;\n        const nextError = nextStep.errorType;\n        if (nextError !== prevError && nextError !== 'never' && nextError !== 'unknown') {\n          edgeLabel = edgeLabel ? `${edgeLabel}<br/>E: ${escapeLabel(nextError)}` : `E: ${escapeLabel(nextError)}`;\n        }\n\n        // Effectful transforms get bold edges (==>)\n        const arrow = nextStep.isEffectful ? '==>' : '-->';\n\n        if (i === 0) {\n          lines.push(`  ${id}[\"${label}\"] ${arrow}|${edgeLabel}| ${nextId}[\"${nextLabel}\"]`);\n        } else {\n          lines.push(`  ${id} ${arrow}|${edgeLabel}| ${nextId}[\"${nextLabel}\"]`);\n        }\n      } else if (i === 0) {\n        // Single-step chain: just render the node\n        lines.push(`  ${id}[\"${label}\"]`);\n      }\n    }\n\n    globalIdx += steps.length;\n  }\n\n  return [...lines, ...styleLines].join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { calculateComplexity } from '../complexity';\n\nexport type DiagramType = 'mermaid' | 'railway';\n\n/**\n * Infer the best diagram type for an Effect program.\n *\n * Decision order:\n * 1. Hard rules: parallel/race/switch/loop/conditional/decision → mermaid\n * 2. Soft heuristics: low complexity → railway, otherwise mermaid\n */\nexport function inferBestDiagramType(ir: StaticEffectIR): DiagramType {\n  const nodes = ir.root.children;\n\n  // Hard rules: structural nodes that railway cannot represent\n  if (hasNodeType(nodes, 'parallel')) return 'mermaid';\n  if (hasNodeType(nodes, 'race')) return 'mermaid';\n  if (hasNodeType(nodes, 'switch')) return 'mermaid';\n  if (hasNodeType(nodes, 'loop')) return 'mermaid';\n  if (hasNodeType(nodes, 'conditional')) return 'mermaid';\n  if (hasNodeType(nodes, 'decision')) return 'mermaid';\n\n  // Check stats for structural indicators that may not appear as IR nodes\n  // (e.g., when the analyzer records counts but the IR is simplified)\n  const stats = ir.metadata.stats;\n  if (\n    stats.decisionCount > 2 ||\n    stats.switchCount > 0 ||\n    stats.conditionalCount > 2\n  ) {\n    return 'mermaid';\n  }\n\n  // Soft heuristics based on complexity metrics\n  const metrics = calculateComplexity(ir);\n\n  if (\n    metrics.cyclomaticComplexity <= 3 &&\n    metrics.decisionPoints <= 1 &&\n    metrics.maxDepth <= 2\n  ) {\n    return 'railway';\n  }\n\n  return 'mermaid';\n}\n\nfunction hasNodeType(\n  nodes: readonly StaticFlowNode[],\n  type: StaticFlowNode['type'],\n): boolean {\n  for (const node of nodes) {\n    if (node.type === type) return true;\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0 && hasNodeType(children, type)) return true;\n  }\n  return false;\n}\n","/**\n * JSON output generation for Effect IR\n */\n\nimport { Effect } from 'effect';\nimport type { StaticEffectIR, JSONRenderOptions } from '../types';\n\n/**\n * Version of the emitted IR document.\n *\n * Stamped on every JSON document so a consumer can validate what it received\n * and migrate across analyzer releases instead of guessing from the shape.\n * Bump it whenever the emitted structure changes incompatibly.\n */\nexport const IR_SCHEMA_VERSION = 1 as const;\n\nconst DEFAULT_OPTIONS: JSONRenderOptions = {\n  pretty: true,\n  includeMetadata: true,\n  compact: false,\n};\n\n/**\n * Render Effect IR as JSON string\n */\nexport const renderJSON = (\n  ir: StaticEffectIR,\n  options?: Partial<JSONRenderOptions>,\n): Effect.Effect<string> =>\n  Effect.gen(function* () {\n    const opts = { ...DEFAULT_OPTIONS, ...options };\n    const space = opts.pretty ? 2 : undefined;\n\n    const data = opts.includeMetadata\n      ? {\n          schemaVersion: IR_SCHEMA_VERSION,\n          root: ir.root,\n          metadata: ir.metadata,\n          references:\n            ir.references instanceof Map\n              ? Object.fromEntries(ir.references)\n              : ir.references,\n        }\n      : { root: ir.root };\n\n    return JSON.stringify(data, replacer, space);\n  });\n\n/**\n * Render multiple Effect IRs as JSON array\n */\nexport const renderMultipleJSON = (\n  irs: readonly StaticEffectIR[],\n  options?: Partial<JSONRenderOptions>,\n): Effect.Effect<string> =>\n  Effect.gen(function* () {\n    const opts = { ...DEFAULT_OPTIONS, ...options };\n    const space = opts.pretty ? 2 : undefined;\n\n    const data = irs.map((ir) =>\n      opts.includeMetadata\n        ? {\n            schemaVersion: IR_SCHEMA_VERSION,\n            root: ir.root,\n            metadata: ir.metadata,\n            references:\n              ir.references instanceof Map\n                ? Object.fromEntries(ir.references)\n                : ir.references,\n          }\n        : { root: ir.root },\n    );\n\n    return JSON.stringify(data, replacer, space);\n  });\n\n/**\n * JSON replacer to handle circular references and special types\n */\nconst replacer = (_key: string, value: unknown): unknown => {\n  // Handle Map\n  if (value instanceof Map) {\n    return Object.fromEntries(value);\n  }\n\n  // Handle Set\n  if (value instanceof Set) {\n    return Array.from(value);\n  }\n\n  // Handle BigInt\n  if (typeof value === 'bigint') {\n    return value.toString();\n  }\n\n  return value;\n};\n","/**\n * Interactive HTML Output (GAP 22 v2)\n *\n * Generates a self-contained HTML file with:\n * - Embedded IR and Mermaid diagram\n * - Search/filter nodes by type, name, complexity\n * - Click-to-navigate: click node to see source location, IR details\n * - Path explorer: select a path and highlight it\n * - Complexity heatmap: color nodes by complexity contribution\n * - Error/data flow toggles\n * - 6-theme system with system preference detection and localStorage persistence\n */\n\nimport type { StaticEffectIR } from '../types';\nimport { renderStaticMermaid } from './mermaid';\nimport { generatePaths } from '../path-generator';\nimport { calculateComplexity } from '../complexity';\n\nexport type HtmlTheme = 'midnight' | 'ocean' | 'ember' | 'forest' | 'daylight' | 'paper';\n\nexport interface HtmlOutputOptions {\n  readonly title?: string | undefined;\n  /** Named theme, or legacy 'light'/'dark' aliases (mapped to daylight/midnight). */\n  readonly theme?: HtmlTheme | 'light' | 'dark' | undefined;\n}\n\n/**\n * Maps legacy theme aliases to their named equivalents.\n * Returns the theme name unchanged if it's already a named theme.\n */\nexport function resolveThemeName(\n  theme: HtmlTheme | 'light' | 'dark' | undefined,\n): HtmlTheme | undefined {\n  if (theme === 'light') return 'daylight';\n  if (theme === 'dark') return 'midnight';\n  return theme;\n}\n\n\n/**\n * Render IR as a self-contained HTML page with interactive features.\n */\nexport function renderInteractiveHTML(\n  ir: StaticEffectIR,\n  options: HtmlOutputOptions = {},\n): string {\n  const title = options.title ?? `${ir.root.programName} - Effect Analysis`;\n  const resolvedTheme = resolveThemeName(options.theme);\n  const mermaidCode = renderStaticMermaid(ir).replace(/<\\/script>/gi, '<\\\\/script>');\n\n  // Generate paths and complexity for embedding\n  const paths = generatePaths(ir);\n  const complexity = calculateComplexity(ir);\n\n  // Also generate the data-flow and error-flow overlay versions\n  const mermaidWithDataFlow = renderStaticMermaid(ir, { dataFlowOverlay: true }).replace(/<\\/script>/gi, '<\\\\/script>');\n  const mermaidWithErrorFlow = renderStaticMermaid(ir, { errorFlowOverlay: true }).replace(/<\\/script>/gi, '<\\\\/script>');\n\n  const irJson = JSON.stringify(ir, null, 2)\n    .replace(/</g, '\\\\u003c')\n    .replace(/>/g, '\\\\u003e');\n\n  const pathsJson = JSON.stringify(paths, null, 2)\n    .replace(/</g, '\\\\u003c')\n    .replace(/>/g, '\\\\u003e');\n\n  const complexityJson = JSON.stringify(complexity, null, 2)\n    .replace(/</g, '\\\\u003c')\n    .replace(/>/g, '\\\\u003e');\n\n  const initialThemeJs = resolvedTheme ? `\"${resolvedTheme}\"` : 'null';\n\n  return `<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"midnight\">\n<head>\n  <meta charset=\"UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n  <title>${escapeHtml(title)}</title>\n  <script src=\"https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js\"></scr` + `ipt>\n  <style>\n    /* Shared font stacks — system-first so the artifact works offline / from file:// */\n    :root {\n      --ui-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;\n      --ui-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, 'Cascadia Code', 'JetBrains Mono', monospace;\n    }\n\n    /* Theme definitions\n       Each theme defines: bg, fg, muted, panel-bg, header-bg, border,\n       accent, accent-dim, selected-bg, signal, scheme. */\n    [data-theme=\"midnight\"] {\n      --bg: #0a0b0f; --fg: #e6e8ed; --muted: #8b919c;\n      --panel-bg: #15171c; --header-bg: #0a0b0f;\n      --border: rgba(255,255,255,0.08); --accent: #a78bfa; --accent-dim: rgba(124,111,240,0.14);\n      --selected-bg: rgba(124,111,240,0.18); --signal: #c8ff3a;\n      --scheme: dark;\n    }\n    [data-theme=\"ocean\"] {\n      --bg: #0a1628; --fg: #c8d8ee; --muted: #7a90b0;\n      --panel-bg: #0f1e35; --header-bg: #142742;\n      --border: #1a3452; --accent: #4da6e8; --accent-dim: rgba(77,166,232,0.12);\n      --selected-bg: #0f2847; --signal: #4da6e8;\n      --scheme: dark;\n    }\n    [data-theme=\"ember\"] {\n      --bg: #1a0f0f; --fg: #e0d0c8; --muted: #9b8278;\n      --panel-bg: #221414; --header-bg: #2e1a1a;\n      --border: #3a2222; --accent: #e8845a; --accent-dim: rgba(232,132,90,0.12);\n      --selected-bg: #2e1a1a; --signal: #e8845a;\n      --scheme: dark;\n    }\n    [data-theme=\"forest\"] {\n      --bg: #0c1a0f; --fg: #c8d8c8; --muted: #7a9080;\n      --panel-bg: #111f14; --header-bg: #18281a;\n      --border: #1e3a20; --accent: #5ac87a; --accent-dim: rgba(90,200,122,0.12);\n      --selected-bg: #18281a; --signal: #5ac87a;\n      --scheme: dark;\n    }\n    [data-theme=\"daylight\"] {\n      --bg: #f8f9fb; --fg: #1a2030; --muted: #5a6378;\n      --panel-bg: #ffffff; --header-bg: #ffffff;\n      --border: #dde1ea; --accent: #3a6fd8; --accent-dim: rgba(58,111,216,0.08);\n      --selected-bg: #e3f2fd; --signal: #2e6a0a;\n      --scheme: light;\n    }\n    [data-theme=\"paper\"] {\n      --bg: #faf8f5; --fg: #2a2218; --muted: #6a5a44;\n      --panel-bg: #fffefa; --header-bg: #fffefa;\n      --border: #e0d8cc; --accent: #b07830; --accent-dim: rgba(176,120,48,0.08);\n      --selected-bg: #f4f0e8; --signal: #7a4d10;\n      --scheme: light;\n    }\n\n    html { color-scheme: var(--scheme, dark); }\n\n    * { box-sizing: border-box; margin: 0; padding: 0; }\n    body {\n      font-family: var(--ui-sans);\n      background: var(--bg); color: var(--fg);\n      -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;\n    }\n    ::selection { background: var(--accent); color: var(--bg); }\n\n    :focus-visible {\n      outline: 2px solid var(--accent);\n      outline-offset: 2px;\n      border-radius: 3px;\n    }\n\n    .header {\n      padding: 0.85rem 1.1rem; background: var(--header-bg);\n      border-bottom: 1px solid var(--border);\n      display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;\n    }\n    .header h1 {\n      font-family: var(--ui-mono);\n      font-size: 0.92rem; font-weight: 600; letter-spacing: -0.005em;\n      display: inline-flex; align-items: center; gap: 0.55rem;\n    }\n    .header h1::before {\n      content: ''; width: 0.5rem; height: 0.5rem; border-radius: 50%;\n      background: var(--signal);\n      box-shadow: 0 0 10px var(--signal);\n    }\n    .header .stats {\n      font-family: var(--ui-mono);\n      font-size: 0.7rem; letter-spacing: 0.04em; text-transform: uppercase;\n      color: var(--muted);\n    }\n\n    .theme-picker { position: relative; margin-left: auto; }\n    .theme-picker > button {\n      padding: 5px 10px; border: 1px solid var(--border); border-radius: 4px;\n      background: var(--panel-bg); color: var(--fg); cursor: pointer;\n      font-family: var(--ui-mono); font-size: 0.7rem;\n      letter-spacing: 0.06em; text-transform: uppercase;\n      transition: border-color 150ms ease, color 150ms ease;\n    }\n    .theme-picker > button:hover { border-color: var(--accent); color: var(--accent); }\n    .theme-menu {\n      display: none; position: absolute; right: 0; top: 100%; margin-top: 6px;\n      background: var(--panel-bg); border: 1px solid var(--border); border-radius: 6px;\n      padding: 4px 0; min-width: 160px; z-index: 100;\n      box-shadow: 0 8px 24px rgba(0,0,0,0.35);\n    }\n    .theme-menu.open { display: block; }\n    .theme-menu button {\n      display: block; width: 100%; padding: 7px 12px;\n      border: none; background: transparent; color: var(--fg);\n      text-align: left; cursor: pointer;\n      font-family: var(--ui-mono); font-size: 0.72rem;\n      letter-spacing: 0.04em;\n    }\n    .theme-menu button:hover { background: var(--accent-dim); }\n    .theme-menu button.active { color: var(--accent); font-weight: 600; }\n\n    .toolbar {\n      padding: 0.55rem 1.1rem; background: var(--panel-bg);\n      border-bottom: 1px solid var(--border);\n      display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center;\n    }\n    .toolbar input[type=\"text\"], .toolbar select {\n      padding: 5px 9px; border: 1px solid var(--border); border-radius: 4px;\n      background: var(--bg); color: var(--fg);\n      font-family: var(--ui-mono); font-size: 0.78rem;\n      transition: border-color 150ms ease;\n    }\n    .toolbar input[type=\"text\"] { width: 220px; }\n    .toolbar input[type=\"text\"]:focus, .toolbar select:focus {\n      outline: none; border-color: var(--accent);\n    }\n    .toolbar label {\n      font-family: var(--ui-mono);\n      font-size: 0.72rem; letter-spacing: 0.04em; text-transform: uppercase;\n      color: var(--muted);\n      display: flex; align-items: center; gap: 5px; cursor: pointer;\n    }\n    .toolbar .sep { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }\n\n    .layout { display: grid; grid-template-columns: 1fr minmax(260px, 380px); height: calc(100vh - 90px); }\n    @media (max-width: 900px) { .layout { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; } }\n\n    .diagram-pane { overflow: auto; padding: 1.25rem; border-right: 1px solid var(--border); }\n    .diagram-pane .mermaid { min-height: 200px; }\n    .diagram-pane .mermaid:not(.themed) svg { visibility: hidden; }\n\n    .sidebar { overflow-y: auto; display: flex; flex-direction: column; }\n    .sidebar-tabs { display: flex; border-bottom: 1px solid var(--border); background: var(--header-bg); }\n    .sidebar-tabs button {\n      flex: 1; padding: 10px 8px; border: none; background: transparent;\n      color: var(--muted); cursor: pointer;\n      font-family: var(--ui-mono);\n      font-size: 0.7rem; letter-spacing: 0.08em; text-transform: uppercase;\n      border-bottom: 1px solid transparent;\n      transition: color 150ms ease, border-color 150ms ease;\n    }\n    .sidebar-tabs button.active { border-bottom-color: var(--accent); color: var(--accent); font-weight: 600; }\n    .sidebar-tabs button:hover { color: var(--fg); }\n\n    .tab-content { flex: 1; overflow-y: auto; padding: 1rem; font-size: 0.85rem; }\n    .tab-content[hidden] { display: none; }\n\n    .detail-section { margin-bottom: 1.25rem; }\n    .detail-section h3 {\n      font-family: var(--ui-mono);\n      font-size: 0.7rem; font-weight: 600;\n      letter-spacing: 0.12em; text-transform: uppercase;\n      color: var(--muted); margin-bottom: 0.55rem;\n    }\n    .detail-section h3::before { content: '// '; color: var(--signal); }\n    .detail-section pre {\n      background: var(--bg); border: 1px solid var(--border);\n      padding: 0.6rem 0.75rem; border-radius: 4px; overflow-x: auto;\n      font-family: var(--ui-mono); font-size: 0.75rem;\n      white-space: pre-wrap; word-break: break-word; color: var(--fg);\n    }\n    .detail-section table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }\n    .detail-section td, .detail-section th { padding: 5px 8px; text-align: left; border-bottom: 1px solid var(--border); }\n    .detail-section th {\n      font-family: var(--ui-mono);\n      font-size: 0.68rem; font-weight: 600;\n      letter-spacing: 0.08em; text-transform: uppercase;\n      color: var(--muted);\n    }\n\n    .path-item {\n      padding: 7px 10px; border: 1px solid var(--border); border-radius: 4px;\n      margin-bottom: 5px; cursor: pointer; font-size: 0.8rem;\n      transition: border-color 150ms ease, background 150ms ease;\n    }\n    .path-item:hover { background: var(--panel-bg); border-color: var(--accent-dim); }\n    .path-item.selected { border-color: var(--accent); background: var(--selected-bg); }\n    .path-step {\n      display: inline-block; padding: 2px 7px; margin: 1px;\n      background: var(--panel-bg); border: 1px solid var(--border); border-radius: 3px;\n      font-family: var(--ui-mono); font-size: 0.72rem;\n    }\n\n    .complexity-badge {\n      display: inline-block; padding: 2px 9px; border-radius: 3px;\n      font-family: var(--ui-mono);\n      font-size: 0.7rem; font-weight: 600;\n      letter-spacing: 0.04em; text-transform: uppercase;\n      border: 1px solid;\n    }\n    .complexity-low    { background: rgba(200,255,58,0.10);  color: #b8e632; border-color: rgba(200,255,58,0.30); }\n    .complexity-medium { background: rgba(254,188,46,0.12); color: #f0b337; border-color: rgba(254,188,46,0.32); }\n    .complexity-high   { background: rgba(255,123,123,0.12); color: #ff7b7b; border-color: rgba(255,123,123,0.32); }\n    [data-theme=\"daylight\"] .complexity-low    { background: #e6f6c4; color: #4a6f0a; border-color: #c2dd7d; }\n    [data-theme=\"daylight\"] .complexity-medium { background: #fff3c8; color: #7a5400; border-color: #e6c982; }\n    [data-theme=\"daylight\"] .complexity-high   { background: #ffd9d9; color: #a02828; border-color: #f0a0a0; }\n    [data-theme=\"paper\"] .complexity-low    { background: #e6f6c4; color: #4a6f0a; border-color: #c2dd7d; }\n    [data-theme=\"paper\"] .complexity-medium { background: #fff3c8; color: #7a5400; border-color: #e6c982; }\n    [data-theme=\"paper\"] .complexity-high   { background: #ffd9d9; color: #a02828; border-color: #f0a0a0; }\n  </style>\n</head>\n<body>\n  <div class=\"header\">\n    <h1>${escapeHtml(title)}</h1>\n    <span class=\"stats\" id=\"complexity-stats\"></span>\n    <div class=\"theme-picker\">\n      <button onclick=\"toggleThemeMenu()\" id=\"theme-btn\">Theme</button>\n      <div class=\"theme-menu\" id=\"theme-menu\">\n        <button onclick=\"applyTheme('midnight')\">Console</button>\n        <button onclick=\"applyTheme('ocean')\">Ocean</button>\n        <button onclick=\"applyTheme('ember')\">Ember</button>\n        <button onclick=\"applyTheme('forest')\">Forest</button>\n        <button onclick=\"applyTheme('daylight')\">Daylight</button>\n        <button onclick=\"applyTheme('paper')\">Paper</button>\n      </div>\n    </div>\n  </div>\n  <div class=\"toolbar\">\n    <input type=\"text\" id=\"search\" placeholder=\"Search nodes...\" oninput=\"handleSearch(this.value)\">\n    <select id=\"typeFilter\" onchange=\"handleTypeFilter(this.value)\">\n      <option value=\"\">All types</option>\n    </select>\n    <div class=\"sep\"></div>\n    <label><input type=\"checkbox\" id=\"toggleDataFlow\" onchange=\"toggleOverlay('data')\"> Data Flow</label>\n    <label><input type=\"checkbox\" id=\"toggleErrorFlow\" onchange=\"toggleOverlay('error')\"> Error Flow</label>\n    <div class=\"sep\"></div>\n    <select id=\"pathSelect\" onchange=\"selectPath(this.value)\">\n      <option value=\"\">Select path...</option>\n    </select>\n  </div>\n  <div class=\"layout\">\n    <div class=\"diagram-pane\">\n      <pre class=\"mermaid\" id=\"mermaid-diagram\">${escapeHtml(mermaidCode)}</pre>\n    </div>\n    <div class=\"sidebar\">\n      <div class=\"sidebar-tabs\">\n        <button class=\"active\" onclick=\"showTab('details')\">Details</button>\n        <button onclick=\"showTab('paths')\">Paths</button>\n        <button onclick=\"showTab('ir')\">IR</button>\n      </div>\n      <div class=\"tab-content\" id=\"tab-details\">\n        <div class=\"detail-section\">\n          <h3>Complexity</h3>\n          <table id=\"complexity-table\"></table>\n        </div>\n        <div class=\"detail-section\" id=\"node-details\">\n          <h3>Node Details</h3>\n          <p style=\"opacity:0.6\">Click a node in the diagram to see details.</p>\n        </div>\n      </div>\n      <div class=\"tab-content\" id=\"tab-paths\" hidden>\n        <div id=\"paths-list\"></div>\n      </div>\n      <div class=\"tab-content\" id=\"tab-ir\" hidden>\n        <pre id=\"ir-json\" style=\"font-size:0.7rem\">${irJson}</pre>\n      </div>\n    </div>\n  </div>\n  <script>\n    var INITIAL_THEME = ${initialThemeJs};\n    var STORAGE_KEY = 'effect-viz-theme';\n    var DARK_THEMES = ['midnight', 'ocean', 'ember', 'forest'];\n\n    var MERMAID_THEME_VARS = {\n      midnight: { primaryColor: '#1c1e24', primaryTextColor: '#e6e8ed', primaryBorderColor: '#7c6ff0', lineColor: '#555a64', secondaryColor: '#15171c', tertiaryColor: '#0a0b0f', background: '#0a0b0f', mainBkg: '#1c1e24', nodeBorder: '#7c6ff0', clusterBkg: '#15171c', clusterBorder: 'rgba(124,111,240,0.5)', titleColor: '#e6e8ed', edgeLabelBackground: '#15171c', nodeTextColor: '#e6e8ed' },\n      ocean: { primaryColor: '#132d4a', primaryTextColor: '#c8d8ee', primaryBorderColor: '#1f4a70', lineColor: '#1f4a70', secondaryColor: '#0f1e35', tertiaryColor: '#142742', background: '#0a1628', mainBkg: '#132d4a', nodeBorder: '#1f4a70', clusterBkg: '#0f1e35', clusterBorder: '#1f4a70', titleColor: '#c8d8ee', edgeLabelBackground: '#0f1e35', nodeTextColor: '#c8d8ee' },\n      ember: { primaryColor: '#2e1c18', primaryTextColor: '#e0d0c8', primaryBorderColor: '#5a3328', lineColor: '#5a3328', secondaryColor: '#221414', tertiaryColor: '#2e1a1a', background: '#1a0f0f', mainBkg: '#2e1c18', nodeBorder: '#5a3328', clusterBkg: '#221414', clusterBorder: '#5a3328', titleColor: '#e0d0c8', edgeLabelBackground: '#221414', nodeTextColor: '#e0d0c8' },\n      forest: { primaryColor: '#152e1a', primaryTextColor: '#c8d8c8', primaryBorderColor: '#264a2c', lineColor: '#264a2c', secondaryColor: '#111f14', tertiaryColor: '#18281a', background: '#0c1a0f', mainBkg: '#152e1a', nodeBorder: '#264a2c', clusterBkg: '#111f14', clusterBorder: '#264a2c', titleColor: '#c8d8c8', edgeLabelBackground: '#111f14', nodeTextColor: '#c8d8c8' },\n      daylight: { primaryColor: '#e8ecf4', primaryTextColor: '#1a2030', primaryBorderColor: '#b0b8cc', lineColor: '#b0b8cc', secondaryColor: '#f0f2f8', tertiaryColor: '#ffffff', background: '#f8f9fb', mainBkg: '#e8ecf4', nodeBorder: '#b0b8cc', clusterBkg: '#ffffff', clusterBorder: '#dde1ea', titleColor: '#1a2030', edgeLabelBackground: '#ffffff', nodeTextColor: '#1a2030' },\n      paper: { primaryColor: '#f0ebe0', primaryTextColor: '#2a2218', primaryBorderColor: '#c8bda8', lineColor: '#c8bda8', secondaryColor: '#f5f0e8', tertiaryColor: '#fffefa', background: '#faf8f5', mainBkg: '#f0ebe0', nodeBorder: '#c8bda8', clusterBkg: '#fffefa', clusterBorder: '#e0d8cc', titleColor: '#2a2218', edgeLabelBackground: '#fffefa', nodeTextColor: '#2a2218' }\n    };\n\n    function getSystemPreference() {\n      if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n        return 'midnight';\n      }\n      return 'daylight';\n    }\n\n    function resolveTheme() {\n      if (INITIAL_THEME) return INITIAL_THEME;\n      try {\n        var stored = localStorage.getItem(STORAGE_KEY);\n        if (stored) return stored;\n      } catch(e) {}\n      return getSystemPreference();\n    }\n\n    // Restyle SVG nodes after Mermaid renders to match the active theme.\n    // Mermaid classDef styles are baked into SVG elements as inline style with !important,\n    // so we must directly modify the style attribute to override them.\n    function rethemeSvgNodes(themeName) {\n      var isDark = DARK_THEMES.indexOf(themeName) >= 0;\n      var vars = MERMAID_THEME_VARS[themeName] || MERMAID_THEME_VARS.midnight;\n      var svg = document.querySelector('.mermaid svg');\n      if (!svg) return;\n      // Mark container as themed so CSS can reveal the SVG\n      var container = document.getElementById('mermaid-diagram');\n      if (container) container.classList.add('themed');\n      // Override all label-container shapes (nodes)\n      var shapes = svg.querySelectorAll('.label-container');\n      shapes.forEach(function(el) {\n        el.setAttribute('style', 'fill:' + vars.primaryColor + ' !important;stroke:' + vars.primaryBorderColor + ' !important;stroke-width:1px !important');\n      });\n      // Override node labels text color\n      var labels = svg.querySelectorAll('.nodeLabel, .label');\n      labels.forEach(function(el) {\n        el.style.color = vars.primaryTextColor;\n        el.style.fill = vars.primaryTextColor;\n      });\n      // Override edge paths\n      var edges = svg.querySelectorAll('.flowchart-link');\n      edges.forEach(function(el) {\n        el.style.stroke = vars.lineColor;\n      });\n      // Override edge labels\n      var edgeLabels = svg.querySelectorAll('.edgeLabel');\n      edgeLabels.forEach(function(el) {\n        el.style.backgroundColor = vars.edgeLabelBackground;\n        el.style.color = vars.primaryTextColor;\n      });\n      var edgeLabelRects = svg.querySelectorAll('.edgeLabel rect');\n      edgeLabelRects.forEach(function(el) {\n        el.setAttribute('style', 'fill:' + vars.edgeLabelBackground + ' !important');\n      });\n      // Override arrowheads\n      var markers = svg.querySelectorAll('.marker, .arrowMarkerPath');\n      markers.forEach(function(el) {\n        el.setAttribute('style', 'fill:' + vars.lineColor + ' !important;stroke:' + vars.lineColor + ' !important');\n      });\n    }\n\n    function applyTheme(name, skipRerender) {\n      document.documentElement.setAttribute('data-theme', name);\n      try { localStorage.setItem(STORAGE_KEY, name); } catch(e) {}\n      // Update mermaid theme with custom variables matching our theme\n      var vars = MERMAID_THEME_VARS[name] || MERMAID_THEME_VARS.midnight;\n      mermaid.initialize({ startOnLoad: false, theme: 'base', themeVariables: vars, securityLevel: 'loose' });\n      if (!skipRerender) {\n        var el = document.getElementById('mermaid-diagram');\n        if (el) {\n          // Restore diagram source text before re-rendering (after initial render the element contains SVG, not source)\n          var dataOn = document.getElementById('toggleDataFlow').checked;\n          var errorOn = document.getElementById('toggleErrorFlow').checked;\n          var src = DIAGRAMS.base;\n          if (dataOn) src = DIAGRAMS.dataFlow;\n          if (errorOn) src = DIAGRAMS.errorFlow;\n          if (dataOn && errorOn) src = DIAGRAMS.dataFlow;\n          el.textContent = src;\n          el.removeAttribute('data-processed');\n          el.classList.remove('themed');\n          mermaid.init(undefined, el);\n          rethemeOnRender(name);\n        }\n      }\n      // Update active state in menu\n      var btns = document.querySelectorAll('.theme-menu button');\n      btns.forEach(function(b) {\n        b.classList.toggle('active', b.textContent.toLowerCase() === name);\n      });\n      document.getElementById('theme-menu').classList.remove('open');\n    }\n\n    function toggleThemeMenu() {\n      document.getElementById('theme-menu').classList.toggle('open');\n    }\n\n    // Close menu on outside click\n    document.addEventListener('click', function(e) {\n      var picker = document.querySelector('.theme-picker');\n      if (picker && !picker.contains(e.target)) {\n        document.getElementById('theme-menu').classList.remove('open');\n      }\n    });\n\n    // Listen for system preference changes\n    if (window.matchMedia) {\n      window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {\n        // Only react if no explicit theme was set\n        try {\n          if (!localStorage.getItem(STORAGE_KEY) && !INITIAL_THEME) {\n            applyTheme(e.matches ? 'midnight' : 'daylight');\n          }\n        } catch(ex) {}\n      });\n    }\n\n    // Retheme as soon as mermaid inserts an SVG into the diagram element.\n    // Uses a MutationObserver to avoid timing guesswork and prevent the flash\n    // of default classDef colors (e.g. green Start node) before theme colors apply.\n    // The SVG stays hidden (via CSS visibility:hidden) until rethemeSvgNodes adds .themed.\n    function rethemeOnRender(themeName) {\n      var el = document.getElementById('mermaid-diagram');\n      if (!el) return;\n      el.classList.remove('themed');\n      function applyAfterFrame() {\n        // Yield two frames so mermaid finishes applying its inline !important styles\n        requestAnimationFrame(function() {\n          requestAnimationFrame(function() {\n            rethemeSvgNodes(themeName);\n          });\n        });\n      }\n      // If SVG is already present (synchronous path), retheme after frame\n      if (el.querySelector('svg')) { applyAfterFrame(); return; }\n      var obs = new MutationObserver(function(mutations, observer) {\n        if (el.querySelector('svg')) {\n          observer.disconnect();\n          applyAfterFrame();\n        }\n      });\n      obs.observe(el, { childList: true, subtree: true });\n    }\n\n    // Apply initial theme (skip re-render since Mermaid hasn't rendered yet)\n    applyTheme(resolveTheme(), true);\n\n    // Init Mermaid (single init on page load)\n    var currentThemeName = resolveTheme();\n    var initVars = MERMAID_THEME_VARS[currentThemeName] || MERMAID_THEME_VARS.midnight;\n    mermaid.initialize({ startOnLoad: true, theme: 'base', themeVariables: initVars, securityLevel: 'loose' });\n\n    // Watch for the initial mermaid render and retheme immediately\n    rethemeOnRender(currentThemeName);\n\n    const IR_DATA = ${irJson};\n    const PATHS_DATA = ${pathsJson};\n    const COMPLEXITY = ${complexityJson};\n    const DIAGRAMS = {\n      base: ${JSON.stringify(mermaidCode)},\n      dataFlow: ${JSON.stringify(mermaidWithDataFlow)},\n      errorFlow: ${JSON.stringify(mermaidWithErrorFlow)}\n    };\n\n    // Complexity stats\n    document.getElementById('complexity-stats').textContent =\n      'CC: ' + COMPLEXITY.cyclomaticComplexity +\n      ' | Cognitive: ' + COMPLEXITY.cognitiveComplexity +\n      ' | Depth: ' + COMPLEXITY.maxDepth +\n      ' | Paths: ' + COMPLEXITY.pathCount;\n\n    // Complexity table\n    var ct = document.getElementById('complexity-table');\n    ct.innerHTML = Object.entries(COMPLEXITY).map(function(e) {\n      return '<tr><td>' + e[0] + '</td><td><b>' + e[1] + '</b></td></tr>';\n    }).join('');\n\n    // Paths list\n    var pl = document.getElementById('paths-list');\n    var pathSelect = document.getElementById('pathSelect');\n    PATHS_DATA.forEach(function(p, i) {\n      var div = document.createElement('div');\n      div.className = 'path-item';\n      div.onclick = function() { selectPath(i); };\n      div.innerHTML = '<b>Path ' + (i+1) + '</b> (' + p.steps.length + ' steps)<br>' +\n        p.steps.map(function(s) { return '<span class=\"path-step\">' + (s.name||s.nodeId) + '</span>'; }).join(' \\u2192 ');\n      pl.appendChild(div);\n      var opt = document.createElement('option');\n      opt.value = i;\n      opt.textContent = 'Path ' + (i+1) + ' (' + p.steps.length + ' steps)';\n      pathSelect.appendChild(opt);\n    });\n\n    // Build flat node index for click-to-navigate\n    var nodeIndex = {};\n    function indexNodes(nodes) {\n      if (!nodes) return;\n      nodes.forEach(function(n) {\n        if (n.id) nodeIndex[n.id] = n;\n        // Recurse into known child arrays\n        if (n.children) indexNodes(n.children);\n        if (n.onTrue) indexNodes(n.onTrue);\n        if (n.onFalse) indexNodes(n.onFalse);\n        if (n.tryBody) indexNodes(n.tryBody);\n        if (n.catchBody) indexNodes(n.catchBody);\n        if (n.finallyBody) indexNodes(n.finallyBody);\n        if (n.body) indexNodes(n.body);\n        if (n.yields) n.yields.forEach(function(y) { if (y.effect) indexNodes([y.effect]); });\n        if (n.source && n.source.id) indexNodes([n.source]);\n        if (n.handler && n.handler.id) indexNodes([n.handler]);\n        if (n.operations) indexNodes(n.operations);\n        if (n.cases) n.cases.forEach(function(c) { if (c.body) indexNodes(c.body); });\n      });\n    }\n    indexNodes(IR_DATA.root.children);\n\n    // Type filter populate\n    var types = new Set();\n    function collectTypes(nodes) {\n      if (!nodes) return;\n      nodes.forEach(function(n) {\n        types.add(n.type);\n        if (n.children) collectTypes(n.children);\n        if (n.onTrue) collectTypes(n.onTrue);\n        if (n.onFalse) collectTypes(n.onFalse);\n        if (n.body) collectTypes(n.body);\n        if (n.tryBody) collectTypes(n.tryBody);\n        if (n.catchBody) collectTypes(n.catchBody);\n      });\n    }\n    collectTypes(IR_DATA.root.children);\n    var tf = document.getElementById('typeFilter');\n    Array.from(types).sort().forEach(function(t) {\n      var opt = document.createElement('option');\n      opt.value = t; opt.textContent = t;\n      tf.appendChild(opt);\n    });\n\n    // Tab switching\n    function showTab(name) {\n      document.querySelectorAll('.tab-content').forEach(function(el) { el.hidden = true; });\n      document.querySelectorAll('.sidebar-tabs button').forEach(function(el) { el.classList.remove('active'); });\n      document.getElementById('tab-' + name).hidden = false;\n      event.target.classList.add('active');\n    }\n\n    // Search\n    function handleSearch(q) {\n      // Simple text highlight in IR tab\n      var pre = document.getElementById('ir-json');\n      if (!q) { pre.innerHTML = JSON.stringify(IR_DATA, null, 2); return; }\n      var text = JSON.stringify(IR_DATA, null, 2);\n      var escaped = q.replace(/[.*+?^\\${}()|\\\\[\\\\]\\\\\\\\]/g, '\\\\\\\\$&');\n      pre.innerHTML = text.replace(new RegExp(escaped, 'gi'), '<mark>$&</mark>');\n    }\n\n    function handleTypeFilter(type) {\n      // Scroll IR to first occurrence of selected type\n      if (!type) return;\n      var pre = document.getElementById('ir-json');\n      var text = pre.textContent;\n      var idx = text.indexOf('\"type\": \"' + type + '\"');\n      if (idx >= 0) {\n        showTab('ir');\n        document.querySelectorAll('.sidebar-tabs button').forEach(function(b) {\n          b.classList.toggle('active', b.textContent === 'IR');\n        });\n      }\n    }\n\n    // Overlay toggles\n    function toggleOverlay(kind) {\n      var el = document.getElementById('mermaid-diagram');\n      var dataOn = document.getElementById('toggleDataFlow').checked;\n      var errorOn = document.getElementById('toggleErrorFlow').checked;\n      var src = DIAGRAMS.base;\n      if (dataOn) src = DIAGRAMS.dataFlow;\n      if (errorOn) src = DIAGRAMS.errorFlow;\n      if (dataOn && errorOn) src = DIAGRAMS.dataFlow; // data takes precedence\n      el.textContent = src;\n      el.removeAttribute('data-processed');\n      el.classList.remove('themed');\n      mermaid.init(undefined, el);\n      var curTheme = document.documentElement.getAttribute('data-theme') || 'midnight';\n      rethemeOnRender(curTheme);\n    }\n\n    // Path selection\n    function selectPath(idx) {\n      idx = parseInt(idx);\n      document.querySelectorAll('.path-item').forEach(function(el, i) {\n        el.classList.toggle('selected', i === idx);\n      });\n    }\n\n    // Click-to-navigate: show node details when clicking on diagram nodes\n    function truncLabel(s, max) {\n      if (!s || s.length <= max) return s;\n      return s.slice(0, max) + '…';\n    }\n    var LABEL_MAX = 60;\n    function showNodeDetails(nodeId) {\n      var node = nodeIndex[nodeId];\n      if (!node) return;\n      var det = document.getElementById('node-details');\n      var loc = node.location ? node.location.filePath + ':' + node.location.line + ':' + node.location.column : 'N/A';\n      var html = '<h3>Node Details</h3>';\n      html += '<table>';\n      html += '<tr><td>ID</td><td><code>' + node.id + '</code></td></tr>';\n      html += '<tr><td>Type</td><td><b>' + node.type + '</b></td></tr>';\n      if (node.callee) html += '<tr><td>Callee</td><td>' + truncLabel(node.callee, LABEL_MAX) + '</td></tr>';\n      if (node.displayName) html += '<tr><td>Display</td><td>' + truncLabel(node.displayName, LABEL_MAX) + '</td></tr>';\n      if (node.semanticRole) html += '<tr><td>Role</td><td>' + node.semanticRole + '</td></tr>';\n      html += '<tr><td>Location</td><td><code>' + loc + '</code></td></tr>';\n      if (node.typeSignature) {\n        var sig = node.typeSignature;\n        html += '<tr><td>Type Sig</td><td><code>Effect&lt;' + (sig.successType||'?') + ', ' + (sig.errorType||'?') + ', ' + (sig.requirementsType||'?') + '&gt;</code></td></tr>';\n      }\n      html += '</table>';\n      if (node.description) html += '<p style=\"margin-top:0.5rem;opacity:0.8\">' + node.description + '</p>';\n      det.innerHTML = html;\n      // Switch to details tab\n      document.querySelectorAll('.tab-content').forEach(function(el) { el.hidden = true; });\n      document.querySelectorAll('.sidebar-tabs button').forEach(function(b) { b.classList.remove('active'); });\n      document.getElementById('tab-details').hidden = false;\n      document.querySelectorAll('.sidebar-tabs button')[0].classList.add('active');\n    }\n\n    // Register Mermaid click callbacks after rendering.\n    // The initial retheme is handled by rethemeOnRender above.\n    function bindNodeClicks() {\n      var svgNodes = document.querySelectorAll('.mermaid svg .node');\n      svgNodes.forEach(function(el) {\n        el.style.cursor = 'pointer';\n        el.addEventListener('click', function() {\n          var id = el.id || '';\n          for (var key in nodeIndex) {\n            if (id.indexOf(key) >= 0 || id.indexOf(key.replace(/[^a-zA-Z0-9]/g, '_')) >= 0) {\n              showNodeDetails(key);\n              return;\n            }\n          }\n        });\n      });\n    }\n    // Observe the diagram element; bind clicks once SVG appears\n    (function() {\n      var el = document.getElementById('mermaid-diagram');\n      if (!el) return;\n      var obs = new MutationObserver(function() {\n        if (el.querySelector('svg')) { obs.disconnect(); bindNodeClicks(); }\n      });\n      obs.observe(el, { childList: true, subtree: true });\n    })();\n  </scr` + `ipt>\n</body>\n</html>`;\n}\n\nfunction escapeHtml(s: string): string {\n  return s\n    .replace(/&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;');\n}\n","/**\n * Documentation Generation for Effect IR\n *\n * Generates comprehensive markdown documentation from analyzed Effect programs:\n * workflow steps, service dependencies, complexity metrics, and embedded diagrams.\n */\n\nimport type { StaticEffectIR, StaticFlowNode } from '../types';\nimport { getStaticChildren } from '../types';\nimport { Option } from 'effect';\nimport { calculateComplexity } from '../complexity';\nimport { renderStaticMermaid } from './mermaid';\nimport { analyzeErrorFlow } from '../error-flow';\nimport { buildDataFlowGraph } from '../data-flow';\nimport { DEFAULT_LABEL_MAX, truncateDisplayText } from '../analysis-utils';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface DocSection {\n  title: string;\n  content: string;\n}\n\nexport interface DocumentationOptions {\n  /** Include Mermaid diagram in documentation */\n  includeDiagram?: boolean | undefined;\n  /** Include complexity metrics */\n  includeComplexity?: boolean | undefined;\n  /** Include service dependency table */\n  includeServiceDeps?: boolean | undefined;\n  /** Include error type documentation */\n  includeErrors?: boolean | undefined;\n  /** Include data flow information */\n  includeDataFlow?: boolean | undefined;\n}\n\nconst DEFAULT_DOC_OPTIONS: Required<DocumentationOptions> = {\n  includeDiagram: true,\n  includeComplexity: true,\n  includeServiceDeps: true,\n  includeErrors: true,\n  includeDataFlow: true,\n};\n\n// =============================================================================\n// Step Collection\n// =============================================================================\n\ninterface WorkflowStep {\n  name: string;\n  type: string;\n  description: string;\n  depth: number;\n}\n\nfunction collectWorkflowSteps(\n  nodes: readonly StaticFlowNode[],\n  steps: WorkflowStep[],\n  depth: number,\n): void {\n  for (const node of nodes) {\n    const step = describeNode(node, depth);\n    if (step) steps.push(step);\n\n    const children = Option.getOrElse(getStaticChildren(node), () => []);\n    if (children.length > 0) {\n      collectWorkflowSteps(children, steps, depth + 1);\n    }\n  }\n}\n\nfunction describeNode(node: StaticFlowNode, depth: number): WorkflowStep | null {\n  switch (node.type) {\n    case 'effect':\n      return {\n        name: truncateDisplayText(node.callee || 'Effect', DEFAULT_LABEL_MAX),\n        type: 'effect',\n        description: truncateDisplayText(\n          node.displayName ?? node.callee,\n          DEFAULT_LABEL_MAX,\n        ),\n        depth,\n      };\n    case 'error-handler':\n      return {\n        name: node.handlerType,\n        type: 'error-handler',\n        description: `Error handler: ${node.handlerType}${node.errorTag ? ` (catches ${node.errorTag})` : ''}`,\n        depth,\n      };\n    case 'parallel':\n      return {\n        name: node.callee || 'parallel',\n        type: 'parallel',\n        description: `Parallel execution of ${node.children.length} effects`,\n        depth,\n      };\n    case 'race':\n      return {\n        name: node.callee || 'race',\n        type: 'race',\n        description: `Race between ${node.children.length} effects`,\n        depth,\n      };\n    case 'retry':\n      return {\n        name: 'Retry',\n        type: 'retry',\n        description: `Retry${node.schedule ? ` with schedule: ${node.schedule}` : ''}`,\n        depth,\n      };\n    case 'timeout':\n      return {\n        name: 'Timeout',\n        type: 'timeout',\n        description: `Timeout${node.duration ? ` after ${node.duration}` : ''}`,\n        depth,\n      };\n    case 'resource':\n      return {\n        name: 'Resource',\n        type: 'resource',\n        description: 'Acquire/Release resource lifecycle',\n        depth,\n      };\n    case 'conditional':\n      return {\n        name: node.conditionalType,\n        type: 'conditional',\n        description: truncateDisplayText(\n          `Conditional: ${node.condition}`,\n          DEFAULT_LABEL_MAX,\n        ),\n        depth,\n      };\n    case 'decision':\n      return {\n        name: node.label || 'decision',\n        type: 'decision',\n        description: `Decision: ${node.label || node.condition}`,\n        depth,\n      };\n    case 'loop':\n      return {\n        name: node.loopType,\n        type: 'loop',\n        description: truncateDisplayText(\n          `Loop: ${node.loopType}${node.iterSource ? ` over ${node.iterSource}` : ''}`,\n          DEFAULT_LABEL_MAX,\n        ),\n        depth,\n      };\n    case 'layer':\n      return {\n        name: 'Layer',\n        type: 'layer',\n        description: `Layer${node.provides?.length ? ` providing: ${node.provides.join(', ')}` : ''}`,\n        depth,\n      };\n    case 'stream':\n      return {\n        name: 'Stream',\n        type: 'stream',\n        description: truncateDisplayText(\n          `Stream pipeline${node.pipeline.length > 0 ? `: ${node.pipeline.map(p => p.operation).join(' → ')}` : ''}`,\n          DEFAULT_LABEL_MAX,\n        ),\n        depth,\n      };\n    case 'fiber':\n      return {\n        name: node.operation,\n        type: 'fiber',\n        description: `Fiber: ${node.operation}${node.isDaemon ? ' (daemon)' : ''}${node.isScoped ? ' (scoped)' : ''}`,\n        depth,\n      };\n    default:\n      return null;\n  }\n}\n\n// =============================================================================\n// Rendering\n// =============================================================================\n\n/**\n * Generate comprehensive markdown documentation from an analyzed Effect IR.\n */\nexport function renderDocumentation(\n  ir: StaticEffectIR,\n  options?: Partial<DocumentationOptions>,\n): string {\n  const opts = { ...DEFAULT_DOC_OPTIONS, ...options };\n  const sections: string[] = [];\n\n  // Title\n  sections.push(`# ${ir.root.programName}`);\n  sections.push('');\n\n  // Description\n  if (ir.root.jsdocDescription) {\n    sections.push(ir.root.jsdocDescription);\n    sections.push('');\n  }\n\n  // Overview\n  sections.push('## Overview');\n  sections.push('');\n  sections.push(`- **Source**: \\`${ir.metadata.filePath}\\``);\n  sections.push(`- **Entry**: ${ir.root.source}`);\n  if (ir.root.typeSignature) {\n    const sig = ir.root.typeSignature;\n    sections.push(`- **Type**: \\`Effect<${sig.successType}, ${sig.errorType}, ${sig.requirementsType}>\\``);\n  }\n  sections.push('');\n\n  // Workflow Steps\n  const steps: WorkflowStep[] = [];\n  collectWorkflowSteps(ir.root.children, steps, 0);\n  if (steps.length > 0) {\n    sections.push('## Workflow Steps');\n    sections.push('');\n    for (const step of steps) {\n      const indent = '  '.repeat(step.depth);\n      sections.push(`${indent}- **${step.name}** _(${step.type})_: ${step.description}`);\n    }\n    sections.push('');\n  }\n\n  // Service Dependencies\n  if (opts.includeServiceDeps && ir.root.dependencies.length > 0) {\n    sections.push('## Service Dependencies');\n    sections.push('');\n    sections.push('| Service | Type | Layer |');\n    sections.push('|---------|------|-------|');\n    for (const dep of ir.root.dependencies) {\n      sections.push(`| ${dep.name} | ${dep.typeSignature ?? '-'} | ${dep.isLayer ? 'Yes' : 'No'} |`);\n    }\n    sections.push('');\n  }\n\n  // Error Types\n  if (opts.includeErrors) {\n    const errorFlow = analyzeErrorFlow(ir);\n    if (errorFlow.allErrors.length > 0) {\n      sections.push('## Error Types');\n      sections.push('');\n      for (const error of errorFlow.allErrors) {\n        const producers = errorFlow.errorToSteps.get(error) ?? [];\n        sections.push(`- **${error}**: produced by ${producers.length} step(s)`);\n      }\n      sections.push('');\n    }\n  }\n\n  // Complexity\n  if (opts.includeComplexity) {\n    const complexity = calculateComplexity(ir);\n    sections.push('## Complexity Metrics');\n    sections.push('');\n    sections.push(`| Metric | Value |`);\n    sections.push(`|--------|-------|`);\n    sections.push(`| Cyclomatic Complexity | ${complexity.cyclomaticComplexity} |`);\n    sections.push(`| Cognitive Complexity | ${complexity.cognitiveComplexity} |`);\n    sections.push(`| Max Depth | ${complexity.maxDepth} |`);\n    sections.push(`| Decision Points | ${complexity.decisionPoints} |`);\n    sections.push(`| Max Parallel Breadth | ${complexity.maxParallelBreadth} |`);\n    sections.push('');\n  }\n\n  // Data Flow\n  if (opts.includeDataFlow) {\n    const dataFlow = buildDataFlowGraph(ir);\n    if (dataFlow.undefinedReads.length > 0 || dataFlow.duplicateWrites.length > 0) {\n      sections.push('## Data Flow Warnings');\n      sections.push('');\n      for (const read of dataFlow.undefinedReads) {\n        sections.push(`- **Undefined read**: \\`${read.key}\\` read by ${read.readerName ?? read.readerId}`);\n      }\n      for (const dup of dataFlow.duplicateWrites) {\n        sections.push(`- **Duplicate write**: \\`${dup.key}\\` written by ${dup.writerIds.join(', ')}`);\n      }\n      sections.push('');\n    }\n  }\n\n  // Diagram\n  if (opts.includeDiagram) {\n    sections.push('## Flow Diagram');\n    sections.push('');\n    sections.push('```mermaid');\n    sections.push(renderStaticMermaid(ir));\n    sections.push('```');\n    sections.push('');\n  }\n\n  return sections.join('\\n');\n}\n\n/**\n * Generate documentation for multiple programs.\n */\nexport function renderMultiProgramDocs(\n  irs: readonly StaticEffectIR[],\n  options?: Partial<DocumentationOptions>,\n): string {\n  const sections: string[] = [];\n\n  sections.push('# Effect Program Documentation');\n  sections.push('');\n  sections.push(`Generated: ${new Date().toISOString()}`);\n  sections.push('');\n\n  // Table of contents\n  sections.push('## Programs');\n  sections.push('');\n  for (const ir of irs) {\n    sections.push(`- [${ir.root.programName}](#${ir.root.programName.toLowerCase().replace(/[^a-z0-9]/g, '-')})`);\n  }\n  sections.push('');\n\n  // Each program\n  for (const ir of irs) {\n    sections.push('---');\n    sections.push('');\n    sections.push(renderDocumentation(ir, options));\n    sections.push('');\n  }\n\n  return sections.join('\\n');\n}\n","/**\n * Plain-English explanation renderer for Effect IR trees.\n *\n * Walks the static IR and produces a human-readable narrative\n * describing what an Effect program does.\n */\n\nimport type {\n  StaticEffectIR,\n  StaticFlowNode,\n  StaticEffectProgram,\n} from '../types';\nimport {\n  DEFAULT_LABEL_MAX,\n  canonicalizeServiceDisplayName,\n  truncateDisplayText,\n} from '../analysis-utils';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst indent = (depth: number): string => '  '.repeat(depth);\n\n/** Summarise a node in a short inline phrase (no newline). */\nfunction shortLabel(node: StaticFlowNode): string {\n  const t = (s: string, max = DEFAULT_LABEL_MAX) => truncateDisplayText(s, max);\n  switch (node.type) {\n    case 'effect': {\n      if (node.constructorKind === 'callback') return t(node.tracedName ?? node.displayName ?? node.callee);\n      if (node.usePattern) {\n        const wrapper = node.serviceCall?.serviceType ?? node.usePattern.wrapperName;\n        return t(`${wrapper}.use`);\n      }\n      if (node.serviceCall) {\n        return t(`${node.serviceCall.serviceType}.${node.serviceCall.methodName}`);\n      }\n      return t(node.displayName ?? node.callee);\n    }\n    case 'generator':\n      return 'Effect.gen block';\n    case 'pipe':\n      return t(`pipe(${shortLabel(node.initial)})`);\n    case 'parallel':\n      return t(`${node.callee}(${node.children.length} effects)`);\n    case 'race':\n      return t(`${node.callee}(${node.children.length} effects)`);\n    case 'error-handler':\n      return node.handlerType;\n    case 'retry':\n      return 'retry';\n    case 'timeout':\n      return node.duration ? `timeout(${node.duration})` : 'timeout';\n    case 'resource':\n      return 'acquireRelease';\n    case 'conditional':\n      return `if ${node.conditionLabel ?? node.condition}`;\n    case 'loop':\n      return t(\n        `${node.loopType}${node.iterSource ? `(${node.iterSource})` : ''}`,\n      );\n    case 'layer':\n      return node.provides ? `Layer(${node.provides.join(', ')})` : 'Layer';\n    case 'stream':\n      return node.pipeline.length > 0\n        ? `Stream.${node.pipeline.map((op) => op.operation).join(' -> ')}`\n        : 'Stream';\n    case 'fiber':\n      return `Fiber.${node.operation}`;\n    case 'concurrency-primitive':\n      return `${node.primitive}.${node.operation}`;\n    case 'decision':\n      return `if ${node.condition}`;\n    case 'switch':\n      return `switch(${node.expression})`;\n    case 'try-catch':\n      return 'try/catch';\n    case 'terminal':\n      return node.terminalKind;\n    case 'match':\n      return node.matchedTags ? `Match(${node.matchedTags.join(', ')})` : 'Match';\n    case 'transform':\n      return node.transformType;\n    case 'channel':\n      return 'Channel';\n    case 'sink':\n      return 'Sink';\n    case 'cause':\n      return `Cause.${node.causeOp}`;\n    case 'exit':\n      return `Exit.${node.exitOp}`;\n    case 'schedule':\n      return `Schedule.${node.scheduleOp}`;\n    case 'interruption':\n      return node.interruptionType;\n    case 'opaque':\n      return `(opaque: ${node.reason})`;\n    case 'unknown':\n      return `(unknown: ${node.reason})`;\n  }\n}\n\n/** Track whether parallel/race nodes are encountered during a walk. */\ninterface WalkState {\n  hasParallelism: boolean;\n  serviceCallsSeen: Set<string>;\n}\n\nconst shouldSuppressExplainEffectNode = (node: Extract<StaticFlowNode, { type: 'effect' }>): boolean => {\n  if (node.serviceCall || node.usePattern || node.constructorKind === 'callback') return false;\n  if (node.constructorKind === 'fn' || node.constructorKind === 'fnUntraced') return true;\n  if (node.description === 'function-lift' || node.callee === 'fn' || node.callee === 'Effect.fn') {\n    return true;\n  }\n  return false;\n};\n\n// ---------------------------------------------------------------------------\n// Core recursive walker\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively walks a `StaticFlowNode` and produces indented description lines.\n */\nexport function explainNode(\n  node: StaticFlowNode,\n  depth: number,\n  state: WalkState = { hasParallelism: false, serviceCallsSeen: new Set() },\n): string[] {\n  const pad = indent(depth);\n  const lines: string[] = [];\n\n  switch (node.type) {\n    // ----- effect -----------------------------------------------------------\n    case 'effect': {\n      if (shouldSuppressExplainEffectNode(node)) break;\n      if (node.constructorKind === 'callback') {\n        const label = truncateDisplayText(\n          node.tracedName ?? node.displayName ?? node.callee,\n          DEFAULT_LABEL_MAX,\n        );\n        lines.push(`${pad}Registers callback bridge: ${label}`);\n        if (node.asyncCallback) {\n          lines.push(\n            `${pad}  Callback: ${node.asyncCallback.resumeCallCount} resume call${node.asyncCallback.resumeCallCount === 1 ? '' : 's'}${node.asyncCallback.returnsCanceller ? ', returns cleanup' : ''}`,\n          );\n        }\n        if (node.callbackBody && node.callbackBody.length > 0) {\n          lines.push(`${pad}  Inner effects:`);\n          for (const child of node.callbackBody) {\n            lines.push(...explainNode(child, depth + 2, state));\n          }\n        }\n        break;\n      }\n      if (node.usePattern) {\n        const wrapper = node.serviceCall?.serviceType ?? node.usePattern.wrapperName;\n        state.serviceCallsSeen.add(canonicalizeServiceDisplayName(wrapper));\n        const desc = node.description ? ` — ${node.description}` : '';\n        lines.push(`${pad}Uses ${wrapper} via .use callback${desc}`);\n        if (node.callbackBody && node.callbackBody.length > 0) {\n          lines.push(`${pad}  Callback:`);\n          for (const child of node.callbackBody) {\n            lines.push(...explainNode(child, depth + 2, state));\n          }\n        }\n        break;\n      }\n      if (node.serviceCall) {\n        state.serviceCallsSeen.add(\n          canonicalizeServiceDisplayName(node.serviceCall.serviceType),\n        );\n        // Tag-style service acquisition (e.g. yield* Logger)\n        if (\n          node.callee.includes('Tag') ||\n          node.callee.includes('Context') ||\n          node.callee === node.serviceCall.serviceType\n        ) {\n          lines.push(`${pad}Acquires ${node.serviceCall.serviceType} service`);\n        } else {\n          const desc = node.description ? ` — ${node.description}` : '';\n          lines.push(\n            `${pad}Calls ${node.serviceCall.serviceType}.${node.serviceCall.methodName}${desc}`,\n          );\n        }\n      } else {\n        const label = truncateDisplayText(\n          node.displayName ?? node.callee,\n          DEFAULT_LABEL_MAX,\n        );\n        const desc = node.description ? ` — ${node.description}` : '';\n        // If displayName has a binding arrow (e.g. \"logger <- Logger\"), it's a service yield\n        if (label.includes(' <- ')) {\n          lines.push(`${pad}Yields ${label}`);\n        } else {\n          lines.push(`${pad}Calls ${label}${desc}`);\n        }\n      }\n      if (node.callbackBody && node.callbackBody.length > 0) {\n        lines.push(`${pad}  Callback:`);\n        for (const child of node.callbackBody) {\n          lines.push(...explainNode(child, depth + 2, state));\n        }\n      }\n      break;\n    }\n\n    // ----- generator --------------------------------------------------------\n    case 'generator': {\n      for (const y of node.yields) {\n        const childLines = explainNode(y.effect, depth, state);\n        // If variableName and the displayName already contains it (e.g. \"logger <- Logger\"),\n        // skip adding it again. Otherwise prefix with \"varName = ...\"\n        const firstChild = childLines[0];\n        if (y.variableName && firstChild !== undefined) {\n          const trimmed = firstChild.trimStart();\n          const alreadyHasBinding = trimmed.includes(`${y.variableName} <-`) || trimmed.includes(`${y.variableName} =`);\n          if (!alreadyHasBinding) {\n            childLines[0] = `${pad}${y.variableName} = ${trimmed.replace(/^Calls /, '')}`;\n          }\n        }\n        lines.push(...childLines);\n      }\n      if (node.returnNode) {\n        const retLines = explainNode(node.returnNode, depth, state);\n        const firstRet = retLines[0];\n        if (firstRet !== undefined) {\n          const trimmed = firstRet.trimStart();\n          retLines[0] = `${pad}Returns ${trimmed.replace(/^Calls /, '')}`;\n          lines.push(...retLines);\n        }\n      }\n      break;\n    }\n\n    // ----- pipe -------------------------------------------------------------\n    case 'pipe': {\n      lines.push(`${pad}Pipes ${shortLabel(node.initial)} through:`);\n      const initLines = explainNode(node.initial, depth + 1, state);\n      lines.push(...initLines);\n      for (const t of node.transformations) {\n        const tLines = explainNode(t, depth + 1, state);\n        lines.push(...tLines);\n      }\n      break;\n    }\n\n    // ----- parallel ---------------------------------------------------------\n    case 'parallel': {\n      state.hasParallelism = true;\n      const concDesc =\n        node.concurrency !== undefined && node.concurrency !== 'sequential'\n          ? ` (concurrency: ${node.concurrency})`\n          : '';\n      lines.push(\n        `${pad}Runs ${node.children.length} effects in ${node.mode}${concDesc}:`,\n      );\n      for (const child of node.children) {\n        lines.push(...explainNode(child, depth + 1, state));\n      }\n      break;\n    }\n\n    // ----- race -------------------------------------------------------------\n    case 'race': {\n      state.hasParallelism = true;\n      lines.push(`${pad}Races ${node.children.length} effects:`);\n      for (const child of node.children) {\n        lines.push(...explainNode(child, depth + 1, state));\n      }\n      break;\n    }\n\n    // ----- error-handler ----------------------------------------------------\n    case 'error-handler': {\n      const tagInfo = node.errorTag\n        ? ` \"${node.errorTag}\"`\n        : node.errorTags && node.errorTags.length > 0\n          ? ` [${node.errorTags.join(', ')}]`\n          : '';\n      switch (node.handlerType) {\n        case 'catch':\n          lines.push(`${pad}Catches all errors on:`);\n          break;\n        case 'catchTag':\n          lines.push(`${pad}Catches tag${tagInfo} on:`);\n          break;\n        case 'catchTags':\n          lines.push(`${pad}Catches tags${tagInfo} on:`);\n          break;\n        case 'orElse':\n          lines.push(`${pad}Falls back (orElse) on error:`);\n          break;\n        case 'orDie':\n          lines.push(`${pad}Converts errors to defects (orDie):`);\n          break;\n        case 'mapError':\n          lines.push(`${pad}Maps error on:`);\n          break;\n        case 'ignore':\n          lines.push(`${pad}Ignores errors on:`);\n          break;\n        default:\n          lines.push(`${pad}Handles errors (${node.handlerType})${tagInfo}:`);\n      }\n      lines.push(...explainNode(node.source, depth + 1, state));\n      if (node.handler) {\n        lines.push(`${pad}  Handler:`);\n        lines.push(...explainNode(node.handler, depth + 2, state));\n      }\n      break;\n    }\n\n    // ----- retry ------------------------------------------------------------\n    case 'retry': {\n      if (node.scheduleInfo) {\n        const maxPart =\n          node.scheduleInfo.maxRetries !== undefined\n            ? `max ${node.scheduleInfo.maxRetries}`\n            : '';\n        const stratPart = node.scheduleInfo.baseStrategy;\n        const parts = [maxPart, stratPart].filter(Boolean).join(', ');\n        lines.push(`${pad}Retries (${parts}):`);\n      } else if (node.schedule) {\n        lines.push(`${pad}Retries with ${node.schedule}:`);\n      } else {\n        lines.push(`${pad}Retries:`);\n      }\n      lines.push(...explainNode(node.source, depth + 1, state));\n      if (node.hasFallback) {\n        lines.push(`${pad}  (with fallback on exhaustion)`);\n      }\n      break;\n    }\n\n    // ----- timeout ----------------------------------------------------------\n    case 'timeout': {\n      const dur = node.duration ? ` after ${node.duration}` : '';\n      lines.push(`${pad}Times out${dur}:`);\n      lines.push(...explainNode(node.source, depth + 1, state));\n      if (node.hasFallback) {\n        lines.push(`${pad}  (with fallback on timeout)`);\n      }\n      break;\n    }\n\n    // ----- resource ---------------------------------------------------------\n    case 'resource': {\n      lines.push(`${pad}Acquires resource:`);\n      lines.push(...explainNode(node.acquire, depth + 1, state));\n      if (node.use) {\n        lines.push(`${pad}  Uses:`);\n        lines.push(...explainNode(node.use, depth + 2, state));\n      }\n      lines.push(`${pad}  Then releases:`);\n      lines.push(...explainNode(node.release, depth + 2, state));\n      break;\n    }\n\n    // ----- conditional ------------------------------------------------------\n    case 'conditional': {\n      const label = node.conditionLabel ?? node.condition;\n      lines.push(`${pad}If ${label}:`);\n      lines.push(...explainNode(node.onTrue, depth + 1, state));\n      if (node.onFalse) {\n        lines.push(`${pad}Else:`);\n        lines.push(...explainNode(node.onFalse, depth + 1, state));\n      }\n      break;\n    }\n\n    // ----- decision ---------------------------------------------------------\n    case 'decision': {\n      lines.push(`${pad}If ${node.condition}:`);\n      for (const child of node.onTrue) {\n        lines.push(...explainNode(child, depth + 1, state));\n      }\n      if (node.onFalse && node.onFalse.length > 0) {\n        lines.push(`${pad}Else:`);\n        for (const child of node.onFalse) {\n          lines.push(...explainNode(child, depth + 1, state));\n        }\n      }\n      break;\n    }\n\n    // ----- switch -----------------------------------------------------------\n    case 'switch': {\n      lines.push(`${pad}Switch on ${node.expression}:`);\n      for (const c of node.cases) {\n        const caseLabel = c.isDefault\n          ? 'default'\n          : c.labels.join(', ');\n        lines.push(`${pad}  Case ${caseLabel}:`);\n        for (const child of c.body) {\n          lines.push(...explainNode(child, depth + 2, state));\n        }\n      }\n      break;\n    }\n\n    // ----- try-catch --------------------------------------------------------\n    case 'try-catch': {\n      lines.push(`${pad}Try:`);\n      for (const child of node.tryBody) {\n        lines.push(...explainNode(child, depth + 1, state));\n      }\n      if (node.catchBody && node.catchBody.length > 0) {\n        lines.push(`${pad}Catch:`);\n        for (const child of node.catchBody) {\n          lines.push(...explainNode(child, depth + 1, state));\n        }\n      }\n      if (node.finallyBody && node.finallyBody.length > 0) {\n        lines.push(`${pad}Finally:`);\n        for (const child of node.finallyBody) {\n          lines.push(...explainNode(child, depth + 1, state));\n        }\n      }\n      break;\n    }\n\n    // ----- terminal ---------------------------------------------------------\n    case 'terminal': {\n      switch (node.terminalKind) {\n        case 'return': {\n          if (node.value && node.value.length > 0) {\n            lines.push(`${pad}Returns:`);\n            for (const child of node.value) {\n              lines.push(...explainNode(child, depth + 1, state));\n            }\n          } else {\n            lines.push(`${pad}Returns`);\n          }\n          break;\n        }\n        case 'throw':\n          lines.push(`${pad}Throws`);\n          break;\n        case 'break':\n          lines.push(`${pad}Breaks`);\n          break;\n        case 'continue':\n          lines.push(`${pad}Continues`);\n          break;\n      }\n      break;\n    }\n\n    // ----- loop -------------------------------------------------------------\n    case 'loop': {\n      const src = node.iterSource\n        ? ` over ${truncateDisplayText(node.iterSource, DEFAULT_LABEL_MAX)}`\n        : '';\n      lines.push(`${pad}Iterates (${node.loopType})${src}:`);\n      lines.push(...explainNode(node.body, depth + 1, state));\n      if (node.callbackBody && node.callbackBody.length > 0) {\n        lines.push(`${pad}  Callback:`);\n        for (const child of node.callbackBody) {\n          lines.push(...explainNode(child, depth + 2, state));\n        }\n      }\n      break;\n    }\n\n    // ----- layer ------------------------------------------------------------\n    case 'layer': {\n      const provides =\n        node.provides && node.provides.length > 0\n          ? ` providing ${node.provides.join(', ')}`\n          : '';\n      const requires =\n        node.requires && node.requires.length > 0\n          ? ` (requires ${node.requires.join(', ')})`\n          : '';\n      lines.push(`${pad}Provides layer${provides}${requires}:`);\n      for (const op of node.operations) {\n        lines.push(...explainNode(op, depth + 1, state));\n      }\n      break;\n    }\n\n    // ----- stream -----------------------------------------------------------\n    case 'stream': {\n      const ops = node.pipeline.map((o) => o.operation).join(' -> ');\n      const sinkPart = node.sink ? ` -> ${node.sink}` : '';\n      const serviceStreamSource =\n        node.source.type === 'effect' &&\n        node.source.serviceCall?.methodName.startsWith('stream')\n          ? `${node.source.serviceCall.serviceType}.${node.source.serviceCall.methodName}`\n          : undefined;\n      const isReactor =\n        node.pipeline.some((op) => op.operation === 'runForEach') &&\n        (node.constructorType === 'fromPubSub' ||\n          node.constructorType === 'fromSubscriptionRef' ||\n          node.constructorType === 'fromEventListener' ||\n          serviceStreamSource !== undefined);\n      if (isReactor) {\n        const sourceKind =\n          serviceStreamSource ??\n          node.constructorType?.replace(/^from/, '') ??\n          'event source';\n        lines.push(`${pad}Background stream reactor (${sourceKind}): ${ops}${sinkPart}`);\n      } else {\n        lines.push(`${pad}Stream: ${ops}${sinkPart}`);\n      }\n      lines.push(...explainNode(node.source, depth + 1, state));\n      for (const op of node.pipeline) {\n        if (op.callbackBody && op.callbackBody.length > 0) {\n          lines.push(`${pad}  ${op.operation} callback:`);\n          for (const child of op.callbackBody) {\n            lines.push(...explainNode(child, depth + 2, state));\n          }\n        }\n      }\n      break;\n    }\n\n    // ----- fiber ------------------------------------------------------------\n    case 'fiber': {\n      const scopeNote = node.isDaemon ? ' (daemon)' : node.isScoped ? ' (scoped)' : '';\n      lines.push(`${pad}Fiber ${node.operation}${scopeNote}:`);\n      if (node.fiberSource) {\n        lines.push(...explainNode(node.fiberSource, depth + 1, state));\n      }\n      break;\n    }\n\n    // ----- concurrency-primitive --------------------------------------------\n    case 'concurrency-primitive': {\n      const cap = node.capacity !== undefined ? ` (capacity: ${node.capacity})` : '';\n      lines.push(`${pad}${node.primitive}.${node.operation}${cap}`);\n      if (node.source) {\n        lines.push(...explainNode(node.source, depth + 1, state));\n      }\n      break;\n    }\n\n    // ----- match ------------------------------------------------------------\n    case 'match': {\n      if (node.matchedTags && node.matchedTags.length > 0) {\n        lines.push(`${pad}Matches tags: ${node.matchedTags.join(', ')}`);\n      } else {\n        lines.push(`${pad}Match (${node.matchOp})`);\n      }\n      break;\n    }\n\n    // ----- transform --------------------------------------------------------\n    case 'transform': {\n      lines.push(`${pad}Transforms via ${node.transformType}`);\n      if (node.source) {\n        lines.push(...explainNode(node.source, depth + 1, state));\n      }\n      break;\n    }\n\n    // ----- cause ------------------------------------------------------------\n    case 'cause': {\n      lines.push(`${pad}Cause.${node.causeOp}`);\n      if (node.children) {\n        for (const child of node.children) {\n          lines.push(...explainNode(child, depth + 1, state));\n        }\n      }\n      break;\n    }\n\n    // ----- exit -------------------------------------------------------------\n    case 'exit': {\n      lines.push(`${pad}Exit.${node.exitOp}`);\n      break;\n    }\n\n    // ----- schedule ---------------------------------------------------------\n    case 'schedule': {\n      lines.push(`${pad}Schedule.${node.scheduleOp}`);\n      break;\n    }\n\n    // ----- channel ----------------------------------------------------------\n    case 'channel': {\n      const ops = node.pipeline.map((o) => o.operation).join(' -> ');\n      lines.push(`${pad}Channel${ops ? `: ${ops}` : ''}`);\n      if (node.source) {\n        lines.push(...explainNode(node.source, depth + 1, state));\n      }\n      break;\n    }\n\n    // ----- sink -------------------------------------------------------------\n    case 'sink': {\n      const ops = node.pipeline.map((o) => o.operation).join(' -> ');\n      lines.push(`${pad}Sink${ops ? `: ${ops}` : ''}`);\n      if (node.source) {\n        lines.push(...explainNode(node.source, depth + 1, state));\n      }\n      break;\n    }\n\n    // ----- interruption -----------------------------------------------------\n    case 'interruption': {\n      lines.push(`${pad}${node.interruptionType}`);\n      if (node.source) {\n        lines.push(...explainNode(node.source, depth + 1, state));\n      }\n      if (node.handler) {\n        lines.push(`${pad}  On interrupt:`);\n        lines.push(...explainNode(node.handler, depth + 2, state));\n      }\n      break;\n    }\n\n    // ----- opaque -----------------------------------------------------------\n    case 'opaque': {\n      if (node.reason === 'callback-body' || node.reason === 'predicate') {\n        lines.push(`${pad}${truncateDisplayText(node.sourceText, DEFAULT_LABEL_MAX)}`);\n      } else {\n        lines.push(`${pad}(opaque: ${node.reason})`);\n      }\n      break;\n    }\n\n    // ----- unknown ----------------------------------------------------------\n    case 'unknown': {\n      lines.push(`${pad}(unknown: ${node.reason})`);\n      break;\n    }\n  }\n\n  return lines;\n}\n\n// ---------------------------------------------------------------------------\n// Program-level renderer\n// ---------------------------------------------------------------------------\n\nfunction renderProgram(program: StaticEffectProgram, _ir: StaticEffectIR): string {\n  const state: WalkState = {\n    hasParallelism: false,\n    serviceCallsSeen: new Set(),\n  };\n\n  // Collect body lines from children\n  const bodyLines: string[] = [];\n  const visibleChildren =\n    program.children.length > 1 &&\n    program.children[0]?.type === 'effect' &&\n    (program.children[0].constructorKind === 'fn' ||\n      program.children[0].constructorKind === 'fnUntraced')\n      ? program.children.slice(1)\n      : program.children;\n  const childrenToRender =\n    visibleChildren.some((child) => child.type === 'generator')\n      ? visibleChildren.filter((child) => child.type === 'generator')\n      : visibleChildren;\n  for (const child of childrenToRender) {\n    bodyLines.push(...explainNode(child, 1, state));\n  }\n\n  // Number top-level steps\n  const numberedLines = numberTopLevelSteps(bodyLines);\n\n  // Header\n  const header = `${program.programName} (${program.source}):`;\n\n  // Footer sections\n  const footer: string[] = [];\n\n  // Services required\n  const services = new Set<string>();\n  for (const dep of program.dependencies) {\n    if (dep.name !== 'Effect') {\n      services.add(canonicalizeServiceDisplayName(dep.name));\n    }\n  }\n  Array.from(state.serviceCallsSeen).forEach((svc) => {\n    if (svc !== 'Effect') {\n      services.add(canonicalizeServiceDisplayName(svc));\n    }\n  });\n  if (services.size > 0) {\n    footer.push(`  Services required: ${Array.from(services).join(', ')}`);\n  }\n\n  // Error paths\n  if (program.errorTypes.length > 0) {\n    footer.push(`  Error paths: ${program.errorTypes.join(', ')}`);\n  }\n\n  // Concurrency\n  if (state.hasParallelism) {\n    footer.push('  Concurrency: uses parallelism / racing');\n  } else {\n    footer.push('  Concurrency: sequential (no parallelism)');\n  }\n\n  const sections = [header, numberedLines.join('\\n')];\n  if (footer.length > 0) {\n    sections.push('');\n    sections.push(footer.join('\\n'));\n  }\n\n  return sections.join('\\n');\n}\n\n/**\n * Numbers lines at depth=1 (2 leading spaces) as top-level steps,\n * leaving deeper lines unchanged.\n */\nfunction numberTopLevelSteps(lines: string[]): string[] {\n  let step = 0;\n  return lines.map((line) => {\n    // Depth-1 lines start with exactly 2 spaces then a non-space character\n    if (/^ {2}\\S/.test(line)) {\n      step++;\n      return `  ${step}. ${line.trimStart()}`;\n    }\n    return line;\n  });\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Renders a full plain-English explanation for a single Effect IR program.\n */\nexport function renderExplanation(ir: StaticEffectIR): string {\n  return renderProgram(ir.root, ir);\n}\n\n/**\n * Renders explanations for multiple programs, separated by `---`.\n */\nexport function renderMultipleExplanations(irs: readonly StaticEffectIR[]): string {\n  return irs.map((ir) => renderExplanation(ir)).join('\\n\\n---\\n\\n');\n}\n","/**\n * Summary Output Module\n *\n * Produces ultra-compact one-liner-per-program output for quick overview\n * of Effect program characteristics.\n */\n\nimport type { StaticEffectIR } from '../types';\nimport { calculateComplexity } from '../complexity';\n\n// =============================================================================\n// Source Kind Abbreviations\n// =============================================================================\n\nconst SOURCE_ABBREVIATIONS: Record<StaticEffectIR['root']['source'], string> = {\n  generator: 'gen',\n  direct: 'direct',\n  pipe: 'pipe',\n  run: 'run',\n  'workflow-execute': 'wf-exec',\n  class: 'class',\n  classProperty: 'classProp',\n  classMethod: 'classMeth',\n  functionDeclaration: 'fnDecl',\n};\n\nfunction abbreviateSource(source: StaticEffectIR['root']['source']): string {\n  return SOURCE_ABBREVIATIONS[source];\n}\n\n// =============================================================================\n// Single Program Summary\n// =============================================================================\n\n/**\n * Render a one-line summary for a single Effect program IR.\n *\n * Format:\n *   programName | gen | 6 steps | 2 services | 0 errors | 1 handler | complexity: 2\n */\nexport function renderSummary(ir: StaticEffectIR): string {\n  const name = ir.root.programName;\n  const kind = abbreviateSource(ir.root.source);\n  const steps = ir.metadata.stats.totalEffects;\n  const services = ir.root.dependencies.length;\n  const errors = ir.root.errorTypes.length;\n  const handlers = ir.metadata.stats.errorHandlerCount;\n  const complexity = calculateComplexity(ir).cyclomaticComplexity;\n\n  return [\n    name,\n    kind,\n    `${steps} steps`,\n    `${services} services`,\n    `${errors} errors`,\n    `${handlers} ${handlers === 1 ? 'handler' : 'handlers'}`,\n    `complexity: ${complexity}`,\n  ].join(' | ');\n}\n\n// =============================================================================\n// Multiple Program Summary Table\n// =============================================================================\n\ninterface SummaryRow {\n  readonly program: string;\n  readonly kind: string;\n  readonly steps: number;\n  readonly services: number;\n  readonly errors: number;\n  readonly handlers: number;\n  readonly complexity: number;\n}\n\nfunction extractRow(ir: StaticEffectIR): SummaryRow {\n  return {\n    program: ir.root.programName,\n    kind: abbreviateSource(ir.root.source),\n    steps: ir.metadata.stats.totalEffects,\n    services: ir.root.dependencies.length,\n    errors: ir.root.errorTypes.length,\n    handlers: ir.metadata.stats.errorHandlerCount,\n    complexity: calculateComplexity(ir).cyclomaticComplexity,\n  };\n}\n\n/**\n * Render a formatted, column-aligned table summarizing multiple Effect program IRs.\n *\n * Example output:\n *   Program          | Kind | Steps | Services | Errors | Handlers | Complexity\n *   -----------------+------+-------+----------+--------+----------+-----------\n *   serviceProgram   | gen  |     6 |        2 |      0 |        0 |          2\n *   databaseProgram  | gen  |     5 |        2 |      1 |        1 |          3\n */\nexport function renderMultipleSummaries(irs: readonly StaticEffectIR[]): string {\n  if (irs.length === 0) {\n    return '(no programs)';\n  }\n\n  const rows = irs.map(extractRow);\n\n  // Header labels\n  const headers = {\n    program: 'Program',\n    kind: 'Kind',\n    steps: 'Steps',\n    services: 'Services',\n    errors: 'Errors',\n    handlers: 'Handlers',\n    complexity: 'Complexity',\n  };\n\n  // Calculate column widths: max of header width and all row values\n  const widths = {\n    program: Math.max(headers.program.length, ...rows.map((r) => r.program.length)),\n    kind: Math.max(headers.kind.length, ...rows.map((r) => r.kind.length)),\n    steps: Math.max(headers.steps.length, ...rows.map((r) => String(r.steps).length)),\n    services: Math.max(headers.services.length, ...rows.map((r) => String(r.services).length)),\n    errors: Math.max(headers.errors.length, ...rows.map((r) => String(r.errors).length)),\n    handlers: Math.max(headers.handlers.length, ...rows.map((r) => String(r.handlers).length)),\n    complexity: Math.max(headers.complexity.length, ...rows.map((r) => String(r.complexity).length)),\n  };\n\n  const padRight = (s: string, w: number) => s + ' '.repeat(Math.max(0, w - s.length));\n  const padLeft = (s: string, w: number) => ' '.repeat(Math.max(0, w - s.length)) + s;\n\n  // Header line\n  const headerLine = [\n    padRight(headers.program, widths.program),\n    padRight(headers.kind, widths.kind),\n    padRight(headers.steps, widths.steps),\n    padRight(headers.services, widths.services),\n    padRight(headers.errors, widths.errors),\n    padRight(headers.handlers, widths.handlers),\n    padRight(headers.complexity, widths.complexity),\n  ].join(' | ');\n\n  // Separator line\n  const separatorLine = [\n    '-'.repeat(widths.program),\n    '-'.repeat(widths.kind),\n    '-'.repeat(widths.steps),\n    '-'.repeat(widths.services),\n    '-'.repeat(widths.errors),\n    '-'.repeat(widths.handlers),\n    '-'.repeat(widths.complexity),\n  ].join('-+-');\n\n  // Data rows: program left-aligned, numeric columns right-aligned\n  const dataLines = rows.map((row) =>\n    [\n      padRight(row.program, widths.program),\n      padRight(row.kind, widths.kind),\n      padLeft(String(row.steps), widths.steps),\n      padLeft(String(row.services), widths.services),\n      padLeft(String(row.errors), widths.errors),\n      padLeft(String(row.handlers), widths.handlers),\n      padLeft(String(row.complexity), widths.complexity),\n    ].join(' | '),\n  );\n\n  return [headerLine, separatorLine, ...dataLines].join('\\n');\n}\n","/**\n * Test Coverage Matrix Generator\n *\n * Generates a test coverage matrix from Effect paths, helping developers\n * ensure all paths through an Effect program are tested.\n */\n\nimport type {\n  EffectPath,\n  TestMatrix,\n  TestPath,\n  TestCondition,\n  TestMatrixSummary,\n} from '../types';\n\n// =============================================================================\n// Options\n// =============================================================================\n\nexport interface TestMatrixOptions {\n  /** Prefix for generated test names */\n  testNamePrefix?: string;\n  /** Function to customize test name generation */\n  testNameGenerator?: (path: EffectPath) => string;\n  /** Whether to include paths with loops (they may need special handling) */\n  includeLoopPaths?: boolean;\n}\n\nconst DEFAULT_OPTIONS: Required<TestMatrixOptions> = {\n  testNamePrefix: 'should',\n  testNameGenerator: defaultTestNameGenerator,\n  includeLoopPaths: true,\n};\n\n// =============================================================================\n// Main Generator\n// =============================================================================\n\nexport function generateTestMatrix(\n  paths: EffectPath[],\n  options: TestMatrixOptions = {},\n): TestMatrix {\n  const opts = { ...DEFAULT_OPTIONS, ...options };\n\n  let filteredPaths = paths;\n  if (!opts.includeLoopPaths) {\n    filteredPaths = paths.filter((p) => !p.hasLoops);\n  }\n\n  const testPaths = filteredPaths.map((path) => generateTestPath(path, opts));\n  const conditions = extractConditions(filteredPaths);\n  const summary = calculateSummary(testPaths, conditions);\n\n  return {\n    paths: testPaths,\n    conditions,\n    summary,\n  };\n}\n\n// =============================================================================\n// Test Path Generation\n// =============================================================================\n\nfunction generateTestPath(\n  path: EffectPath,\n  opts: Required<TestMatrixOptions>,\n): TestPath {\n  const testName = opts.testNameGenerator(path);\n  const priority = determinePriority(path);\n\n  const setupConditions = path.conditions.map((c) => {\n    const verb = c.mustBe ? 'be truthy' : 'be falsy';\n    return `Set up ${c.expression} to ${verb}`;\n  });\n\n  const expectedSteps = path.steps.map((s) => {\n    const name = s.name ?? s.nodeId;\n    return s.repeated ? `${name} (may repeat)` : name;\n  });\n\n  return {\n    id: path.id,\n    suggestedTestName: testName,\n    description: path.description,\n    setupConditions,\n    expectedSteps,\n    priority,\n  };\n}\n\nfunction determinePriority(path: EffectPath): 'high' | 'medium' | 'low' {\n  if (path.conditions.length === 0 && !path.hasLoops) {\n    return 'high';\n  }\n  if (path.hasLoops && path.conditions.length > 2) {\n    return 'low';\n  }\n  return 'medium';\n}\n\nfunction defaultTestNameGenerator(path: EffectPath): string {\n  const parts: string[] = ['should'];\n\n  if (path.steps.length > 0) {\n    const mainSteps = path.steps.filter((s) => !s.repeated).slice(0, 3);\n    if (mainSteps.length > 0) {\n      const stepNames = mainSteps.map((s) =>\n        camelToSpaces(s.name ?? s.nodeId),\n      );\n      parts.push(stepNames.join(' then '));\n    }\n  }\n\n  if (path.conditions.length > 0) {\n    parts.push('when');\n    const conditionDescriptions = path.conditions.slice(0, 2).map((c) => {\n      const simplified = simplifyCondition(c.expression);\n      return c.mustBe ? simplified : `not ${simplified}`;\n    });\n    parts.push(conditionDescriptions.join(' and '));\n  }\n\n  if (path.hasLoops) {\n    parts.push('(with iteration)');\n  }\n\n  return parts.join(' ');\n}\n\nfunction camelToSpaces(str: string): string {\n  return str\n    .replace(/([a-z])([A-Z])/g, '$1 $2')\n    .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2')\n    .toLowerCase();\n}\n\nfunction simplifyCondition(expression: string): string {\n  return expression\n    .replace(/\\s*===\\s*true/g, '')\n    .replace(/\\s*===\\s*false/g, ' is false')\n    .replace(/\\s*===\\s*/g, ' is ')\n    .replace(/\\s*!==\\s*/g, ' is not ')\n    .replace(/\\s*>\\s*/g, ' greater than ')\n    .replace(/\\s*<\\s*/g, ' less than ')\n    .replace(/\\s*>=\\s*/g, ' at least ')\n    .replace(/\\s*<=\\s*/g, ' at most ')\n    .replace(/&&/g, ' and ')\n    .replace(/\\|\\|/g, ' or ')\n    .trim();\n}\n\n// =============================================================================\n// Condition Extraction\n// =============================================================================\n\nfunction extractConditions(paths: EffectPath[]): TestCondition[] {\n  const conditionMap = new Map<\n    string,\n    { whenTrue: string[]; whenFalse: string[] }\n  >();\n\n  for (const path of paths) {\n    for (const condition of path.conditions) {\n      const key = condition.expression;\n\n      if (!conditionMap.has(key)) {\n        conditionMap.set(key, { whenTrue: [], whenFalse: [] });\n      }\n\n      const entry = conditionMap.get(key);\n      if (entry) {\n        if (condition.mustBe) {\n          entry.whenTrue.push(path.id);\n        } else {\n          entry.whenFalse.push(path.id);\n        }\n      }\n    }\n  }\n\n  return Array.from(conditionMap.entries()).map(([expression, affected]) => ({\n    expression,\n    affectedPathsWhenTrue: affected.whenTrue,\n    affectedPathsWhenFalse: affected.whenFalse,\n  }));\n}\n\n// =============================================================================\n// Summary\n// =============================================================================\n\nfunction calculateSummary(\n  paths: TestPath[],\n  conditions: TestCondition[],\n): TestMatrixSummary {\n  const highPriorityPaths = paths.filter((p) => p.priority === 'high').length;\n  const minTestsForCoverage = Math.max(\n    1,\n    conditions.length * 2,\n  );\n\n  return {\n    totalPaths: paths.length,\n    highPriorityPaths,\n    totalConditions: conditions.length,\n    minTestsForCoverage,\n  };\n}\n\n// =============================================================================\n// Output Formatting\n// =============================================================================\n\nexport function formatTestMatrixMarkdown(matrix: TestMatrix): string {\n  const lines: string[] = [];\n\n  lines.push('# Test Coverage Matrix');\n  lines.push('');\n  lines.push('## Summary');\n  lines.push('');\n  lines.push(`- **Total Paths:** ${matrix.summary.totalPaths}`);\n  lines.push(`- **High Priority Paths:** ${matrix.summary.highPriorityPaths}`);\n  lines.push(`- **Conditions to Test:** ${matrix.summary.totalConditions}`);\n  lines.push(\n    `- **Minimum Tests for Coverage:** ${matrix.summary.minTestsForCoverage}`,\n  );\n  lines.push('');\n\n  lines.push('## Test Cases');\n  lines.push('');\n\n  const highPriority = matrix.paths.filter((p) => p.priority === 'high');\n  const mediumPriority = matrix.paths.filter((p) => p.priority === 'medium');\n  const lowPriority = matrix.paths.filter((p) => p.priority === 'low');\n\n  if (highPriority.length > 0) {\n    lines.push('### High Priority');\n    lines.push('');\n    for (const path of highPriority) {\n      lines.push(...formatTestPathLines(path));\n    }\n    lines.push('');\n  }\n\n  if (mediumPriority.length > 0) {\n    lines.push('### Medium Priority');\n    lines.push('');\n    for (const path of mediumPriority) {\n      lines.push(...formatTestPathLines(path));\n    }\n    lines.push('');\n  }\n\n  if (lowPriority.length > 0) {\n    lines.push('### Low Priority');\n    lines.push('');\n    for (const path of lowPriority) {\n      lines.push(...formatTestPathLines(path));\n    }\n    lines.push('');\n  }\n\n  if (matrix.conditions.length > 0) {\n    lines.push('## Conditions Coverage');\n    lines.push('');\n    lines.push('| Condition | Paths When True | Paths When False |');\n    lines.push('|-----------|-----------------|------------------|');\n\n    for (const condition of matrix.conditions) {\n      const truncatedExpr =\n        condition.expression.length > 40\n          ? condition.expression.slice(0, 40) + '...'\n          : condition.expression;\n      const trueCount = condition.affectedPathsWhenTrue.length;\n      const falseCount = condition.affectedPathsWhenFalse.length;\n      lines.push(`| \\`${truncatedExpr}\\` | ${trueCount} | ${falseCount} |`);\n    }\n    lines.push('');\n  }\n\n  lines.push('## Test Checklist');\n  lines.push('');\n  for (const path of matrix.paths) {\n    const priority =\n      path.priority === 'high'\n        ? 'HIGH'\n        : path.priority === 'medium'\n          ? 'MED'\n          : 'LOW';\n    lines.push(`- [ ] [${priority}] ${path.suggestedTestName}`);\n  }\n  lines.push('');\n\n  return lines.join('\\n');\n}\n\nfunction formatTestPathLines(path: TestPath): string[] {\n  const lines: string[] = [];\n  lines.push(`#### ${path.suggestedTestName}`);\n  lines.push('');\n\n  if (path.setupConditions.length > 0) {\n    lines.push('**Setup:**');\n    for (const condition of path.setupConditions) {\n      lines.push(`- ${condition}`);\n    }\n    lines.push('');\n  }\n\n  lines.push('**Expected Steps:**');\n  for (let i = 0; i < path.expectedSteps.length; i++) {\n    lines.push(`${i + 1}. ${path.expectedSteps[i]}`);\n  }\n  lines.push('');\n\n  return lines;\n}\n\nexport function formatTestMatrixAsCode(\n  matrix: TestMatrix,\n  options: {\n    testRunner?: 'vitest' | 'jest' | 'mocha';\n    programName?: string;\n  } = {},\n): string {\n  const runner = options.testRunner ?? 'vitest';\n  const programName = options.programName ?? 'program';\n\n  const lines: string[] = [];\n\n  if (runner === 'vitest') {\n    lines.push(\"import { describe, it, expect } from 'vitest';\");\n  } else if (runner === 'jest') {\n    lines.push('// Jest test file');\n  } else {\n    lines.push(\"import { describe, it } from 'mocha';\");\n    lines.push(\"import { expect } from 'chai';\");\n  }\n\n  lines.push('');\n  lines.push(`describe('${programName}', () => {`);\n\n  for (const path of matrix.paths) {\n    lines.push('');\n    lines.push(`  it('${escapeString(path.suggestedTestName)}', async () => {`);\n    lines.push('    // Setup');\n    for (const condition of path.setupConditions) {\n      lines.push(`    // TODO: ${condition}`);\n    }\n    lines.push('');\n    lines.push('    // Execute effect program');\n    lines.push(`    // const result = await Effect.runPromise(${programName});`);\n    lines.push('');\n    lines.push('    // Verify expected steps executed');\n    for (const step of path.expectedSteps) {\n      lines.push(`    // TODO: Verify ${step} was executed`);\n    }\n    lines.push('  });');\n  }\n\n  lines.push('});');\n  lines.push('');\n\n  return lines.join('\\n');\n}\n\nfunction escapeString(str: string): string {\n  return str.replace(/'/g, \"\\\\'\").replace(/\"/g, '\\\\\"');\n}\n\nexport function formatTestChecklist(matrix: TestMatrix): string {\n  const lines: string[] = [];\n\n  lines.push('Test Coverage Checklist');\n  lines.push('=======================');\n  lines.push('');\n  lines.push(`Total: ${matrix.summary.totalPaths} tests needed`);\n  lines.push(`High Priority: ${matrix.summary.highPriorityPaths}`);\n  lines.push('');\n\n  for (const path of matrix.paths) {\n    const marker =\n      path.priority === 'high'\n        ? '***'\n        : path.priority === 'medium'\n          ? '**'\n          : '*';\n    lines.push(`[ ] ${marker} ${path.suggestedTestName}`);\n    if (path.setupConditions.length > 0) {\n      lines.push(`    Conditions: ${path.setupConditions.join(', ')}`);\n    }\n  }\n\n  return lines.join('\\n');\n}\n"],"mappings":"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AClCE,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,eACA,WACA,cACA,WACA,UACA,UACA,iBACA,gBACA,YACA,YACA,UACA,aACA,aACA,eACA,eACA,WACA,OACA,WACA,aACA,WACF,EAEaC,GAAsB,IAAI,IAAI,CACzC,QAAS,gBAAiB,SAAU,SAAU,UAAW,SACzD,WAAY,UAAW,OAAQ,OAAQ,SAAU,QAAS,MAC1D,MAAO,UAAW,UAAW,SAAU,SAAU,OAAQ,UACzD,UAAW,SAAU,eAAgB,SAAU,WAAY,iBAC7D,CAAC,EAEYC,GAA0B,IAAI,IAAI,CAE7C,SAAU,QAAS,SAAU,QAAS,SAAU,WAAY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","names":["diagram_entry_exports","__export","DEFAULT_THRESHOLDS","IR_SCHEMA_VERSION","analyze","assessComplexity","buildTopOffendersReport","calculateComplexity","computeDiagramFidelity","computeFileDiagramQuality","computeProgramDiagramQuality","diffPrograms","explainNode","findStaticNodesForSpanPath","formatComplexitySummary","formatDiagramFidelity","formatTestChecklist","formatTestMatrixAsCode","formatTestMatrixMarkdown","generateTestMatrix","inferBestDiagramType","parseSourceArg","renderCausesMermaid","renderConcurrencyMermaid","renderDataflowMermaid","renderDecisionsMermaid","renderDiffJSON","renderDiffMarkdown","renderDiffMermaid","renderDocumentation","renderEnhancedMermaid","renderEnhancedMermaidEffect","renderErrorsMermaid","renderExplanation","renderInteractiveHTML","renderJSON","renderLayersMermaid","renderMermaid","renderMermaidWithRuntimeTrace","renderMultiProgramDocs","renderMultipleExplanations","renderMultipleJSON","renderMultipleSummaries","renderPathsMermaid","renderRailwayMermaid","renderRetryGanttMermaid","renderRetryMermaid","renderSequenceMermaid","renderServiceGraphMermaid","renderServicesMermaid","renderServicesMermaidFromMap","renderStaticMermaid","renderSummary","renderTestabilityMermaid","renderTimelineMermaid","resolveGitHubPR","resolveGitSource","resolveThemeName","summarizePathSteps","traceFromEffectSpans","traceFromOpenTelemetry","traceFromSpanTree","__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","getStaticChildren","node","y","retryNode","list","src","children","c","import_effect","import_effect","EFFECT_TYPE_REGEX_3","EFFECT_TYPE_REGEX_2","effectTypeSignatureFromTypeText","typeText","clean","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","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","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","tagIndex","rawText","descriptionMatch","leadingComments","lastComment","commentText","cleaned","extractJSDocTags","tryGetJsDocText","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","escapeMermaidLabel","extractFunctionName","withoutArgs","parts","receiver","computeDisplayName","variableName","fnName","wrapper","op","channelOps","sinkOps","countMeaningfulNodes","count","walk","computeSemanticRole","desc","unwrapExpression","expr","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","n","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","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","analyzeErrorHandlerCall","deps","call","callee","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","analyzePipeChain","node","sourceFile","filePath","opts","warnings","stats","serviceScope","SyntaxKind","loadTsMorph","args","expr","isMethodPipe","baseExpr","transformArgs","baseNode","resolveIdentifierToLayerInitializer","baseSourceFile","basePath","project","inProject","added","initial","transformations","analyzed","sourceOrderedSpanNames","spanNameDynamic","filteredTransformations","t","argText","match","spanNames","spanName","typeFlow","typeChecker","flow","initialSig","extractEffectTypeSignature","argNode","sig","pipeNode","generateId","computeDisplayName","computeSemanticRole","unwrapExpression","body","unknownNode","extractLocation","returnedExpr","stmt","analyzeEffectCall","text","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","ERROR_HANDLER_PATTERNS","pattern","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","DEFAULT_THRESHOLDS","calculateComplexity","ir","nodes","cyclomatic","calculateCyclomaticComplexity","cognitive","calculateCognitiveComplexity","pathCount","calculatePathCount","maxDepth","calculateMaxDepth","maxParallelBreadth","calculateMaxParallelBreadth","decisionPoints","countDecisionPoints","complexity","node","countDecisionPointsInNode","children","getStaticChildren","childList","count","child","calculateCognitiveForNodes","nestingDepth","calculateCognitiveForNode","caseItem","hasUnbounded","result","pathCountForNode","truePaths","pathCountForNodes","falsePaths","total","childPaths","product","c","casePaths","paths","depthOfNode","currentDepth","maxChildDepth","maxBreadth","parallelBreadthOfNode","assessComplexity","metrics","thresholds","warnings","recommendations","level","hasError","w","hasWarning","formatComplexitySummary","assessment","lines","warning","icon","rec","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","DEFAULT_OPTIONS","generatePaths","ir","options","generatePathsWithMetadata","context","initialState","generatePathsForNodes","state","index","generatePathDescription","nodes","currentState","states","node","newStates","generatePathsForNode","term","handleEffectNode","handleGeneratorNode","handlePipeNode","handleParallelNode","handleRaceNode","handleErrorHandlerNode","handleSingleChildNode","handleResourceNode","handleConditionalNode","handleLoopNode","handleLayerNode","handleStreamNode","handleConcurrencyOrFiberNode","handleDecisionNode","handleSwitchNode","handleTryCatchNode","handleTerminalNode","handleCauseNode","handleLeafStepNode","handleMatchNode","handleTransformNode","handleChannelNode","handleSinkNode","handleInterruptionNode","stepRef","children","y","combinedStates","child","newCombinedStates","childStates","childState","first","allStates","maxAllowed","roomLeft","toAdd","sourceStates","handlerStates","resourceNodes","trueCondition","trueState","trueStates","falseCondition","falseState","falseStates","step","idx","p","stateWithStep","caseItem","caseLabel","caseCondition","caseState","caseStates","tryStates","catchStates","catchCondition","catchState","combined","finalStates","_context","parts","conditionParts","c","verb","stepNames","s","name","import_effect","import_effect","collectEffectNodesInOrder","nodes","result","node","children","getStaticChildren","buildDataFlowGraph","ir","edges","producedKeys","keyProducers","effectNodesOrdered","eff","writes","reads","s","producers","i","from","to","key","contextId","undefinedReads","duplicateWrites","writers","import_effect","parseErrorTypes","errorType","splitTopLevelUnion","collectEffectErrors","nodes","result","node","eff","errors","children","getStaticChildren","analyzeErrorFlow","ir","stepErrors","allErrorsSet","errorToSteps","stepsWithoutErrors","step","error","steps","unionErrors","a","b","withoutErrors","current","removed","set","e","collectErrorsFromSubtree","out","visit","err","findCauseKindInSubtree","child","walkPropagation","errorsIn","own","handler","sourceErrors","afterNarrow","handlerErrors","causeKind","branchErrors","fromChild","analyzeErrorPropagation","propagation","byNodeId","p","DEFAULT_STYLES","DEFAULT_OPTIONS","escapeLabel","label","truncate","str","maxLength","sanitizeId","id","renderStaticMermaidInternal","ir","options","nodeLabelAnnotations","autoDetail","nodeCount","countMeaningfulNodes","opts","context","lines","startId","endId","firstNodeId","lastNodeIds","renderNodes","lastId","subgraph","line","edge","styles","usedStyleKeys","styleClass","key","value","nodeId","dataFlow","buildDataFlowGraph","irToMermaid","dfEdge","fromMermaid","toMermaid","read","mermaidId","dup","writerId","errorFlow","analyzeErrorFlow","errorPropagation","analyzeErrorPropagation","stepError","prop","handlerMermaid","nodeMermaid","narrowed","nodes","depth","prevLastNodeIds","node","result","renderNode","prevId","getNodeId","getNodeLabel","annotations","truncateDisplayText","DEFAULT_LABEL_MAX","p","usedDisplayName","annotationsHaveTypeSig","a","sig","filteredAnnotations","getNodeStyleClass","compactLeafTypes","summaryLabel","childResult","children","y","chain","forkId","joinId","modeLabel","i","child","branchResult","sourceResult","handlerNodeId","lastIds","handlerResult","wrapperId","acquireResult","resourceId","useResult","decisionId","condLabel","onTrueResult","onFalseResult","loopId","bodyLabel","bodyResult","trueResult","falseResult","switchId","switchLabel","caseItem","caseLabel","caseResult","warnId","tryResult","allLastIds","catchId","catchLabel","catchResult","finallyResult","termId","termLabel","valueResult","opaqueId","opaqueLabel","causeId","exitId","schedId","matchId","tag","tagNodeId","chanId","sinkId","intId","renderStaticMermaid","TRACE_STYLES","renderMermaidWithRuntimeTrace","trace","irIndex","indexIR","matchedSpanIds","suffixMatchedSpanIds","unmatchedSpanIds","ambiguousSpanIds","usedStatuses","assignments","span","staticIds","exact","start","ids","spanPathKey","staticId","status","renderMermaid","isLogLikeStep","name","n","isPureTransformLikeStep","isEnvironmentLikeStep","isServiceBoundaryLikeStep","prefix","applyServiceBoundaryPrefixes","steps","out","prefixed","step","summarizePathSteps","path","collapseLogs","collapseTransforms","collapseEnvironment","collapsedGroups","current","currentName","j","next","nextName","count","renderPathsMermaid","paths","direction","stepNodes","nodeCounter","displayPaths","displayPath","stepInfo","edges","firstStep","firstInfo","cur","curInfo","nextInfo","lastStep","lastInfo","DEFAULT_ENHANCED_OPTIONS","collectEnhancedAnnotations","map","showTypes","showServices","visit","services","s","t","c","op","renderEnhancedMermaid","enhancedOpts","mermaidOpts","renderEnhancedMermaidEffect","collectFiberNodes","getStaticChildren","renderSequenceMermaid","fibers","forks","f","joins","_f","raw","_","fid","collectRetryNodes","renderRetryGanttMermaid","retries","withSchedule","r","idx","info","max","renderServiceGraphMermaid","serviceMap","sgLines","sanitize","serviceId","artifact","methodCount","edgesAdded","layer","req","edgeKey","fromId","toId","MAX_PROGRAM_TIPS","MAX_FILE_TIPS","clamp","n","min","max","uniqueCapped","items","startsWithAllowedTipPrefix","tip","normalizeTip","collectAllNodes","nodes","out","visit","list","node","children","getStaticChildren","isLogLike","name","looksAnonymousEffectNode","callee","isServiceCallNode","hasNamedServiceCallee","c","computeMetrics","ir","options","detailedSteps","effects","sideEffects","logEffects","unknownNodes","anonymousNodeCount","serviceCalls","namedServiceCalls","pipeNodes","pipeChainCount","maxPipeChainLength","p","representativePath","generatePaths","a","b","summary","summarizePathSteps","ratioBase","serviceBase","scoreFromMetrics","metrics","unknownPenalty","anonymousPenalty","stepPenalty","logPenalty","sideEffectPenalty","score","band","reasonsFromMetrics","reasons","logCount","tipsFromMetrics","tips","computeProgramDiagramQuality","hintReasons","hintTips","aggregateMetrics","qualities","weights","q","totalWeight","weightedAvg","picker","sum","i","weightedSum","computeFileDiagramQuality","filePath","programs","programQualities","weightedScore","makeEntry","metricValue","rankTop","entries","valueOf","topN","dv","buildTopOffendersReport","fileQualities","capped","import_effect","addPaths","spans","byId","span","pathFor","seen","parent","traceFromEffectSpans","ended","hrDurationMs","start","end","traceFromOpenTelemetry","durationMs","traceFromSpanTree","trace","flat","walk","node","parentSpanId","child","root","import_effect","CONTAINER_TYPES","computeFingerprint","node","collectStepsWithContext","containerType","index","results","children","getStaticChildren","nextContainer","childIdx","child","childResults","countContainerTypes","counts","walk","diffPrograms","before","after","options","detectRenames","regressionMode","beforeSteps","afterSteps","matchedBeforeIdx","matchedAfterIdx","entries","matchByFingerprint","requireSameContainer","bIdx","beforeStep","candidates","aIdx","afterCandidate","bestIdx","bestDist","i","dist","afterStep","bStep","bi","matchedBefore","bs","as2","structuralChanges","beforeContainers","afterContainers","allContainerKeys","key","bCount","aCount","summary","e","sc","KIND_ICONS","formatStepLine","entry","icon","callee","renderDiffMarkdown","diff","options","showUnchanged","title","lines","visibleSteps","s","sc","prefix","renderDiffJSON","diff","options","buildStepIdMap","mermaidOutput","map","nodePattern","match","id","renderDiffMermaid","after","diff","options","direction","showRemoved","baseMermaid","renderStaticMermaid","_stepIdMap","addedIds","s","_removedIds","movedIds","renamedIds","irToMermaid","lines","styleLines","line","nodeMatch","mermaidId","label","step","irId","phantomId","import_node_child_process","parseSourceArg","arg","gitRefMatch","resolveGitSource","ref","filePath","cwd","error","msg","resolveGitHubPR","prUrl","result","data","import_effect","stepId","index","letter","cycle","stripErrorSuffix","name","extractErrorTypes","node","raw","splitTopLevelUnion","s","collectErrorTypes","seen","errors","visit","current","errorType","children","getStaticChildren","child","computeLabel","binding","stripped","labelled","truncateDisplayText","DEFAULT_LABEL_MAX","isTransparentRailwayNode","isOpaqueRailwayStep","isSkippedRailwayNode","isDefinitionNode","callee","isAnonymousEffect","NESTED","bindingOf","arrival","flattenNodesToSteps","nodes","steps","yielded","push","buildSteps","flat","renderRailwayMermaid","ir","options","direction","lines","errorLines","hasPerStepErrors","i","currentStep","id","label","escapeMermaidLabel","nextStep","nextId","nextLabel","errorTypes","errId","errLabel","lastId","import_effect","collectRequiredFromNode","node","result","reqs","r","x","children","getStaticChildren","c","getProvidedServiceId","getFirstArgText","callee","analyzeServiceFlow","ir","options","requiredServices","child","dedupedRequired","providedServices","unsatisfiedAt","consumedBy","available","getFirstArg","walk","nodes","eff","providedId","prov","list","u","serviceLifecycle","p","sanitizeId","text","renderServicesMermaid","ir","options","direction","requiredServices","providedServices","analyzeServiceFlow","depsFromIR","allServiceIds","req","dep","lines","programName","escapeMermaidLabel","serviceId","id","label","prov","renderServicesMermaidFromMap","serviceMap","artifact","methodCount","edgesAdded","layer","edgeKey","fromId","toId","sanitizeId","text","stripErrorSuffix","name","renderErrorsMermaid","ir","options","direction","errorFlow","analyzeErrorFlow","propagation","analyzeErrorPropagation","lines","handlerNodes","handledErrors","p","handlerId","err","unhandledErrors","e","stepsWithErrors","s","step","label","escapeMermaidLabel","error","handler","import_effect","DECISION_TYPES","truncate","text","max","nodeLabel","node","collectDecisionNodes","nodes","result","counter","visit","children","getStaticChildren","child","cond","dec","sw","c","findDecisionInfo","decisions","d","findFirstDecision","found","renderBranchTarget","terminalCounter","tId","decInfo","label","escapeMermaidLabel","renderArrayBranchTarget","firstNode","renderDecisionsMermaid","ir","options","direction","lines","nodeId","condText","trueLabel","falseLabel","trueBranch","falseBranch","exprText","caseLabel","caseBranch","m","matchLabel","tag","import_effect","sanitizeId","text","EFFECT_FAILURE_CALLEES","getErrorTypeLabel","node","raw","calleeToKind","callee","collectFailureNodes","results","op","childFailures","children","child","kind","errorType","label","truncateDisplayText","DEFAULT_LABEL_MAX","getStaticChildren","renderFailureNode","parentId","edgeLabel","lines","styledNodes","counter","nodeId","escaped","escapeMermaidLabel","edge","childEdgeLabel","renderCausesMermaid","ir","options","direction","failureNodes","rootId","programName","styleGroups","className","nodeIds","import_effect","nodeId","prefix","index","childLabel","node","t","s","truncateDisplayText","DEFAULT_LABEL_MAX","capitalize","collectConcurrencyNodes","nodes","result","visit","children","getStaticChildren","child","renderConcurrencyMermaid","ir","options","direction","collected","lines","styleLines","globalIdx","orderedIds","entry","pNode","pId","count","modeLabel","label","escapeMermaidLabel","joinId","i","cId","cLabel","branchLabel","edgeLabel","rNode","rId","winnerId","fNode","fId","op","sourceLabel","cpNode","cpId","primName","from","to","import_effect","collectSteps","nodes","steps","visit","node","callee","displayName","children","getStaticChildren","child","collectParticipants","seen","participants","visitStep","step","svc","renderParallelBlock","lines","indent","i","truncateDisplayText","DEFAULT_LABEL_MAX","rawLabel","label","renderTimelineMermaid","ir","p","method","info","retries","dur","import_effect","collectLayerNodes","nodes","result","node","layer","info","op","children","getStaticChildren","buildLayerDependencyGraph","ir","layers","edges","serviceToLayers","depLayerId","svc","list","req","sanitizeId","id","renderLayersMermaid","ir","options","direction","graph","buildLayerDependencyGraph","lines","allServices","layer","svc","req","mergedLayerIds","label","lifecycle","nodeId","edge","from","to","import_effect","collectResilienceNodes","nodes","result","node","children","getStaticChildren","buildRetryLabel","info","parts","operationLabel","source","renderRetryMermaid","ir","options","direction","collected","lines","index","prefix","opLabel","escapeMermaidLabel","retryNode","retryLabel","timeoutNode","duration","timeoutLabel","renderTestabilityMermaid","ir","options","direction","services","deps","layerNames","lines","easyIds","hardIds","i","sid","service","mockWord","import_effect","stepId","index","collectPipeSteps","node","chains","pipeNode","steps","initialSig","t","transformType","isEffectful","sig","children","getStaticChildren","child","collectGeneratorSteps","genNode","y","renderDataflowMermaid","ir","options","direction","allChains","lines","styleLines","globalIdx","baseIdx","i","step","id","label","escapeMermaidLabel","nextStep","nextId","nextLabel","edgeLabel","prevError","nextError","arrow","import_effect","inferBestDiagramType","ir","nodes","hasNodeType","stats","metrics","calculateComplexity","type","node","children","getStaticChildren","import_effect","IR_SCHEMA_VERSION","DEFAULT_OPTIONS","renderJSON","ir","options","opts","space","data","replacer","renderMultipleJSON","irs","_key","value","resolveThemeName","theme","renderInteractiveHTML","ir","options","title","resolvedTheme","mermaidCode","renderStaticMermaid","paths","generatePaths","complexity","calculateComplexity","mermaidWithDataFlow","mermaidWithErrorFlow","irJson","pathsJson","complexityJson","initialThemeJs","escapeHtml","s","import_effect","DEFAULT_DOC_OPTIONS","collectWorkflowSteps","nodes","steps","depth","node","step","describeNode","children","getStaticChildren","truncateDisplayText","DEFAULT_LABEL_MAX","p","renderDocumentation","ir","options","opts","sections","sig","indent","dep","errorFlow","analyzeErrorFlow","error","producers","complexity","calculateComplexity","dataFlow","buildDataFlowGraph","read","dup","renderStaticMermaid","renderMultiProgramDocs","irs","indent","depth","shortLabel","node","s","max","DEFAULT_LABEL_MAX","truncateDisplayText","wrapper","op","shouldSuppressExplainEffectNode","explainNode","state","pad","lines","label","child","canonicalizeServiceDisplayName","desc","y","childLines","firstChild","trimmed","retLines","firstRet","initLines","t","tLines","concDesc","tagInfo","maxPart","stratPart","parts","dur","c","caseLabel","src","provides","requires","ops","o","sinkPart","serviceStreamSource","sourceKind","scopeNote","cap","renderProgram","program","_ir","bodyLines","visibleChildren","childrenToRender","numberedLines","numberTopLevelSteps","header","footer","services","dep","svc","sections","step","line","renderExplanation","ir","renderMultipleExplanations","irs","SOURCE_ABBREVIATIONS","abbreviateSource","source","renderSummary","ir","name","kind","steps","services","errors","handlers","complexity","calculateComplexity","extractRow","renderMultipleSummaries","irs","rows","headers","widths","r","padRight","s","w","padLeft","headerLine","separatorLine","dataLines","row","DEFAULT_OPTIONS","defaultTestNameGenerator","generateTestMatrix","paths","options","opts","filteredPaths","p","testPaths","path","generateTestPath","conditions","extractConditions","summary","calculateSummary","testName","priority","determinePriority","setupConditions","c","verb","expectedSteps","s","name","parts","mainSteps","stepNames","camelToSpaces","conditionDescriptions","simplified","simplifyCondition","str","expression","conditionMap","condition","key","entry","affected","highPriorityPaths","minTestsForCoverage","formatTestMatrixMarkdown","matrix","lines","highPriority","mediumPriority","lowPriority","formatTestPathLines","truncatedExpr","trueCount","falseCount","i","formatTestMatrixAsCode","runner","programName","escapeString","step","formatTestChecklist","marker"]}