{"version":3,"sources":["../src/index.ts","../src/register-node-ts-morph.ts","../src/ts-morph-loader.ts","../src/analyze.ts","../src/static-analyzer.ts","../src/analysis-utils.ts","../src/analysis-patterns.ts","../src/type-extractor.ts","../src/types.ts","../src/core-analysis.ts","../src/path-utils.ts","../src/alias-resolution.ts","../src/effect-analysis.ts","../src/analysis-context.ts","../src/callback-summary.ts","../src/concurrency-fiber-analyzers.ts","../src/control-flow-analyzers.ts","../src/analysis-classifiers.ts","../src/error-handler-analyzer.ts","../src/layer-initializer-resolution.ts","../src/parallel-race-analyzers.ts","../src/resource-analyzer.ts","../src/retry-timeout-analyzers.ts","../src/service-type-heuristics.ts","../src/stream-channel-sink-analyzers.ts","../src/program-discovery.ts","../src/project-analyzer.ts","../src/audit-assessment.ts","../src/ir.ts","../src/fidelity-findings.ts","../src/project-architecture.ts","../src/project-corpus.ts","../src/service-registry.ts","../src/analysis-session.ts","../src/diagram-fidelity.ts","../src/runtime-trace.ts","../src/output/mermaid.ts","../src/data-flow.ts","../src/error-flow.ts","../src/walkthrough.ts"],"sourcesContent":["/** Canonical Effect v4 interface. */\n\nexport { analysis, type AnalysisSession, createAnalysisSession } from \"./analysis-session\"\n\nexport {\n  computeDiagramFidelity,\n  type DiagramFidelityIssue,\n  type DiagramFidelityIssueKind,\n  type DiagramFidelityReport,\n  formatDiagramFidelity\n} from \"./diagram-fidelity\"\n\nexport {\n  assessIRFidelity,\n  type FidelityDimension,\n  type FidelityFinding,\n  type FidelityFindingKind,\n  type IRFidelityAssessment\n} from \"./fidelity-findings\"\n\nexport {\n  type OpenTelemetryReadableSpan,\n  type RuntimeSpanStatus,\n  type RuntimeTrace,\n  type RuntimeTraceSpan,\n  type SpanTree,\n  type SpanTreeNode,\n  traceFromEffectSpans,\n  traceFromOpenTelemetry,\n  traceFromSpanTree\n} from \"./runtime-trace\"\n\nexport { renderMermaidWithRuntimeTrace, renderStaticMermaid, type RuntimeOverlayResult } from \"./output/mermaid\"\n\nexport {\n  advance,\n  advanceWhileLinear,\n  beginWalkthrough,\n  type ChoiceKind,\n  rewind,\n  type WalkChoice,\n  type WalkStep,\n  type Walkthrough\n} from \"./walkthrough\"\n\nexport type { AnalyzerOptions, SourceLocation, StaticEffectIR, StaticEffectProgram, StaticFlowNode } from \"./types\"\n","import { createRequire } from \"node:module\"\nimport type * as TsMorph from \"ts-morph\"\nimport { setTsMorphLoader } from \"./ts-morph-loader\"\n\n/** Current module location in both ESM and bundled CommonJS builds. */\nexport const nodeModuleLocation = typeof __filename === \"string\" ? __filename : import.meta.url\n\nsetTsMorphLoader(() => {\n  const require = createRequire(nodeModuleLocation)\n  return require(\"ts-morph\") as typeof TsMorph\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 * as TsMorph from \"ts-morph\"\nimport type { Project, SourceFile } from \"ts-morph\"\n\ntype TsMorphModule = typeof TsMorph\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 = getBuiltinModule(\"node:module\") ?? getBuiltinModule(\"module\")\n  const createRequire = 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 = 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 { analyzeEffectFile, analyzeEffectSource, resetIdCounter } from \"./static-analyzer\"\nimport { AnalysisError } from \"./types\"\nimport type { AnalyzerOptions, StaticEffectIR } from \"./types\"\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    ReadonlyArray<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: ReadonlyArray<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 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 { DEFAULT_OPTIONS, isJsOrJsxPath } from \"./analysis-utils\"\nimport { analyzeProgram } from \"./core-analysis\"\nimport { findEffectPrograms } from \"./program-discovery\"\nimport { createProject, createProjectFromSource, loadTsMorph } from \"./ts-morph-loader\"\nimport { AnalysisError } from \"./types\"\nimport type { AnalyzerOptions, StaticEffectIR } from \"./types\"\n\nexport { resetIdCounter } from \"./analysis-utils\"\n\nexport const analyzeEffectFile = (\n  filePath: string,\n  options?: AnalyzerOptions\n): Effect.Effect<ReadonlyArray<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) => 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<ReadonlyArray<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) => 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 { Option } from \"effect\"\nimport type {\n  CallExpression,\n  ClassDeclaration,\n  FunctionDeclaration,\n  GetAccessorDeclaration,\n  MethodDeclaration,\n  Node,\n  PropertyAssignment,\n  PropertyDeclaration,\n  VariableDeclaration\n} from \"ts-morph\"\nimport { BUILT_IN_TYPE_NAMES, KNOWN_EFFECT_NAMESPACES } from \"./analysis-patterns\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport { splitTopLevelUnion } from \"./type-extractor\"\nimport type {\n  AnalysisStats,\n  AnalyzerOptions,\n  ConcurrencyMode,\n  DependencyInfo,\n  JSDocTags,\n  SemanticRole,\n  SourceLocation,\n  StaticFlowNode\n} from \"./types\"\nimport { getStaticChildren } from \"./types\"\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 => 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/** True when a `concurrency` setting lets more than one fiber run at a time. */\nexport const isConcurrent = (concurrency: ConcurrencyMode | undefined): boolean =>\n  concurrency !== undefined && concurrency !== \"sequential\" && concurrency !== 0 && concurrency !== 1\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\n/**\n * A program's error channel. The checker's `E` for the program reflects its\n * handlers (catchTag, catch, mapError, ...). The per-node union is the\n * fallback when that type does not resolve.\n */\nexport function programErrorTypes(\n  programErrorType: string | undefined,\n  nodes: ReadonlyArray<StaticFlowNode>\n): Array<string> {\n  const err = programErrorType?.trim()\n  if (err === \"never\") return []\n  if (err && err !== \"unknown\" && err !== \"any\") return splitTopLevelUnion(err).sort()\n  return collectErrorTypes(nodes)\n}\n\nexport function collectErrorTypes(nodes: ReadonlyArray<StaticFlowNode>): Array<string> {\n  const set = new Set<string>()\n  const visit = (list: ReadonlyArray<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: ReadonlyArray<StaticFlowNode>): Array<DependencyInfo> {\n  const byName = new Map<string, DependencyInfo>()\n  const visit = (list: ReadonlyArray<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?: () => Array<{\n        getText: () => string\n        getComment?: () => string | Array<{ 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?: () => Array<{ 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: Array<{ name: string; description?: string }> = []\n  let returns: string | undefined\n  const throws: Array<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 = /^(?:\\{[^}]*\\}\\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:\n    | CallExpression\n    | FunctionDeclaration\n    | VariableDeclaration\n    | ClassDeclaration\n    | PropertyDeclaration\n    | MethodDeclaration\n    | GetAccessorDeclaration\n  readonly type:\n    | \"generator\"\n    | \"direct\"\n    | \"pipe\"\n    | \"run\"\n    | \"workflow-execute\"\n    | \"class\"\n    | \"classProperty\"\n    | \"classMethod\"\n    | \"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\nconst ASCII_REPLACEMENTS: ReadonlyArray<readonly [RegExp, string]> = [\n  [/[\\u2014\\u2013\\u2012\\u2212]/g, \"-\"],\n  [/\\u2192/g, \"->\"],\n  [/\\u2190/g, \"<-\"],\n  [/\\u21d2/g, \"=>\"],\n  [/\\u2026/g, \"...\"],\n  [/\\u26a0\\ufe0f?/g, \"!\"],\n  [/[\\u2018\\u2019]/g, \"'\"],\n  [/[\\u201c\\u201d]/g, \"\\\"\"],\n  [/\\u2264/g, \"<=\"],\n  [/\\u2265/g, \">=\"],\n  [/[\\u2022\\u00b7]/g, \"*\"]\n]\n\n/** Replace the typographic symbols renderers emit (dashes, arrows, ellipsis) with ASCII. */\nexport const toAsciiText = (text: string): string =>\n  ASCII_REPLACEMENTS.reduce((acc, [pattern, ascii]) => acc.replace(pattern, ascii), text)\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 = node.wrappedCall ?? 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: Array<string> = [\"Stream\", ...ops]\n      if (node.sink && ops.at(-1) !== 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: ReadonlyArray<StaticFlowNode>): number => {\n  let count = 0\n  const walk = (list: ReadonlyArray<StaticFlowNode>) => {\n    for (const node of list) {\n      if (node.type !== \"unknown\") count++\n      const children = Option.getOrElse(getStaticChildren(node), () => [] as ReadonlyArray<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 * Pattern maps and semantic helpers for Effect API detection and classification.\n */\n\nimport type {\n  ArrowFunction,\n  AwaitExpression,\n  Block,\n  CallExpression,\n  ConditionalExpression,\n  FunctionExpression,\n  GetAccessorDeclaration,\n  MethodDeclaration,\n  Node,\n  ObjectLiteralExpression,\n  PrefixUnaryExpression,\n  PropertyAccessExpression,\n  PropertyAssignment,\n  SetAccessorDeclaration\n} from \"ts-morph\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type { StaticCauseNode, StaticExitNode, StaticMatchNode, StaticScheduleNode, StaticTransformNode } 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([\n  \"flatMap\",\n  \"andThen\",\n  \"tapBoth\",\n  \"tapError\",\n  \"tapErrorTag\",\n  \"tapErrorCause\",\n  \"tapDefect\",\n  \"zipWith\",\n  \"zipLeft\",\n  \"zipRight\",\n  \"zip\",\n  \"ap\",\n  \"flatten\"\n])\n/** Taps run their callback for its effects; the analyzer follows the callback. */\nexport const TAP_TRANSFORMS = new Set<StaticTransformNode[\"transformType\"]>([\n  \"tap\",\n  \"tapBoth\",\n  \"tapError\",\n  \"tapErrorTag\",\n  \"tapErrorCause\",\n  \"tapDefect\"\n])\n/** Taps that run only on failure: side branches off the error rail. */\nexport const ERROR_TAP_TRANSFORMS = new Set<StaticTransformNode[\"transformType\"]>([\n  \"tapError\",\n  \"tapErrorTag\",\n  \"tapErrorCause\",\n  \"tapDefect\"\n])\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 => 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 => 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\",\n  \"ReadonlyArray\",\n  \"String\",\n  \"Number\",\n  \"Boolean\",\n  \"Object\",\n  \"Function\",\n  \"Promise\",\n  \"Math\",\n  \"Date\",\n  \"RegExp\",\n  \"Error\",\n  \"Map\",\n  \"Set\",\n  \"WeakMap\",\n  \"WeakSet\",\n  \"Symbol\",\n  \"BigInt\",\n  \"JSON\",\n  \"Console\",\n  \"process\",\n  \"Buffer\",\n  \"EventEmitter\",\n  \"Window\",\n  \"Document\",\n  \"AbortController\"\n])\n\nexport const KNOWN_EFFECT_NAMESPACES = new Set([\n  // Core runtime — these are never services themselves\n  \"Effect\",\n  \"Layer\",\n  \"Stream\",\n  \"Queue\",\n  \"PubSub\",\n  \"Deferred\",\n  \"Semaphore\",\n  \"Mailbox\",\n  \"SubscriptionRef\",\n  \"Scope\",\n  \"Fiber\",\n  \"Runtime\",\n  \"ManagedRuntime\",\n  \"Cause\",\n  \"Exit\",\n  // Data types\n  \"Data\",\n  \"Option\",\n  \"Either\",\n  \"Chunk\",\n  \"HashMap\",\n  \"HashSet\",\n  \"List\",\n  \"SortedMap\",\n  \"SortedSet\",\n  // Matching, config, schema (S is a common alias for Schema)\n  \"Match\",\n  \"Config\",\n  \"Schema\",\n  \"Schedule\",\n  \"S\",\n  // Observability\n  \"Metric\",\n  \"Tracer\",\n  \"Logger\",\n  // Fiber management\n  \"FiberRef\",\n  \"FiberHandle\",\n  \"FiberSet\",\n  \"FiberMap\",\n  // Caching\n  \"Cache\",\n  \"ScopedCache\",\n  \"RateLimiter\",\n  \"Supervisor\",\n  // Refs and state\n  \"Ref\",\n  \"SynchronizedRef\",\n  \"Context\",\n  // Pure utilities — never services\n  \"Random\",\n  \"Clock\",\n  \"Duration\",\n  \"DateTime\",\n  \"Predicate\",\n  \"Tuple\",\n  \"Struct\",\n  \"Record\",\n  \"Encoding\",\n  \"Order\",\n  \"Equivalence\",\n  \"Brand\",\n  \"Inspectable\",\n  \"Equal\",\n  \"Hash\",\n  \"Differ\",\n  \"Types\",\n  \"Unify\",\n  \"Pipeable\",\n  // Streams / channels / sinks\n  \"Sink\",\n  \"Channel\",\n  \"GroupBy\",\n  \"Take\",\n  // STM\n  \"STM\",\n  \"TRef\",\n  \"TMap\",\n  \"TSet\",\n  \"TArray\",\n  \"TQueue\",\n  \"TPubSub\",\n  \"TDeferred\",\n  \"TSemaphore\",\n  // HTTP request/response builders — utility namespaces, not services\n  \"HttpClientRequest\",\n  \"HttpClientResponse\",\n  \"HttpClientError\",\n  \"HttpServerRequest\",\n  \"HttpServerResponse\",\n  \"HttpRouter\",\n  \"HttpApiEndpoint\",\n  \"HttpApiGroup\",\n  \"HttpApi\",\n  \"HttpApiBuilder\",\n  \"HttpApiSecurity\",\n  \"HttpMiddleware\",\n  \"FetchHttpClient\",\n  \"NodeHttpClient\",\n  \"BunHttpClient\",\n  // Command (the Effect platform process command, not a service)\n  \"Command\",\n  // SQL utilities\n  \"SqlSchema\",\n  \"SqlResolver\",\n  \"SqlMigrator\",\n  // RPC utilities\n  \"Rpc\",\n  \"RpcRouter\",\n  \"RpcGroup\",\n  \"RpcApi\",\n  \"RpcSerialization\",\n  // Cluster / distributed\n  \"Entity\",\n  \"ClusterSchema\",\n  \"MessageState\",\n  \"Sharding\",\n  // Printer / docs\n  \"Printer\",\n  \"Doc\",\n  \"DocTree\",\n  \"PageWidth\",\n  \"Optimize\",\n  // AI\n  \"AiToolkit\",\n  \"Completions\",\n  \"AiInput\",\n  \"AiResponse\",\n  // OpenTelemetry\n  \"NodeSdk\",\n  \"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.\")) {\n    return \"runtime\"\n  }\n  if (callee.startsWith(\"Scope.\")) return \"scope\"\n  if (callee.startsWith(\"ScopedRef.\") || callee.startsWith(\"RcRef.\") || callee.startsWith(\"RcMap.\")) {\n    return \"resource-ref\"\n  }\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 = 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: 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: 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 = 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            | MethodDeclaration\n            | GetAccessorDeclaration\n            | 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\",\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  \"Cause\",\n  \"Exit\",\n  \"Data\",\n  \"Option\",\n  \"Either\",\n  \"Chunk\",\n  \"HashMap\",\n  \"HashSet\",\n  \"Match\",\n  \"Config\",\n  \"Schema\",\n  \"Cache\",\n  \"ScopedCache\",\n  \"Metric\",\n  \"Logger\",\n  \"Tracer\",\n  \"Context\",\n  \"Brand\",\n  \"Encoding\",\n  \"Predicate\",\n  \"DateTime\",\n  \"Cron\",\n  \"BigDecimal\",\n  \"Graph\",\n  \"HashRing\",\n  \"Redacted\",\n  \"GlobalValue\",\n  \"NodeRuntime\",\n  \"BunRuntime\",\n  \"DenoRuntime\",\n  \"Channel\",\n  \"Sink\"\n])\n\nexport const KNOWN_INTERNAL_MODULES = new Set([\n  \"core\",\n  \"core-effect\",\n  \"core-stream\",\n  \"fiberRuntime\",\n  \"effectable\",\n  \"channel\",\n  \"sink\",\n  \"layer\",\n  \"schedule\",\n  \"mailbox\",\n  \"pubsub\"\n])\n\n// =============================================================================\n// Numeric literal and Context type parsing\n// =============================================================================\n\nexport function parseServiceIdsFromContextType(requiredType: string): Array<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 * 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 { CallExpression, Node, PropertyAccessExpression, Type, TypeChecker, VariableDeclaration } from \"ts-morph\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  CauseTypeSignature,\n  EffectTypeSignature,\n  LayerTypeSignature,\n  ScheduleTypeSignature,\n  ServiceRequirement,\n  SourceLocation,\n  StreamTypeSignature\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 * Read `_tag` string literals off an error type (including unions).\n * `Data.TaggedError(\"NOT_FOUND\")` exposes `_tag: \"NOT_FOUND\"`.\n */\nexport function taggedErrorTagsFromType(type: Type | undefined): ReadonlyArray<string> {\n  if (!type) return []\n  if (type.isUnion()) {\n    return [...new Set(type.getUnionTypes().flatMap((part) => taggedErrorTagsFromType(part)))]\n  }\n\n  const apparent = tagsFromTagProperty(type.getApparentType())\n  if (apparent.length > 0) return apparent\n  const own = tagsFromTagProperty(type)\n  if (own.length > 0) return own\n\n  const symbol = type.getSymbol() ?? type.getAliasSymbol()\n  if (!symbol) return []\n  const tags: Array<string> = []\n  for (const declaration of symbol.getDeclarations()) {\n    const tagged = /TaggedError\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/.exec(declaration.getText())\n    if (tagged?.[1]) tags.push(tagged[1])\n  }\n  return tags\n}\n\nfunction tagsFromTagProperty(type: Type): ReadonlyArray<string> {\n  const tagProperty = type.getProperty(\"_tag\")\n  if (!tagProperty) return []\n  const tags: Array<string> = []\n  for (const declaration of tagProperty.getDeclarations()) {\n    let tagType\n    try {\n      tagType = declaration.getType()\n    } catch {\n      continue\n    }\n    if (tagType.isLiteral()) {\n      const value = tagType.getLiteralValue()\n      if (typeof value === \"string\") tags.push(value)\n      continue\n    }\n    const quoted = /^(?:[\"'])([^\"']+)(?:[\"'])$/.exec(tagType.getText())\n    if (quoted?.[1]) tags.push(quoted[1])\n  }\n  return tags\n}\n\nconst withErrorTags = (\n  signature: EffectTypeSignature,\n  errorType: Type | undefined,\n  node?: Node\n): EffectTypeSignature => {\n  const fromType = taggedErrorTagsFromType(errorType)\n  const fromSource = node ? taggedErrorTagsFromSource(node, signature.errorType) : []\n  const errorTags = fromType.length > 0 ? fromType : fromSource\n  return errorTags.length > 0 ? { ...signature, errorTags } : signature\n}\n\nfunction taggedErrorTagsFromSource(node: Node, errorTypeName: string): ReadonlyArray<string> {\n  const sourceFile = node.getSourceFile()\n  const tags: Array<string> = []\n  for (const name of errorTypeName.split(\"|\").map((part) => part.trim())) {\n    const cls = sourceFile.getClass(name)\n    if (!cls) continue\n    const text = cls.getText()\n    const tagged = /TaggedError\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/.exec(text)\n    if (tagged?.[1]) {\n      tags.push(tagged[1])\n      continue\n    }\n    const field = /(?:readonly\\s+)?_tag\\s*=\\s*['\"]([^'\"]+)['\"]/.exec(text)\n    if (field?.[1]) tags.push(field[1])\n  }\n  return tags\n}\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 withErrorTags(\n          {\n            successType: typeToString(aType),\n            errorType: resolved.errorType,\n            requirementsType: typeToString(rType),\n            isInferred: true,\n            typeConfidence: \"inferred\",\n            rawTypeString: nodeType.getText()\n          },\n          eType,\n          node\n        )\n      }\n    }\n\n    return withErrorTags(\n      {\n        successType: typeToString(aType),\n        errorType: errorTypeStr,\n        requirementsType: typeToString(rType),\n        isInferred: true,\n        typeConfidence: \"declared\",\n        rawTypeString: nodeType.getText()\n      },\n      eType,\n      node\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 withErrorTags(fromText, undefined, node)\n  }\n\n  // Fallback: resolve the callee function's return type annotation\n  const fromCallee = tryExtractFromCalleeReturnType(node)\n  if (fromCallee) return withErrorTags(fromCallee, undefined, node)\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 withErrorTags(\n          {\n            successType: typeToString(aType),\n            errorType: typeToString(eType),\n            requirementsType: typeToString(rType),\n            isInferred: true,\n            typeConfidence: \"inferred\",\n            rawTypeString: returnType.getText()\n          },\n          eType,\n          node\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 withErrorTags(\n              {\n                successType: typeToString(aType),\n                errorType: typeToString(eType),\n                requirementsType: typeToString(rType),\n                isInferred: true,\n                typeConfidence: \"inferred\",\n                rawTypeString: retType.getText()\n              },\n              eType,\n              node\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): Array<ServiceRequirement> => {\n  const requirements: Array<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: ReadonlyArray<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): Array<{ id: string; typeName: string }> => {\n  const services: Array<{ 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: Array<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): Array<string> {\n  const parts: Array<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 * 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 { type 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: ReadonlyArray<{ readonly name: string; readonly description?: string }>\n  readonly returns?: string | undefined\n  readonly throws: ReadonlyArray<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?: ReadonlyArray<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?: Array<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?: ReadonlyArray<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?:\n    | \"sync\"\n    | \"promise\"\n    | \"async\"\n    | \"callback\"\n    | \"never\"\n    | \"void\"\n    | \"fromNullable\"\n    | \"fn\"\n    | \"fnUntraced\"\n    | 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  /** Call lifted by Effect.tryPromise/promise/try/sync, e.g. `wallet.getBalance` */\n  readonly wrappedCall?: string | undefined\n  /** Field a lifted thunk assigns when its body is one assignment, e.g. `ledger.balances` */\n  readonly wrappedAssignment?: 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: Array<{\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: ReadonlyArray<StaticFlowNode>\n  /** Type flow through the pipe chain (A, E, R at each step) */\n  readonly typeFlow?: ReadonlyArray<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: ReadonlyArray<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?: ReadonlyArray<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: ReadonlyArray<StaticFlowNode>\n  /** The callee */\n  readonly callee: string\n  /** Labels for each race competitor */\n  readonly raceLabels?: ReadonlyArray<string> | undefined\n}\n\n/**\n * Error handling (catch, catchTag, orElse, etc.).\n */\nexport interface StaticErrorHandlerNode extends StaticBaseNode {\n  readonly type: \"error-handler\"\n  /** Type of handler: catch, catchTag, orElse, etc. */\n  readonly handlerType:\n    | \"catch\"\n    | \"catchTag\"\n    | \"catchCause\"\n    | \"catchIf\"\n    | \"catchSome\"\n    | \"catchSomeCause\"\n    | \"catchSomeDefect\"\n    | \"catchDefect\"\n    | \"catchTags\"\n    // Effect 4 catch APIs\n    | \"catchReason\"\n    | \"catchReasons\"\n    | \"catchFilter\"\n    | \"catchCauseIf\"\n    | \"catchCauseFilter\"\n    | \"catchNoSuchElement\"\n    | \"catchEager\"\n    | \"orElse\"\n    | \"orElseFail\"\n    | \"orElseSucceed\"\n    | \"orDie\"\n    | \"orDieWith\"\n    | \"flip\"\n    | \"mapError\"\n    | \"mapErrorCause\"\n    | \"mapBoth\"\n    | \"sandbox\"\n    | \"unsandbox\"\n    | \"parallelErrors\"\n    | \"filterOrDie\"\n    | \"filterOrDieMessage\"\n    | \"filterOrElse\"\n    | \"filterOrFail\"\n    | \"match\"\n    | \"matchCause\"\n    | \"matchEffect\"\n    | \"matchCauseEffect\"\n    | \"firstSuccessOf\"\n    | \"ignore\"\n    | \"ignoreLogged\"\n    | \"eventually\"\n  /** The effect being handled */\n  readonly source: StaticFlowNode\n  /** The handler (recovery) effect */\n  readonly handler?: StaticFlowNode | undefined\n  /** For catchTag, the error tag being caught */\n  readonly errorTag?: string | undefined\n  /** For catchTags (object form), the error tags being caught */\n  readonly errorTags?: ReadonlyArray<string> | undefined\n  /** For catchTags (object form), each tag's own recovery effect */\n  readonly tagHandlers?: ReadonlyArray<{ readonly tag: string; readonly handler: StaticFlowNode }> | 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: ReadonlyArray<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  /** The combinator, e.g. `acquireRelease`, `ensuring`, `onError`. */\n  readonly resourceOperation?: string | undefined\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: ReadonlyArray<StaticFlowNode>\n  /** Branch when condition is false (if present) */\n  readonly onFalse?: ReadonlyArray<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: ReadonlyArray<string>\n  /** Whether this is the default case */\n  readonly isDefault: boolean\n  /** Body nodes for this case */\n  readonly body: ReadonlyArray<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: ReadonlyArray<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: ReadonlyArray<StaticFlowNode>\n  /** Catch clause variable name */\n  readonly catchVariable?: string | undefined\n  /** Body of the catch block */\n  readonly catchBody?: ReadonlyArray<StaticFlowNode> | undefined\n  /** Body of the finally block */\n  readonly finallyBody?: ReadonlyArray<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?: ReadonlyArray<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?: ReadonlyArray<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?: ReadonlyArray<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  /**\n   * The analyzed callback of a tap (`tap`, `tapError`, …). A tap runs its\n   * callback for its effects, so those effects are steps in their own right.\n   */\n  readonly callback?: StaticFlowNode | 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?: ReadonlyArray<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?: ReadonlyArray<StaticFlowNode> | undefined\n  /** Iteration variable name (for for-of/for-in loops) */\n  readonly iterVariable?: string | undefined\n  /** `{ concurrency }` option on Effect.forEach & co; absent means sequential */\n  readonly concurrency?: ConcurrencyMode | 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: ReadonlyArray<StaticFlowNode>\n  /** Whether this is a merged layer */\n  readonly isMerged: boolean\n  /** Service tags this layer provides (GAP 2) */\n  readonly provides?: ReadonlyArray<string> | undefined\n  /** Service tags this layer requires (GAP 2) */\n  readonly requires?: ReadonlyArray<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?: ReadonlyArray<StaticFlowNode> | undefined\n  /** Other streams joined in by a merge-like operator (Stream.merge(a, b) → b) */\n  readonly branches?: ReadonlyArray<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: ReadonlyArray<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: ReadonlyArray<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: ReadonlyArray<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:\n    | \"generator\"\n    | \"direct\"\n    | \"pipe\"\n    | \"run\"\n    | \"workflow-execute\"\n    | \"class\"\n    | \"classProperty\"\n    | \"classMethod\"\n    | \"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: ReadonlyArray<StaticFlowNode>\n  /** Dependencies (services required) */\n  readonly dependencies: ReadonlyArray<DependencyInfo>\n  /** Error types */\n  readonly errorTypes: ReadonlyArray<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?: Array<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  /** TaggedError `_tag` literals for E, when the checker can see them */\n  readonly errorTags?: ReadonlyArray<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: ReadonlyArray<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: ReadonlyArray<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: ReadonlyArray<string>\n  /** Validation paths */\n  readonly validationPaths: ReadonlyArray<SchemaValidationPath>\n}\n\n/**\n * Complete Schema analysis result\n */\nexport interface SchemaAnalysis {\n  /** All Schema.decode/encode operations found */\n  readonly operations: ReadonlyArray<SchemaOperation>\n  /** Schema compositions detected */\n  readonly compositions: ReadonlyArray<SchemaComposition>\n  /** Missing error handlers for Schema operations */\n  readonly unhandledOperations: ReadonlyArray<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: ReadonlyArray<string>\n  /** Property names (non-callable members) from the service interface type. */\n  readonly properties: ReadonlyArray<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: ReadonlyArray<AnalysisWarning>\n  readonly stats: AnalysisStats\n  /** Service interface shapes (methods/properties) from Context.Tag/Effect.Service in this file. */\n  readonly serviceDefinitions?: ReadonlyArray<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: ReadonlyArray<string>\n  readonly tips: ReadonlyArray<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: ReadonlyArray<DiagramTopOffenderEntry>\n  readonly mostAnonymousNodes: ReadonlyArray<DiagramTopOffenderEntry>\n  readonly mostUnknownNodes: ReadonlyArray<DiagramTopOffenderEntry>\n  readonly highestLogRatio: ReadonlyArray<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: ReadonlyArray<PathStepRef>\n  readonly conditions: ReadonlyArray<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: ReadonlyArray<TestPath>\n  readonly conditions: ReadonlyArray<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: ReadonlyArray<string>\n  readonly expectedSteps: ReadonlyArray<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: ReadonlyArray<string>\n  readonly affectedPathsWhenFalse: ReadonlyArray<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): ReadonlyArray<StreamOperatorInfo> => {\n  const ops: Array<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<ReadonlyArray<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.source,\n        ...(node.handler ? [node.handler] : []),\n        ...(node.tagHandlers ?? []).map((t) => t.handler)\n      ])\n    case \"retry\": {\n      const retryNode = node\n      const list = ([retryNode.source, retryNode.scheduleNode] as Array<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.use, node.release]\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      const list = [node.source, node.callback].filter((n): n is StaticFlowNode => n !== undefined)\n      return list.length > 0 ? Option.some(list) : Option.none()\n    }\n    case \"layer\":\n      return Option.some([...node.operations])\n    case \"stream\":\n      return Option.some([node.source, ...node.pipeline.flatMap((op) => op.branches ?? [])])\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: Array<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: ReadonlyArray<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: ReadonlyArray<LayerImplementation>\n  /** Programs that consume (yield*) this service */\n  readonly consumers: ReadonlyArray<ServiceConsumerRef>\n  /** Services this service's layers depend on (transitive requirements) */\n  readonly dependencies: ReadonlyArray<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: ReadonlyArray<string>\n  /** Topological order of services (leaves first) */\n  readonly topologicalOrder: ReadonlyArray<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: ReadonlyArray<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: ReadonlyArray<ShowcaseStepDetail>\n}\n","/**\n * Core program analysis: analyzeProgram, analyzeProgramNode,\n * analyzeGeneratorFunction, analyzeRunEntrypointExpression.\n */\n\nimport { Clock, Effect, Option } from \"effect\"\nimport type {\n  ArrayLiteralExpression,\n  ArrowFunction,\n  BinaryExpression,\n  Block,\n  CallExpression,\n  CaseClause,\n  ClassDeclaration,\n  ConditionalExpression,\n  DoStatement,\n  ExpressionStatement,\n  ForInStatement,\n  ForOfStatement,\n  ForStatement,\n  FunctionDeclaration,\n  FunctionExpression,\n  GetAccessorDeclaration,\n  Identifier,\n  IfStatement,\n  LabeledStatement,\n  MethodDeclaration,\n  Node,\n  NumericLiteral,\n  ObjectLiteralExpression,\n  PropertyAccessExpression,\n  PropertyAssignment,\n  PropertyDeclaration,\n  ReturnStatement,\n  SourceFile,\n  StringLiteral,\n  SwitchStatement,\n  ThrowStatement,\n  TryStatement,\n  VariableDeclaration,\n  VariableStatement,\n  WhileStatement,\n  YieldExpression\n} from \"ts-morph\"\nimport { getAliasesForFile, isEffectLikeCallExpression } from \"./alias-resolution\"\nimport { isServiceTagCallee } from \"./analysis-patterns\"\nimport type { EffectProgram } from \"./analysis-utils\"\nimport {\n  collectDependencies,\n  computeDisplayName,\n  computeSemanticRole,\n  createEmptyStats,\n  extractJSDocDescription,\n  extractJSDocTags,\n  extractLocation,\n  extractYieldVariableName,\n  generateId,\n  getJSDocFromParentVariable,\n  programErrorTypes,\n  unwrapExpression\n} from \"./analysis-utils\"\nimport { analyzeEffectCall, analyzeEffectExpression, analyzePipeChain } from \"./effect-analysis\"\nimport { extractServiceDefinitionsFromFile, getWorkflowBodyNodeForRunCall } from \"./program-discovery\"\nimport { resolveRetryPolicy } from \"./retry-timeout-analyzers\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport { extractEffectTypeSignature, extractServiceRequirements } from \"./type-extractor\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  StaticDecisionNode,\n  StaticEffectIR,\n  StaticEffectNode,\n  StaticEffectProgram,\n  StaticFlowNode,\n  StaticGeneratorNode,\n  StaticLayerNode,\n  StaticLoopNode,\n  StaticOpaqueNode,\n  StaticParallelNode,\n  StaticRaceNode,\n  StaticRetryNode,\n  StaticSwitchCase,\n  StaticSwitchNode,\n  StaticTerminalNode,\n  StaticTryCatchNode\n} from \"./types\"\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: Array<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    // `Effect.gen(...).pipe(catch, provide, ...)` is analyzed as one program\n    // (see the 'generator' case), so its type is the pipe's, not the gen's.\n    const typedNode = (program.type === \"generator\" ? findOuterPipeOnGen(program.node as CallExpression) : undefined) ??\n      program.node\n    const typeSignature = extractEffectTypeSignature(typedNode, typeChecker)\n    const requiredServices = extractServiceRequirements(typedNode, 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: programErrorTypes(typeSignature?.errorType, 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: Array<AnalysisWarning>,\n  stats: AnalysisStats\n): Effect.Effect<ReadonlyArray<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 = 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\")) {\n            callee = \"Data.TaggedError\"\n            break\n          }\n          if (clauseText.includes(\"Data.TaggedClass\")) {\n            callee = \"Data.TaggedClass\"\n            break\n          }\n          if (clauseText.includes(\"Data.Error\")) {\n            callee = \"Data.Error\"\n            break\n          }\n          if (clauseText.includes(\"Schema.TaggedRequest\")) {\n            callee = \"Schema.TaggedRequest\"\n            break\n          }\n          if (clauseText.includes(\"Schema.TaggedError\")) {\n            callee = \"Schema.TaggedError\"\n            break\n          }\n          if (clauseText.includes(\"Schema.TaggedClass\")) {\n            callee = \"Schema.TaggedClass\"\n            break\n          }\n          if (clauseText.includes(\"Schema.Class\")) {\n            callee = \"Schema.Class\"\n            break\n          }\n          if (clauseText.includes(\"Context.Tag\")) {\n            callee = \"Context.Tag\"\n            break\n          }\n          if (clauseText.includes(\"Context.Service\")) {\n            callee = \"Context.Service\"\n            break\n          }\n          if (clauseText.includes(\"Context.Reference\")) {\n            callee = \"Context.Reference\"\n            break\n          }\n          if (clauseText.includes(\"Effect.Service\")) {\n            callee = \"Effect.Service\"\n            break\n          }\n        }\n        const description = callee.includes(\"Error\") ?\n          \"error-type\" :\n          callee.includes(\"Schema\") ?\n          \"schema\" :\n          callee === \"Context.Service\" || callee === \"Context.Tag\" || callee === \"Context.Reference\" ||\n            callee === \"Effect.Service\" ?\n          \"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,\n            sourceFile,\n            filePath,\n            opts,\n            warnings,\n            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: Array<StaticFlowNode> = []\n        for (const ret of returnStatements) {\n          const expr = ret.getExpression()\n          if (expr) {\n            const result = yield* analyzeEffectExpression(\n              expr,\n              sourceFile,\n              filePath,\n              opts,\n              warnings,\n              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: Array<StaticFlowNode> = []\n        for (const ret of returnStatements) {\n          const expr = ret.getExpression()\n          if (expr) {\n            const result = yield* analyzeEffectExpression(\n              expr,\n              sourceFile,\n              filePath,\n              opts,\n              warnings,\n              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 a `return value` of the enclosing\n * function? A bare `return` carries nothing to draw, so it does not count.\n */\nfunction containsEarlyReturn(node: Node): boolean {\n  const { Node: TsNode } = loadTsMorph()\n  let found = false\n  node.forEachChild((child) => {\n    if (found || isFunctionBoundary(child)) return\n    found = (TsNode.isReturnStatement(child) && child.getExpression() !== undefined) || containsEarlyReturn(child)\n  })\n  return found\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: ReadonlyArray<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): Array<Node> {\n  const { SyntaxKind } = loadTsMorph()\n  const results: Array<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): Array<CallExpression> {\n  const { SyntaxKind } = loadTsMorph()\n  const calls: Array<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\",\n  \"Step.decide\",\n  \"Step.branch\",\n  \"Step.all\",\n  \"Step.forEach\",\n  \"Step.retry\",\n  \"Step.race\",\n  \"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): Array<StaticSwitchCase> {\n  if (!casesObj) return []\n  const { SyntaxKind } = loadTsMorph()\n  if (casesObj.getKind() !== SyntaxKind.ObjectLiteralExpression) return []\n  const cases: Array<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: Array<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: Array<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: Array<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: ${\n          yieldNode.getText().slice(0, 60)\n        }`,\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: Block,\n  ctx: WalkerContext\n): Effect.Effect<StaticGeneratorNode[\"yields\"], AnalysisError> {\n  return Effect.gen(function*() {\n    const stmts = block.getStatements()\n    const result: Array<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: Array<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) && !containsEarlyReturn(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: Array<StaticSwitchCase> = []\n        let hasFallthrough = false\n        let hasDefault = false\n\n        // Build fallthrough groups\n        let currentLabels: Array<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: Array<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 = 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: Array<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 = 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 = 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 = 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 = 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: Array<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) {\n            // A plain value returned from inside a branch is still an early exit.\n            if (isFunctionBoundary(retStmt.getParentOrThrow().getParentOrThrow())) return []\n            const valueText = expr.getText().replace(/\\s+/g, \" \")\n            const earlyReturn: StaticTerminalNode = {\n              id: generateId(),\n              type: \"terminal\",\n              terminalKind: \"return\",\n              displayName: `return ${valueText.length > 40 ? valueText.slice(0, 40) + \"...\" : valueText}`\n            }\n            ctx.stats.terminalCount++\n            return [{ effect: earlyReturn }]\n          }\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: Array<AnalysisWarning>,\n  stats: AnalysisStats\n): Effect.Effect<ReadonlyArray<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          | ArrowFunction\n          | 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: ReadonlyArray<StaticFlowNode>,\n  pipeCall: CallExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<AnalysisWarning>,\n  stats: AnalysisStats\n): Effect.Effect<ReadonlyArray<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: ReadonlyArray<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: ReadonlyArray<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 { schedule, scheduleInfo, scheduleExpr } = resolveRetryPolicy(argArgs[0])\n        const scheduleNode = scheduleExpr\n          ? yield* analyzeEffectExpression(\n            scheduleExpr,\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          ...(scheduleInfo ? { scheduleInfo } : {}),\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: Array<AnalysisWarning>,\n  stats: AnalysisStats\n): Effect.Effect<Option.Option<ReadonlyArray<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 = 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 * 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 => 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: Array<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: ReadonlyArray<string>): string =>\n  normalizePath(parts.filter((part) => part.length > 0).join(PATH_SEPARATOR))\n\nexport const resolvePath = (...parts: ReadonlyArray<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 { CallExpression, PropertyAccessExpression, SourceFile } from \"ts-morph\"\nimport {\n  API_PREFIXES,\n  EFFECT_NAMESPACE_NAMES,\n  isEffectPackageSpecifier,\n  KNOWN_INTERNAL_MODULES\n} from \"./analysis-patterns\"\nimport { dirnamePath, hasPathPrefix, joinPath, PATH_SEPARATOR, resolvePath } from \"./path-utils\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\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 = 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: Array<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: Array<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 = 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: Array<{ 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(),\n              sourceFile.getFilePath(),\n              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: 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 expression analysis: pipe chains, effect calls, and domain-specific analyzers.\n */\n\nimport { Effect, Option } from \"effect\"\nimport type {\n  ArrayLiteralExpression,\n  ArrowFunction,\n  Block,\n  CallExpression,\n  ConditionalExpression,\n  ExpressionStatement,\n  FunctionExpression,\n  Identifier,\n  NewExpression,\n  Node,\n  ObjectLiteralExpression,\n  PropertyAccessExpression,\n  PropertyAssignment,\n  ReturnStatement,\n  SourceFile,\n  TaggedTemplateExpression\n} from \"ts-morph\"\nimport {\n  getAliasesForFile,\n  isEffectCallee,\n  isEffectLikeCallExpression,\n  normalizeEffectCallee\n} from \"./alias-resolution\"\nimport { bindAnalysisContext, createAnalysisContext } from \"./analysis-context\"\nimport {\n  BUILT_IN_TYPE_NAMES,\n  COLLECTION_PATTERNS,\n  CONDITIONAL_PATTERNS,\n  ERROR_HANDLER_PATTERNS,\n  FIBER_PATTERNS,\n  getSemanticDescriptionWithAliases,\n  INTERRUPTION_PATTERNS,\n  isCauseCall,\n  isExitCall,\n  isMatchCall,\n  isScheduleCall,\n  isTransformCall,\n  KNOWN_EFFECT_NAMESPACES,\n  parseServiceIdsFromContextType\n} from \"./analysis-patterns\"\nimport {\n  computeDisplayName,\n  computeSemanticRole,\n  extractJSDocDescription,\n  extractJSDocTags,\n  extractLocation,\n  generateId,\n  unwrapExpression\n} from \"./analysis-utils\"\nimport { buildCallbackSummaryNodes, summarizeNamedCallbackHandlers } from \"./callback-summary\"\nimport {\n  analyzeConcurrencyPrimitiveCall,\n  analyzeFiberCall as _analyzeFiberCall,\n  analyzeInterruptionCall as _analyzeInterruptionCall\n} from \"./concurrency-fiber-analyzers\"\nimport {\n  analyzeCauseCall as _analyzeCauseCall,\n  analyzeConditionalCall as _analyzeConditionalCall,\n  analyzeExitCall,\n  analyzeLoopCall as _analyzeLoopCall,\n  analyzeMatchCall,\n  analyzeTransformCall as _analyzeTransformCall\n} from \"./control-flow-analyzers\"\nimport { analyzeErrorHandlerCall as _analyzeErrorHandlerCall, classifyErrorHandlerName } from \"./error-handler-analyzer\"\nimport { resolveIdentifierToLayerInitializer } from \"./layer-initializer-resolution\"\nimport {\n  analyzeParallelCall as _analyzeParallelCall,\n  analyzeRaceCall as _analyzeRaceCall\n} from \"./parallel-race-analyzers\"\nimport { analyzeResourceCall as _analyzeResourceCall } from \"./resource-analyzer\"\nimport {\n  analyzeRetryCall as _analyzeRetryCall,\n  analyzeScheduleCall,\n  analyzeTimeoutCall as _analyzeTimeoutCall\n} from \"./retry-timeout-analyzers\"\nimport {\n  classifyUseCallbackKind,\n  isEffectRuntimePrimitive,\n  isLikelyServiceStreamProperty,\n  tryResolveServicePropertyAccess\n} from \"./service-type-heuristics\"\nimport {\n  analyzeChannelCall as _analyzeChannelCall,\n  analyzeSinkCall as _analyzeSinkCall,\n  analyzeStreamCall as _analyzeStreamCall\n} from \"./stream-channel-sink-analyzers\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport { extractEffectTypeSignature, extractLayerTypeSignature, extractServiceRequirements } from \"./type-extractor\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  EffectTypeSignature,\n  LayerLifecycle,\n  StaticDecisionNode,\n  StaticEffectNode,\n  StaticErrorHandlerNode,\n  StaticFiberNode,\n  StaticFlowNode,\n  StaticLayerNode,\n  StaticPipeNode,\n  StaticStreamNode,\n  StaticUnknownNode\n} from \"./types\"\nimport { getStaticChildren } from \"./types\"\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 * Heuristic: does this `.pipe(...)` call apply Effect-level operations?\n *\n * Used to route pipe calls whose base is not literally `Effect.*` but whose\n * transformations are (e.g. `service.doThing().pipe(Effect.retry(...))`).\n * Matches the textual prefix of each arg against the Effect module's common\n * combinators — cheap, no type-checker needed.\n */\nconst EFFECT_PIPE_OP_REGEX =\n  /^Effect\\.(retry|retryOrElse|retryN|timeout(?:Fail|FailCause|Option|To)?|catch\\w*|orElse|orElseSucceed|orElseFail|orElseFailWith|orDie|orDieWith|ignore|ignoreLogged|sandbox|unsandbox|flip|tap|tapBoth|tapDefect|tapError|tapErrorCause|tapErrorTag|mapError|mapBoth|withSpan|annotateLogs|annotateSpans|ensuring|ensuringWith|onError|onExit|delay|repeat|repeatN|repeatOrElse|zip|zipLeft|zipRight|matchEffect|match)\\s*(?:\\(|$)/\n\nconst pipeArgsIncludeEffectOp = (call: CallExpression): boolean => {\n  for (const arg of call.getArguments()) {\n    if (EFFECT_PIPE_OP_REGEX.test(arg.getText())) return true\n  }\n  return false\n}\n\n/**\n * `Effect.orDie` and `Effect.ignore` are unary, so a pipe passes them uncalled\n * and the call-based handler analyzer never sees them.\n */\nconst asErrorHandler = (\n  analyzed: StaticFlowNode,\n  arg: Node,\n  stats: AnalysisStats\n): StaticFlowNode => {\n  if (analyzed.type !== \"effect\") return analyzed\n  if (arg.getKind() === loadTsMorph().SyntaxKind.CallExpression) return analyzed\n  const text = arg.getText()\n  if (!ERROR_HANDLER_PATTERNS.some((pattern) => text.includes(pattern))) {\n    return analyzed\n  }\n  const handlerType = classifyErrorHandlerName(text)\n  stats.errorHandlerCount++\n  const node: StaticErrorHandlerNode = {\n    id: generateId(),\n    type: \"error-handler\",\n    handlerType,\n    // Uncalled combinator: the effect it applies to is the pipe's own base,\n    // which `walkPropagation` already has in hand when it reaches this node.\n    source: { id: generateId(), type: \"effect\", callee: text, description: \"pipe-input\" },\n    ...(analyzed.location ? { location: analyzed.location } : {})\n  }\n  return {\n    ...node,\n    displayName: computeDisplayName(node),\n    semanticRole: computeSemanticRole(node)\n  }\n}\n\nexport const analyzePipeChain = (\n  node: CallExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<AnalysisWarning>,\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>\n): Effect.Effect<ReadonlyArray<StaticFlowNode>, AnalysisError> =>\n  Effect.gen(function*() {\n    const { SyntaxKind } = loadTsMorph()\n    const args = node.getArguments()\n    const expr = node.getExpression()\n    const isMethodPipe = 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: Array<StaticFlowNode> = []\n    for (const arg of transformArgs) {\n      if (arg) {\n        const analyzed = yield* analyzeEffectExpression(\n          arg,\n          sourceFile,\n          filePath,\n          opts,\n          warnings,\n          stats,\n          serviceScope\n        )\n        transformations.push(asErrorHandler(analyzed, arg, stats))\n      }\n    }\n\n    // Detect Effect.withSpan in transformations and merge as annotation\n    const sourceOrderedSpanNames: Array<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: Array<EffectTypeSignature> | undefined\n    yield* Effect.try(() => {\n      const typeChecker = sourceFile.getProject().getTypeChecker()\n      const flow: Array<EffectTypeSignature> = []\n      // Extract initial type\n      const initialSig = extractEffectTypeSignature(baseExpr, typeChecker)\n      if (initialSig) flow.push(initialSig)\n      // Extract type at each transform step\n      for (const argNode of transformArgs) {\n        if (argNode) {\n          const sig = extractEffectTypeSignature(argNode, typeChecker)\n          if (sig) flow.push(sig)\n        }\n      }\n      if (flow.length > 0) typeFlow = flow\n      // Type extraction can fail; leaving typeFlow unset is the fallback.\n    }).pipe(Effect.ignore)\n\n    // A pipe whose only transforms were annotations (Effect.withSpan) adds no\n    // step of its own. Emitting a \"Pipe (0 steps)\" node between every real call\n    // buries the flow; collapse to the base effect and carry the span across.\n    if (filteredTransformations.length === 0) {\n      // Chained annotation pipes stack: `x.pipe(withSpan('inner')).pipe(\n      // withSpan('outer'))` collapses twice onto the same base, so the names\n      // already on it are the inner ones. Concatenating keeps `spanNames`\n      // outermost-first, which is the order `indexIR` builds span paths in;\n      // overwriting would drop the inner span and lose the trace match.\n      const innerSpanNames = initial.spanNames ?? (initial.spanName ? [initial.spanName] : [])\n      const mergedSpanNames = [...spanNames, ...innerSpanNames]\n      const innermost = mergedSpanNames.at(-1)\n      return [{\n        ...initial,\n        ...(innermost ? { spanName: innermost } : {}),\n        ...(mergedSpanNames.length > 0 ? { spanNames: mergedSpanNames } : {}),\n        ...(spanNameDynamic || initial.spanNameDynamic\n          ? { spanNameDynamic: true }\n          : {})\n      }]\n    }\n\n    const pipeNode: StaticPipeNode = {\n      id: generateId(),\n      type: \"pipe\",\n      initial,\n      transformations: filteredTransformations,\n      ...(typeFlow ? { typeFlow } : {}),\n      ...(spanName ? { spanName } : {}),\n      ...(spanNames.length > 0 ? { spanNames } : {}),\n      ...(spanNameDynamic ? { spanNameDynamic: true } : {})\n    }\n    const enrichedPipeNode: StaticPipeNode = {\n      ...pipeNode,\n      displayName: computeDisplayName(pipeNode),\n      semanticRole: computeSemanticRole(pipeNode)\n    }\n\n    return [enrichedPipeNode]\n  })\n\n// =============================================================================\n// Effect Expression Analysis\n// =============================================================================\n\nexport const analyzeEffectExpression = (\n  node: Node,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<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    // `cond ? effectA : effectB` picks one of two programs. Same decision node\n    // as a ternary over `yield*` in a generator; unknown if neither branch is\n    // an Effect.\n    if (node.getKind() === SyntaxKind.ConditionalExpression) {\n      const ternary = node as ConditionalExpression\n      const analyzeBranch = (branch: Node) =>\n        analyzeEffectExpression(branch, sourceFile, filePath, opts, warnings, stats, serviceScope)\n      const whenTrue = yield* analyzeBranch(ternary.getWhenTrue())\n      const whenFalse = yield* analyzeBranch(ternary.getWhenFalse())\n      if (whenTrue.type !== \"unknown\" || whenFalse.type !== \"unknown\") {\n        const condition = ternary.getCondition().getText()\n        const decisionNode: StaticDecisionNode = {\n          id: generateId(),\n          type: \"decision\",\n          decisionId: generateId(),\n          label: condition.length > 40 ? condition.slice(0, 40) + \"...\" : condition,\n          condition,\n          source: \"raw-ternary\",\n          onTrue: [whenTrue],\n          onFalse: [whenFalse],\n          location: extractLocation(node, filePath, opts.includeLocations ?? false)\n        }\n        stats.decisionCount++\n        return decisionNode\n      }\n    }\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\"] = 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: Array<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 type = newExpr.getType()\n      const typeText = type.getText()\n      // A subclass (`class PageSkipped extends Data.TaggedError(...)`) prints\n      // as its own name. An instance that is both an Effect and an Error is a\n      // yieldable error.\n      const isYieldableError = type.getProperty(\"~effect/Effect\") !== undefined &&\n        type.getProperty(\"message\") !== undefined\n      const isErrorLike = ctorName.endsWith(\"Error\") ||\n        typeText.includes(\"YieldableError\") ||\n        typeText.includes(\"TaggedError\") ||\n        isYieldableError\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: Array<AnalysisWarning>,\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>\n): Effect.Effect<StaticFlowNode, AnalysisError> =>\n  Effect.gen(function*() {\n    const { SyntaxKind } = loadTsMorph()\n    // Source text keeps the line breaks of a wrapped member chain\n    // (`deps\\n  .fetchRate`), which surfaces in every label as `deps .fetchRate`.\n    const callee = call.getExpression().getText().replace(/\\s*\\n\\s*/g, \"\")\n    const normalizedCallee = normalizeEffectCallee(callee, sourceFile)\n    const calleeOperation = (/([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 = 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 = 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 = 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 = 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        serviceScope\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) => 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            serviceScope\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        serviceScope\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        serviceScope\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: ReadonlyArray<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 = 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 = 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: Array<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(\n                    expr as CallExpression,\n                    sourceFile,\n                    getAliasesForFile(sourceFile),\n                    opts.knownEffectInternalsRoot\n                  )\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 = 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 (\n      callee.endsWith(\".sync\") || callee.endsWith(\".succeed\") || callee.endsWith(\".fail\") || callee.endsWith(\".try\") ||\n      callee.endsWith(\".suspend\")\n    ) 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 = [\n      \"currentConcurrency\",\n      \"currentLogLevel\",\n      \"currentScheduler\",\n      \"currentTracerEnabled\",\n      \"currentLogSpan\",\n      \"currentLogAnnotations\",\n      \"currentContext\",\n      \"currentRequestBatching\",\n      \"currentMaxOpsBeforeYield\",\n      \"currentSupervisor\",\n      \"currentMetricLabels\",\n      \"interruptedCause\",\n      \"unhandledLogLevel\"\n    ] as const\n    for (const refName of KNOWN_FIBER_REFS) {\n      if (callee.includes(refName)) {\n        fiberRefName = refName\n        break\n      }\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 wrappedCall = LIFTING_CALLEES.has(normalizedCallee) ? liftedCallName(call) : undefined\n    const wrappedAssignment = LIFTING_CALLEES.has(normalizedCallee) && !wrappedCall\n      ? liftedAssignmentTarget(call)\n      : undefined\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      ...(wrappedCall ? { wrappedCall } : {}),\n      ...(wrappedAssignment ? { wrappedAssignment } : {})\n    }\n    const enrichedEffectNode: StaticEffectNode = {\n      ...effectNode,\n      displayName: computeDisplayName(effectNode),\n      semanticRole: computeSemanticRole(effectNode)\n    }\n    return enrichedEffectNode\n  })\n\n/** Constructors that lift one promise-returning or throwing call into an Effect. */\nconst LIFTING_CALLEES = new Set([\"Effect.tryPromise\", \"Effect.promise\", \"Effect.try\", \"Effect.sync\"])\n\n/**\n * The call a lifting constructor wraps: `wallet.getBalance` in\n * `Effect.tryPromise({ try: () => wallet.getBalance(id), catch })` or\n * `Effect.tryPromise(() => wallet.getBalance(id))`.\n */\nconst liftedCallName = (call: CallExpression): string | undefined => {\n  const { Node: TsNode } = loadTsMorph()\n  const returned = liftedResult(call)\n  if (!returned) return undefined\n  let inner = unwrapExpression(returned)\n  if (TsNode.isAwaitExpression(inner)) inner = unwrapExpression(inner.getExpression())\n  if (!TsNode.isCallExpression(inner)) return undefined\n  const name = inner.getExpression().getText()\n  return /^[\\w$.]+$/.test(name) ? name : undefined\n}\n\n/**\n * The thunk a lifting constructor runs: the first argument, or its `try`\n * property in the `{ try, catch }` form.\n */\nconst liftedThunk = (call: CallExpression): Node | undefined => {\n  const { Node: TsNode } = loadTsMorph()\n  let thunk: Node | undefined = call.getArguments()[0]\n  if (thunk && TsNode.isObjectLiteralExpression(thunk)) {\n    const tryProp = thunk.getProperty(\"try\")\n    thunk = tryProp && TsNode.isPropertyAssignment(tryProp) ? tryProp.getInitializer() : tryProp\n  }\n  return thunk\n}\n\n/** The expression a lifted thunk evaluates to, when the thunk is a function. */\nconst liftedResult = (call: CallExpression): Node | undefined => {\n  const { Node: TsNode } = loadTsMorph()\n  const thunk = liftedThunk(call)\n  if (\n    !thunk ||\n    !(TsNode.isArrowFunction(thunk) || TsNode.isFunctionExpression(thunk) || TsNode.isMethodDeclaration(thunk))\n  ) {\n    return undefined\n  }\n  const body = thunk.getBody()\n  return body && TsNode.isBlock(body) ? blockResult(body.getStatements()) : body\n}\n\n/**\n * The field a lifted thunk assigns when its body is one assignment:\n * `ledger.balances` in `Effect.sync(() => { ledger.balances = snapshot })`.\n */\nconst liftedAssignmentTarget = (call: CallExpression): string | undefined => {\n  const { Node: TsNode, SyntaxKind } = loadTsMorph()\n  const result = liftedResult(call)\n  if (!result) return undefined\n  const expr = unwrapExpression(result)\n  if (!TsNode.isBinaryExpression(expr) || expr.getOperatorToken().getKind() !== SyntaxKind.EqualsToken) {\n    return undefined\n  }\n  const target = expr.getLeft().getText()\n  return /^[\\w$.]+$/.test(target) ? target : undefined\n}\n\n/**\n * The expression a block body hands back: its `return` value, or the call in a\n * block that is a single statement, as in `Effect.sync(() => { release(c) })`.\n */\nconst blockResult = (statements: ReadonlyArray<Node>): Node | undefined => {\n  const { Node: TsNode } = loadTsMorph()\n  const returned = statements.find(TsNode.isReturnStatement)?.getExpression()\n  if (returned) return returned\n  const [only] = statements\n  return statements.length === 1 && only && TsNode.isExpressionStatement(only) ? only.getExpression() : undefined\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\nconst analyzeLayerCall = (\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<AnalysisWarning>,\n  stats: AnalysisStats\n): Effect.Effect<StaticLayerNode, AnalysisError> =>\n  Effect.gen(function*() {\n    const args = call.getArguments()\n    const operations: Array<StaticFlowNode> = []\n    const { SyntaxKind } = loadTsMorph()\n\n    if (args.length > 0 && args[0]) {\n      const firstArg = args[0]\n      const isMergeAll = 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 = 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: Array<string> = []\n    // Helper: extract one or more tag names from an arg.\n    const extractTagNames = (node: Node): Array<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\",\n      \"catchCause\",\n      \"orDie\",\n      \"orElse\",\n      \"retry\",\n      \"tap\",\n      \"mapError\",\n      \"mapErrorCause\",\n      \"build\",\n      \"launch\",\n      \"toRuntime\",\n      \"passthrough\",\n      \"project\",\n      \"flatMap\",\n      \"flatten\",\n      \"annotateLogs\",\n      \"annotateSpans\",\n      \"setConfigProvider\",\n      \"setClock\",\n      \"setTracer\",\n      \"locally\",\n      \"withSpan\",\n      \"withLogger\",\n      \"withTracer\",\n      \"withClock\",\n      \"mock\",\n      \"suspend\",\n      \"unwrapEffect\",\n      \"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 = 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","/** Shared recursive context for domain-specific expression analyzers. */\n\nimport type { Effect } from \"effect\"\nimport type { Node, SourceFile } from \"ts-morph\"\nimport type { AnalysisError, AnalysisStats, AnalysisWarning, AnalyzerOptions, StaticFlowNode } from \"./types\"\n\nexport type AnalyzeEffectExpression = (\n  node: Node,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<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\n/**\n * The same context, with a generator's service scope (`s` → `Svc`) carried into\n * every recursive call that doesn't bring its own. Callbacks inside a pipe step\n * (`Effect.tapError(() => s.cleanup)`) then resolve `s.cleanup` as a service\n * call, the same as `s.a` at the head of the pipe.\n */\nexport const withServiceScope = (\n  deps: AnalysisContext,\n  serviceScope: Map<string, string> | undefined\n): AnalysisContext =>\n  serviceScope === undefined ? deps : {\n    analyzeEffectExpression: (node, sourceFile, filePath, opts, warnings, stats, scope) =>\n      deps.analyzeEffectExpression(node, sourceFile, filePath, opts, warnings, stats, scope ?? serviceScope)\n  }\n\nexport type BindAnalysisContext<F> = F extends (\n  context: AnalysisContext,\n  ...args: infer Args\n) => infer Output ? (...args: Args) => Output\n  : never\n\nexport const bindAnalysisContext = <\n  F extends (context: AnalysisContext, ...args: Array<never>) => unknown\n>(\n  context: AnalysisContext,\n  analyzer: F\n): BindAnalysisContext<F> => ((...args: Array<never>) => analyzer(context, ...args)) as BindAnalysisContext<F>\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  ArrowFunction,\n  Block,\n  CallExpression,\n  FunctionExpression,\n  Identifier,\n  Node,\n  SourceFile,\n  VariableStatement\n} from \"ts-morph\"\nimport { computeDisplayName, computeSemanticRole, extractLocation, generateId } from \"./analysis-utils\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  StaticEffectNode,\n  StaticFlowNode,\n  StaticLoopNode\n} from \"./types\"\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: ReadonlyArray<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: ReadonlyArray<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): ReadonlyArray<StaticFlowNode> | undefined => {\n  const { SyntaxKind } = loadTsMorph()\n  const body = fnNode.getBody()\n  const calls: Array<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: Array<AnalysisWarning>,\n  stats: AnalysisStats,\n  resumeParamName: string\n): Effect.Effect<ReadonlyArray<StaticFlowNode>, AnalysisError> =>\n  Effect.gen(function*() {\n    const { SyntaxKind } = loadTsMorph()\n    const summaries: Array<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 = 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: ReadonlyArray<StaticFlowNode>\n): ReadonlyArray<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: Array<AnalysisWarning>,\n  stats: AnalysisStats,\n  resumeParamName: string\n): Effect.Effect<ReadonlyArray<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: Array<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): ReadonlyArray<StaticFlowNode> | undefined => {\n  const { SyntaxKind } = loadTsMorph()\n  const body = fnNode.getBody()\n  const summaries: Array<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 * 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 { CallExpression, NumericLiteral, PropertyAccessExpression, SourceFile } from \"ts-morph\"\nimport type { AnalysisContext } from \"./analysis-context\"\nimport { getNumericLiteralFromNode } from \"./analysis-patterns\"\nimport { computeDisplayName, computeSemanticRole, extractLocation, generateId } from \"./analysis-utils\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  StaticConcurrencyPrimitiveNode,\n  StaticFiberNode,\n  StaticFlowNode,\n  StaticInterruptionNode,\n  StaticStreamNode\n} from \"./types\"\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: Array<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 = 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: Array<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\")) {\n        operation = \"scoped\"\n        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: Array<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(\n        propAccess.getExpression(),\n        sourceFile,\n        filePath,\n        opts,\n        warnings,\n        stats\n      )\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 * 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  ArrowFunction,\n  CallExpression,\n  FunctionExpression,\n  ObjectLiteralExpression,\n  PropertyAccessExpression,\n  PropertyAssignment,\n  SourceFile\n} from \"ts-morph\"\nimport { parseEffectAllOptions } from \"./analysis-classifiers\"\nimport { type AnalysisContext, withServiceScope } from \"./analysis-context\"\nimport {\n  CAUSE_CONSTRUCTORS,\n  CAUSE_OP_MAP,\n  EFFECTFUL_TRANSFORMS,\n  EXHAUSTIVE_OPS,\n  EXIT_CONSTRUCTORS,\n  EXIT_OP_MAP,\n  MATCH_OP_MAP,\n  TAP_TRANSFORMS,\n  TRANSFORM_OPS\n} from \"./analysis-patterns\"\nimport { computeDisplayName, computeSemanticRole, extractLocation, generateId } from \"./analysis-utils\"\nimport {\n  buildCallbackSummaryNodes,\n  buildPureCallbackSummaryNodes,\n  summarizeLoopCallbackSource\n} from \"./callback-summary\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  StaticCauseNode,\n  StaticConditionalNode,\n  StaticExitNode,\n  StaticFlowNode,\n  StaticLoopNode,\n  StaticMatchNode,\n  StaticTransformNode\n} from \"./types\"\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: Array<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: Array<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\"] = callee.includes(\"forEach\") ?\n      \"forEach\" :\n      callee.includes(\"filterMap\") ?\n      \"filterMap\" :\n      callee.includes(\"filter\") ?\n      \"filter\" :\n      callee.includes(\"partition\") ?\n      \"partition\" :\n      callee.includes(\"reduce\") ?\n      \"reduce\" :\n      callee.includes(\"validateAll\") || callee.includes(\"validateFirst\") || callee.includes(\"validateWith\") ?\n      \"validate\" :\n      callee.includes(\"replicate\") ?\n      \"replicate\" :\n      callee.includes(\"dropUntil\") ?\n      \"dropUntil\" :\n      callee.includes(\"dropWhile\") ?\n      \"dropWhile\" :\n      callee.includes(\"takeUntil\") ?\n      \"takeUntil\" :\n      callee.includes(\"takeWhile\") ?\n      \"takeWhile\" :\n      callee.includes(\"every\") ?\n      \"every\" :\n      callee.includes(\"exists\") ?\n      \"exists\" :\n      callee.includes(\"findFirst\") ?\n      \"findFirst\" :\n      callee.includes(\"head\") ?\n      \"head\" :\n      callee.includes(\"mergeAll\") ?\n      \"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 = 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: ReadonlyArray<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 = 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 = 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 = 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    // Trailing `{ concurrency }` options (Effect.forEach(xs, f, { concurrency: 4 })).\n    const lastArg = args.length > 1 ? args[args.length - 1] : undefined\n    const concurrency = lastArg?.getKind() === SyntaxKind.ObjectLiteralExpression\n      ? parseEffectAllOptions(lastArg as ObjectLiteralExpression).concurrency\n      : undefined\n\n    const loopNode: StaticLoopNode = {\n      id: generateId(),\n      type: \"loop\",\n      loopType,\n      iterSource,\n      body,\n      ...(callbackBody ? { callbackBody } : {}),\n      ...(concurrency !== undefined ? { concurrency } : {}),\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: Array<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: Array<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: ReadonlyArray<StaticFlowNode> | undefined\n    if (causeOp === \"parallel\" || causeOp === \"sequential\") {\n      const args = call.getArguments()\n      const childNodes: Array<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  outerDeps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<AnalysisWarning>,\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>\n): Effect.Effect<StaticTransformNode, AnalysisError> =>\n  Effect.gen(function*() {\n    const deps = withServiceScope(outerDeps, serviceScope)\n    const args = call.getArguments()\n    const transformType: StaticTransformNode[\"transformType\"] = 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    // A tap's callback is the last argument: a function, or a reference to one\n    // (`Effect.tapError(svc.cleanup)`). Not an object (tapBoth's { onFailure,\n    // onSuccess }, even by reference) or a tag string.\n    let callback: StaticFlowNode | undefined\n    const callbackArg = TAP_TRANSFORMS.has(transformType) ? args.at(-1) : undefined\n    const { SyntaxKind } = loadTsMorph()\n    const callbackKind = callbackArg?.getKind()\n    if (\n      callbackArg &&\n      (callbackKind === SyntaxKind.ArrowFunction ||\n        callbackKind === SyntaxKind.FunctionExpression ||\n        (transformType !== \"tapBoth\" &&\n          (callbackKind === SyntaxKind.Identifier || callbackKind === SyntaxKind.PropertyAccessExpression)))\n    ) {\n      callback = yield* deps.analyzeEffectExpression(callbackArg, sourceFile, filePath, opts, warnings, stats)\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      ...(callback !== undefined ? { callback } : {}),\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 * 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, ShorthandPropertyAssignment } from \"ts-morph\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type { ChannelOperatorInfo, ConcurrencyMode, ScheduleInfo, SinkOperatorInfo } 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  }\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  }\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  }\n  if (\n    op.includes(\"map\") ||\n    op.includes(\"contramap\") ||\n    op.includes(\"filter\") ||\n    op.includes(\"zip\")\n  ) {\n    return \"transform\"\n  }\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    // `{ concurrency }` shorthand reads the binding's type like `{ concurrency: x }`.\n    const isShorthand = prop.getKind() === SyntaxKind.ShorthandPropertyAssignment\n    if (prop.getKind() !== SyntaxKind.PropertyAssignment && !isShorthand) continue\n    const name = (prop as PropertyAssignment | ShorthandPropertyAssignment).getNameNode().getText()\n    const init = isShorthand\n      ? (prop as ShorthandPropertyAssignment).getNameNode()\n      : (prop as PropertyAssignment).getInitializer()\n    if (!init) continue\n    const text = init.getText()\n    if (name === \"concurrency\") {\n      // Literals and consts (`concurrency: CONCURRENCY`) resolve through their\n      // literal type; any other numeric expression is a bound of unknown size.\n      const type = init.getType()\n      const literal = type.getLiteralValue() ?? /^[\"'](\\w+)[\"']$/.exec(text)?.[1]\n      if (literal === \"unbounded\") concurrency = \"unbounded\"\n      else if (literal === \"sequential\" || literal === \"inherit\") concurrency = \"sequential\"\n      else if (typeof literal === \"number\" && literal >= 0) concurrency = literal\n      else if (type.isNumber()) concurrency = \"bounded\"\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\nconst DURATION_UNITS: Record<string, string> = {\n  millis: \"ms\",\n  seconds: \"s\",\n  minutes: \"m\",\n  hours: \"h\"\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  // `times: N` in retry options or `Schedule.upTo({ times: N })`.\n  const timesMatch = /\\btimes\\s*:\\s*(\\d+)/.exec(t)\n  if (recurUpToMatch) maxRetries = Number.parseInt(recurUpToMatch[1]!, 10)\n  else if (timesMatch) maxRetries = Number.parseInt(timesMatch[1]!, 10)\n  else if (t.includes(\"forever\") || t.includes(\"Schedule.forever\")) maxRetries = \"unlimited\"\n\n  // First argument of the base strategy: `exponential(Duration.millis(10))` -> \"10ms\".\n  const delayMatch =\n    /(?:exponential|fibonacci|spaced|fixed|linear)\\(\\s*(Duration\\.(\\w+)\\(\\s*(\\d+)\\s*\\)|[\"'][^\"']+[\"']|\\d+)/\n      .exec(t)\n  const initialDelay = delayMatch\n    ? delayMatch[2] !== undefined\n      ? `${delayMatch[3]}${DURATION_UNITS[delayMatch[2]] ?? ` ${delayMatch[2]}`}`\n      : delayMatch[1]!.replace(/[\"']/g, \"\")\n    : undefined\n\n  const jittered = t.includes(\"jittered\") || t.includes(\"Schedule.jittered\")\n  const conditions: Array<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    ...(initialDelay !== undefined ? { initialDelay } : {}),\n    jittered,\n    conditions\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  MethodDeclaration,\n  Node,\n  ObjectLiteralExpression,\n  PropertyAccessExpression,\n  PropertyAssignment,\n  SourceFile,\n  StringLiteral\n} from \"ts-morph\"\nimport { type AnalysisContext, withServiceScope } from \"./analysis-context\"\nimport { computeDisplayName, computeSemanticRole, extractLocation, generateId } from \"./analysis-utils\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  StaticErrorHandlerNode,\n  StaticFlowNode\n} from \"./types\"\n\n/**\n * Which handler a callee names. Ordered longest-first: the chain is substring\n * based, so `catchReason` must be tested before `catchCause` and `catch`, or\n * Effect 4's selective catches all read as catch-everything.\n */\nexport const classifyErrorHandlerName = (\n  callee: string\n): StaticErrorHandlerNode[\"handlerType\"] => {\n  if (callee.includes(\"catchCauseFilter\")) {\n    return \"catchCauseFilter\"\n  }\n  if (callee.includes(\"catchCauseIf\")) {\n    return \"catchCauseIf\"\n  }\n  if (callee.includes(\"catchNoSuchElement\")) {\n    return \"catchNoSuchElement\"\n  }\n  if (callee.includes(\"catchReasons\")) {\n    return \"catchReasons\"\n  }\n  if (callee.includes(\"catchReason\")) {\n    return \"catchReason\"\n  }\n  if (callee.includes(\"catchFilter\")) {\n    return \"catchFilter\"\n  }\n  if (callee.includes(\"catchEager\")) {\n    return \"catchEager\"\n  }\n  if (callee.includes(\"catchCause\")) {\n    return \"catchCause\"\n  }\n  if (callee.includes(\"catchSomeCause\")) {\n    return \"catchSomeCause\"\n  }\n  if (callee.includes(\"catchSomeDefect\")) {\n    return \"catchSomeDefect\"\n  }\n  if (callee.includes(\"catchDefect\")) {\n    return \"catchDefect\"\n  }\n  if (callee.includes(\"catchTags\")) {\n    return \"catchTags\"\n  }\n  if (callee.includes(\"catchIf\")) {\n    return \"catchIf\"\n  }\n  if (callee.includes(\"catchSome\")) {\n    return \"catchSome\"\n  }\n  if (callee.includes(\"catchTag\")) {\n    return \"catchTag\"\n  }\n  if (callee.includes(\"catch\")) {\n    return \"catch\"\n  }\n  if (callee.includes(\"orElseFail\")) {\n    return \"orElseFail\"\n  }\n  if (callee.includes(\"orElseSucceed\")) {\n    return \"orElseSucceed\"\n  }\n  if (callee.includes(\"orElse\")) {\n    return \"orElse\"\n  }\n  if (callee.includes(\"orDieWith\")) {\n    return \"orDieWith\"\n  }\n  if (callee.includes(\"orDie\")) {\n    return \"orDie\"\n  }\n  if (callee.includes(\"flip\")) {\n    return \"flip\"\n  }\n  if (callee.includes(\"mapErrorCause\")) {\n    return \"mapErrorCause\"\n  }\n  if (callee.includes(\"mapBoth\")) {\n    return \"mapBoth\"\n  }\n  if (callee.includes(\"mapError\")) {\n    return \"mapError\"\n  }\n  if (callee.includes(\"unsandbox\")) {\n    return \"unsandbox\"\n  }\n  if (callee.includes(\"sandbox\")) {\n    return \"sandbox\"\n  }\n  if (callee.includes(\"parallelErrors\")) {\n    return \"parallelErrors\"\n  }\n  if (callee.includes(\"filterOrDieMessage\")) {\n    return \"filterOrDieMessage\"\n  }\n  if (callee.includes(\"filterOrDie\")) {\n    return \"filterOrDie\"\n  }\n  if (callee.includes(\"filterOrElse\")) {\n    return \"filterOrElse\"\n  }\n  if (callee.includes(\"filterOrFail\")) {\n    return \"filterOrFail\"\n  }\n  if (callee.includes(\"matchCauseEffect\")) {\n    return \"matchCauseEffect\"\n  }\n  if (callee.includes(\"matchCause\")) {\n    return \"matchCause\"\n  }\n  if (callee.includes(\"matchEffect\")) {\n    return \"matchEffect\"\n  }\n  if (callee.includes(\"match\")) {\n    return \"match\"\n  }\n  if (callee.includes(\"firstSuccessOf\")) {\n    return \"firstSuccessOf\"\n  }\n  if (callee.includes(\"ignoreLogged\")) {\n    return \"ignoreLogged\"\n  }\n  if (callee.includes(\"ignore\")) {\n    return \"ignore\"\n  }\n  if (callee.includes(\"eventually\")) {\n    return \"eventually\"\n  }\n  return \"catch\"\n}\n\nexport const analyzeErrorHandlerCall = (\n  outerDeps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<AnalysisWarning>,\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>\n): Effect.Effect<StaticErrorHandlerNode, AnalysisError> =>\n  Effect.gen(function*() {\n    const deps = withServiceScope(outerDeps, serviceScope)\n    const args = call.getArguments()\n\n    const handlerType = classifyErrorHandlerName(callee)\n\n    // For methods that are called as effect.pipe(Effect.catch(handler))\n    // we need to find the source effect differently\n    let source: StaticFlowNode\n    let handler: StaticFlowNode | undefined\n\n    const { SyntaxKind } = loadTsMorph()\n    const isEffect = (n: Node) => n.getType().getProperty(\"~effect/Effect\") !== undefined\n    // Callbacks, handler objects and tag strings are handler arguments. When\n    // types do not resolve (in-memory sources), argument shape decides.\n    const isHandlerShaped = (n: Node) =>\n      n.getKind() === SyntaxKind.ArrowFunction ||\n      n.getKind() === SyntaxKind.FunctionExpression ||\n      n.getKind() === SyntaxKind.ObjectLiteralExpression ||\n      n.getKind() === SyntaxKind.StringLiteral\n    const isDataFirstSource = (n: Node) =>\n      isEffect(n) || (args.length >= 2 && !isHandlerShaped(n) && n.getType().getText() === \"any\")\n    const analyze = (n: Node) => deps.analyzeEffectExpression(n, sourceFile, filePath, opts, warnings, stats)\n    // An object literal (catchTags, match) is a bag of handlers, not an Effect.\n    const analyzeHandler = (n: Node) =>\n      n.getKind() === SyntaxKind.ObjectLiteralExpression ? Effect.succeed(undefined) : analyze(n)\n\n    // Three call shapes:\n    //   effect.catch(fn)               method on an Effect value\n    //   Effect.catchTags(eff, {...})   data-first: source is the first argument\n    //   Effect.catchTags({...})        data-last (inside .pipe): returns a\n    //                                  function, the source is the pipe's base\n    const expr = call.getExpression()\n    const receiver = expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression\n      ? (expr as PropertyAccessExpression).getExpression()\n      : undefined\n    if (receiver && isEffect(receiver)) {\n      source = yield* analyze(receiver)\n      if (args[0]) handler = yield* analyzeHandler(args[0])\n    } else if (args[0] && isDataFirstSource(args[0])) {\n      source = yield* analyze(args[0])\n      // catchTag(eff, \"Tag\", fn): the handler follows the tag.\n      const handlerArg = args[args.length - 1]\n      if (args.length > 1 && handlerArg) handler = yield* analyzeHandler(handlerArg)\n    } else {\n      // Same placeholder `asErrorHandler` uses for an uncalled combinator:\n      // `walkPropagation` supplies the pipe's base when it reaches this node.\n      source = { id: generateId(), type: \"effect\", callee, description: \"pipe-input\" }\n      const handlerArg = args[args.length - 1]\n      if (handlerArg) handler = yield* analyzeHandler(handlerArg)\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: ReadonlyArray<string> | undefined\n    let tagHandlers: Array<{ tag: string; handler: StaticFlowNode }> | undefined\n    if (handlerType === \"catchTag\") {\n      // catchTag(\"Tag\", fn) or catchTag(eff, \"Tag\", fn): the first string literal.\n      const tagArg = args.find((a) => a.getKind() === loadTsMorph().SyntaxKind.StringLiteral)\n      if (tagArg) errorTag = (tagArg as StringLiteral).getLiteralValue()\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        tagHandlers = []\n        for (const p of (objArg as ObjectLiteralExpression).getProperties()) {\n          // `Tag: (e) => ...` analyzes its initializer; `Tag(e) { ... }` the method itself.\n          const body = p.getKind() === SyntaxKind.PropertyAssignment\n            ? (p as PropertyAssignment).getInitializer()\n            : p.getKind() === SyntaxKind.MethodDeclaration\n            ? (p as MethodDeclaration)\n              .getDescendantsOfKind(SyntaxKind.ReturnStatement)\n              .at(-1)\n              ?.getExpression()\n            : undefined\n          if (!body) continue\n          const tag = (p as PropertyAssignment | MethodDeclaration).getName()\n          tagHandlers.push({\n            tag,\n            handler: yield* deps.analyzeEffectExpression(body, sourceFile, filePath, opts, warnings, stats)\n          })\n        }\n        errorTags = tagHandlers.map((t) => t.tag)\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      ...(tagHandlers && tagHandlers.length > 0 ? { tagHandlers } : {}),\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 * 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  Identifier,\n  ImportSpecifier,\n  Node,\n  VariableDeclaration,\n  VariableStatement\n} from \"ts-morph\"\nimport { normalizeEffectCallee, resolveBarrelSourceFile, resolveModulePath } from \"./alias-resolution\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\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 = decl?.getKind() === SyntaxKind.ImportSpecifier\n    ? (decl as ImportSpecifier)\n    : 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 * 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  ArrayLiteralExpression,\n  CallExpression,\n  ObjectLiteralExpression,\n  PropertyAssignment,\n  SourceFile\n} from \"ts-morph\"\nimport { parseEffectAllOptions } from \"./analysis-classifiers\"\nimport type { AnalysisContext } from \"./analysis-context\"\nimport { computeDisplayName, computeSemanticRole, extractLocation, generateId, isConcurrent } from \"./analysis-utils\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  ConcurrencyMode,\n  StaticFlowNode,\n  StaticParallelNode,\n  StaticRaceNode\n} from \"./types\"\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: Array<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: Array<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\") || isConcurrent(concurrency) ? \"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: Array<AnalysisWarning>,\n  stats: AnalysisStats\n): Effect.Effect<StaticRaceNode, AnalysisError> =>\n  Effect.gen(function*() {\n    const args = call.getArguments()\n    const children: Array<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 * 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 { CallExpression, PropertyAccessExpression, SourceFile } from \"ts-morph\"\nimport { type AnalysisContext, withServiceScope } from \"./analysis-context\"\nimport { computeDisplayName, computeSemanticRole, extractLocation, generateId } from \"./analysis-utils\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  StaticFlowNode,\n  StaticResourceNode\n} from \"./types\"\n\nexport const analyzeResourceCall = (\n  outerDeps: AnalysisContext,\n  call: CallExpression,\n  callee: string,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<AnalysisWarning>,\n  stats: AnalysisStats,\n  serviceScope?: Map<string, string>\n): Effect.Effect<StaticResourceNode, AnalysisError> =>\n  Effect.gen(function*() {\n    const deps = withServiceScope(outerDeps, serviceScope)\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      const dataFirst = (resourceOperation === \"onError\" || resourceOperation === \"onExit\") && args.length >= 2\n      if (dataFirst && args[0] && args[1]) {\n        // Effect.onError(effect, cleanup): the effect comes first, then the cleanup.\n        acquire = yield* deps.analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats)\n        release = yield* deps.analyzeEffectExpression(args[1], sourceFile, filePath, opts, warnings, stats)\n      } else {\n        // `x.addFinalizer(f)` is a method chain on x. `Effect.onError(f)` is the\n        // data-last form inside a pipe: `Effect` is the module, not the source.\n        const receiver = expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression\n          ? (expr as PropertyAccessExpression).getExpression().getText()\n          : undefined\n        if (receiver !== undefined && receiver !== \"Effect\") {\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 = 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      }\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 = 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 = 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 = 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      resourceOperation,\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 * 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  Node,\n  ObjectLiteralExpression,\n  PropertyAccessExpression,\n  PropertyAssignment,\n  ShorthandPropertyAssignment,\n  SourceFile,\n  VariableDeclaration\n} from \"ts-morph\"\nimport { getAliasesForFile } from \"./alias-resolution\"\nimport { parseScheduleInfo } from \"./analysis-classifiers\"\nimport type { AnalysisContext } from \"./analysis-context\"\nimport { SCHEDULE_OP_MAP } from \"./analysis-patterns\"\nimport { computeDisplayName, computeSemanticRole, extractLocation, generateId, getNodeText } from \"./analysis-utils\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  StaticFlowNode,\n  StaticRetryNode,\n  StaticScheduleNode,\n  StaticTimeoutNode\n} from \"./types\"\n\ntype ScheduleResolution = Pick<StaticRetryNode, \"schedule\" | \"scheduleInfo\"> & {\n  readonly scheduleExpr: Node | undefined\n}\n\n/** Follow const identifiers (`retrySchedule`) to their initializer. */\nconst followConst = (node: Node): Node => {\n  const { SyntaxKind } = loadTsMorph()\n  let current = node\n  for (let hop = 0; hop < 5 && current.getKind() === SyntaxKind.Identifier; hop++) {\n    const symbol = current.getSymbol()\n    const decl = (symbol?.getAliasedSymbol() ?? symbol)\n      ?.getDeclarations()\n      .find((d) => d.getKind() === SyntaxKind.VariableDeclaration) as VariableDeclaration | undefined\n    const init = decl?.getInitializer()\n    if (!init) break\n    current = init\n  }\n  return current\n}\n\n/** Value of `name` in an options object: `{ name: x }` or shorthand `{ name }`. */\nconst optionValue = (obj: ObjectLiteralExpression, name: string): Node | undefined => {\n  const { SyntaxKind } = loadTsMorph()\n  const prop = obj.getProperty(name)\n  if (prop?.getKind() === SyntaxKind.PropertyAssignment) return (prop as PropertyAssignment).getInitializer()\n  if (prop?.getKind() === SyntaxKind.ShorthandPropertyAssignment) {\n    // `{ schedule }`: the name node's symbol is the property itself, so look\n    // up the variable it reads to reach `Schedule.exponential(...)`.\n    const shorthand = prop as ShorthandPropertyAssignment\n    const decl = shorthand.getValueSymbol()\n      ?.getDeclarations()\n      .find((d) => d.getKind() === SyntaxKind.VariableDeclaration) as VariableDeclaration | undefined\n    return decl?.getInitializer() ?? shorthand.getNameNode()\n  }\n  return undefined\n}\n\nconst asOptions = (node: Node | undefined): ObjectLiteralExpression | undefined =>\n  node?.getKind() === loadTsMorph().SyntaxKind.ObjectLiteralExpression\n    ? (node as ObjectLiteralExpression)\n    : undefined\n\n/**\n * Resolve a retry policy (`Effect.retry(policy)`) to its schedule: unwraps\n * `{ schedule, times, while, until }` and follows schedule consts.\n */\nexport const resolveRetryPolicy = (policy: Node | undefined): ScheduleResolution => {\n  if (!policy) return { schedule: undefined, scheduleInfo: undefined, scheduleExpr: undefined }\n  const resolved = followConst(policy)\n  const options = asOptions(resolved)\n  const scheduleArg = options ? optionValue(options, \"schedule\") : resolved\n  const scheduleExpr = scheduleArg ? followConst(scheduleArg) : undefined\n  const scheduleText = (scheduleExpr ?? policy).getText().replace(/\\s+/g, \" \")\n  const times = options ? optionValue(options, \"times\")?.getText() : undefined\n  const info = parseScheduleInfo(times ? `${scheduleText} times: ${times}` : scheduleText)\n  const predicates = options ? [\"while\", \"until\"].filter((name) => options.getProperty(name)) : []\n  return {\n    schedule: scheduleText,\n    scheduleInfo: info && predicates.length > 0\n      ? { ...info, conditions: [...info.conditions, ...predicates] }\n      : info,\n    scheduleExpr\n  }\n}\n\n/**\n * Split a retry/timeout call into the effect it wraps and its policy argument.\n *   effect.retry(policy)        method on an Effect value\n *   Effect.retry(effect, policy) data-first\n *   Effect.retry(policy)        data-last (inside .pipe): the source is the pipe's base\n */\nconst splitPolicyCall = (call: CallExpression, sourceFile: SourceFile) => {\n  const { SyntaxKind } = loadTsMorph()\n  const args = call.getArguments()\n  const expr = call.getExpression()\n  const receiver = expr.getKind() === SyntaxKind.PropertyAccessExpression\n    ? (expr as PropertyAccessExpression).getExpression()\n    : undefined\n  if (receiver && !getAliasesForFile(sourceFile).has(receiver.getText())) {\n    return { source: receiver, policy: args[0], extraArgs: args.length - 1 }\n  }\n  if (args.length >= 2) return { source: args[0], policy: args[1], extraArgs: args.length - 2 }\n  return { source: undefined, policy: args[0], extraArgs: 0 }\n}\n\nconst analyzePolicySource = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  sourceNode: Node | undefined,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<AnalysisWarning>,\n  stats: AnalysisStats\n): Effect.Effect<StaticFlowNode, AnalysisError> =>\n  sourceNode\n    ? deps.analyzeEffectExpression(sourceNode, sourceFile, filePath, opts, warnings, stats)\n    // Same placeholder the error-handler analyzer uses for a data-last call.\n    : Effect.succeed({\n      id: generateId(),\n      type: \"effect\",\n      callee: call.getExpression().getText(),\n      description: \"pipe-input\"\n    })\n\nexport const analyzeRetryCall = (\n  deps: AnalysisContext,\n  call: CallExpression,\n  sourceFile: SourceFile,\n  filePath: string,\n  opts: Required<AnalyzerOptions>,\n  warnings: Array<AnalysisWarning>,\n  stats: AnalysisStats\n): Effect.Effect<StaticRetryNode, AnalysisError> =>\n  Effect.gen(function*() {\n    const split = splitPolicyCall(call, sourceFile)\n    const source = yield* analyzePolicySource(\n      deps,\n      call,\n      split.source,\n      sourceFile,\n      filePath,\n      opts,\n      warnings,\n      stats\n    )\n    const { schedule, scheduleInfo, scheduleExpr } = resolveRetryPolicy(split.policy)\n    const scheduleNode = scheduleExpr\n      ? yield* deps.analyzeEffectExpression(scheduleExpr, sourceFile, filePath, opts, warnings, stats)\n      : undefined\n    const hasFallback = call.getExpression().getText().includes(\"OrElse\") || split.extraArgs > 0\n\n    stats.retryCount++\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: Array<AnalysisWarning>,\n  stats: AnalysisStats\n): Effect.Effect<StaticTimeoutNode, AnalysisError> =>\n  Effect.gen(function*() {\n    const split = splitPolicyCall(call, sourceFile)\n    const source = yield* analyzePolicySource(\n      deps,\n      call,\n      split.source,\n      sourceFile,\n      filePath,\n      opts,\n      warnings,\n      stats\n    )\n    // `timeoutOrElse({ duration, orElse })` carries the duration in an options object.\n    const options = asOptions(split.policy)\n    const durationArg = options ? optionValue(options, \"duration\") : split.policy\n    const duration = durationArg ? getNodeText(followConst(durationArg)) : undefined\n    const calleeText = getNodeText(call.getExpression())\n    const hasFallback = /timeout(?:Fail|To|OrElse)/.test(calleeText) ||\n      (options?.getProperty(\"orElse\") !== undefined) ||\n      split.extraArgs > 0\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\"] = 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 * 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 { ArrowFunction, FunctionExpression, PropertyAccessExpression } from \"ts-morph\"\nimport { BUILT_IN_TYPE_NAMES, KNOWN_EFFECT_NAMESPACES } from \"./analysis-patterns\"\nimport type { StaticEffectNode } from \"./types\"\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","/**\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  ArrowFunction,\n  CallExpression,\n  FunctionExpression,\n  Node,\n  PropertyAccessExpression,\n  SourceFile\n} from \"ts-morph\"\nimport { channelOpCategory, sinkOpCategory } from \"./analysis-classifiers\"\nimport type { AnalysisContext } from \"./analysis-context\"\nimport { getNumericLiteralFromNode } from \"./analysis-patterns\"\nimport { computeDisplayName, computeSemanticRole, extractLocation, generateId } from \"./analysis-utils\"\nimport { buildCallbackSummaryNodes, buildPureCallbackSummaryNodes } from \"./callback-summary\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  AnalysisError,\n  AnalysisStats,\n  AnalysisWarning,\n  AnalyzerOptions,\n  ChannelOperatorInfo,\n  SinkOperatorInfo,\n  StaticChannelNode,\n  StaticFlowNode,\n  StaticSinkNode,\n  StaticStreamNode,\n  StreamOperatorInfo\n} from \"./types\"\n\n/** Classify a Stream operator by name. */\nfunction classifyStreamOperator(op: string): StreamOperatorInfo[\"category\"] {\n  if (op.startsWith(\"run\")) return \"sink\"\n  if (\n    op === \"toQueue\" || op === \"toPubSub\" || op === \"toReadableStream\" || op === \"toAsyncIterable\" || op === \"toChannel\"\n  ) return \"conversion\"\n  if (op.includes(\"pipeThroughChannel\") || op.includes(\"Channel\") || op.includes(\"channel\") || op.includes(\"duplex\")) {\n    return \"channel\"\n  }\n  if (\n    op.includes(\"grouped\") || op.includes(\"sliding\") || op.includes(\"groupBy\") || op.includes(\"aggregate\") ||\n    op.includes(\"window\")\n  ) 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 (\n    op.includes(\"catch\") || op.includes(\"catchTag\") || op.includes(\"orElse\") || op.includes(\"orDie\") ||\n    op.includes(\"retry\")\n  ) return \"error\"\n  if (\n    op.includes(\"filter\") || op.includes(\"take\") || op.includes(\"drop\") || op.includes(\"head\") || op === \"first\" ||\n    op === \"last\"\n  ) return \"filter\"\n  if (\n    op.includes(\"acquireRelease\") || op.includes(\"scoped\") || op.includes(\"ensuring\") || op.includes(\"onDone\") ||\n    op.includes(\"onError\")\n  ) return \"resource\"\n  if (op.includes(\"provide\") || op.includes(\"withSpan\") || op.includes(\"annotate\")) return \"context\"\n  if (\n    op.includes(\"map\") || op.includes(\"tap\") || op.includes(\"flatMap\") || op.includes(\"mapChunk\") ||\n    op.includes(\"scan\") || op.includes(\"transduce\")\n  ) return \"transform\"\n  return \"other\"\n}\n\n/** Classify a Stream.* constructor (Stream.make, Stream.tick, ...). */\nfunction classifyStreamConstructor(\n  callee: string,\n  opName: string\n): StaticStreamNode[\"constructorType\"] {\n  let constructorType: StaticStreamNode[\"constructorType\"]\n  if (callee.startsWith(\"Stream.\")) {\n    if (opName === \"fromIterable\" || opName === \"fromChunk\" || opName === \"fromChunkQueue\") {\n      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\") {\n      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 (\n      opName === \"unfold\" || opName === \"unfoldEffect\" || opName === \"unfoldChunk\" || opName === \"unfoldChunkEffect\"\n    ) 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\") {\n      constructorType = \"fail\"\n    }\n  }\n  return constructorType\n}\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: Array<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 = analyzedBase.type === \"stream\" ? analyzedBase.source : analyzedBase\n      const pipeline = analyzedBase.type === \"stream\" ? [...analyzedBase.pipeline] : []\n      let sink = analyzedBase.type === \"stream\" ? analyzedBase.sink : undefined\n      let backpressureStrategy = analyzedBase.type === \"stream\"\n        ? analyzedBase.backpressureStrategy\n        : undefined\n      let constructorType = 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        // A bare operator reference such as `.pipe(Stream.runDrain)` has no\n        // call expression, so record it here.\n        const bareOp = /^Stream\\.(\\w+)$/.exec(arg.getText())?.[1]\n        if (analyzed.type !== \"stream\" && bareOp) {\n          const category = classifyStreamOperator(bareOp)\n          pipeline.push({\n            operation: bareOp,\n            isEffectful: bareOp.includes(\"Effect\") || bareOp.startsWith(\"run\") || bareOp.includes(\"tap\"),\n            estimatedCardinality: category === \"sink\" ? \"fewer\" : \"unknown\",\n            category\n          })\n          if (!sink && bareOp.startsWith(\"run\")) sink = bareOp\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    const opName = callee.replace(/^Stream\\./, \"\") || \"unknown\"\n    const constructorType = classifyStreamConstructor(callee, opName)\n    const isStreamArg = (arg: Node) =>\n      arg.getKind() !== SyntaxKind.ArrowFunction &&\n      arg.getKind() !== SyntaxKind.FunctionExpression &&\n      arg.getKind() !== SyntaxKind.ObjectLiteralExpression\n    const streamArgs = args.filter(isStreamArg)\n    // A data-last call (`Stream.merge(b)` inside .pipe) returns a function and\n    // gets its upstream from the pipe. Data-first `Stream.merge(a, b)` takes\n    // `a` as upstream. Either way the remaining stream arguments are branches.\n    const dataLast = call.getType().getCallSignatures().length > 0\n    const isMerge = constructorType === undefined &&\n      classifyStreamOperator(opName) === \"merge\" &&\n      streamArgs.length >= (dataLast ? 1 : 2)\n    const branchArgs = isMerge ? streamArgs.slice(dataLast ? 0 : 1) : []\n    const branches: Array<StaticFlowNode> = []\n    for (const arg of branchArgs) {\n      branches.push(\n        yield* deps.analyzeEffectExpression(arg, sourceFile, filePath, opts, warnings, stats, serviceScope)\n      )\n    }\n\n    let source: StaticFlowNode\n    const valueConstructor = constructorType === \"make\" || constructorType === \"range\" || constructorType === \"tick\" ||\n      constructorType === \"empty\" || constructorType === \"never\" || constructorType === \"succeed\" ||\n      constructorType === \"fromIterable\" || constructorType === \"fromArray\" ||\n      constructorType === \"iterate\" || constructorType === \"unfold\"\n    if (valueConstructor || (isMerge && dataLast)) {\n      // Stream.make('a', 'b'), Stream.tick(...): the arguments are values,\n      // not Effects, so there is no upstream to analyze.\n      source = {\n        id: generateId(),\n        type: \"opaque\",\n        reason: \"stream-constructor\",\n        sourceText: call.getText().slice(0, 100),\n        location: extractLocation(call, filePath, opts.includeLocations ?? false)\n      }\n    } else 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\n    const isEffectful = 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 = constructorType !== undefined ? \"constructor\" : classifyStreamOperator(opName)\n    const cardinality: StreamOperatorInfo[\"estimatedCardinality\"] = opCategory === \"filter\" ?\n      \"fewer\" :\n      opCategory === \"merge\" ?\n      \"more\" :\n      opCategory === \"broadcasting\" ?\n      \"more\" :\n      opCategory === \"halting\" ?\n      \"fewer\" :\n      opCategory === \"sink\" ?\n      \"fewer\" :\n      opCategory === \"windowing\" ?\n      \"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 = 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      ...(branches.length > 0 ? { branches } : {}),\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: Array<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: Array<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: Array<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: Array<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: Array<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 * Effect program discovery: find Effect.gen, pipe, run, class, and class-member programs.\n */\n\nimport type {\n  ArrowFunction,\n  AwaitExpression,\n  CallExpression,\n  ClassDeclaration,\n  ExpressionStatement,\n  FunctionDeclaration,\n  FunctionExpression,\n  GetAccessorDeclaration,\n  Identifier,\n  MethodDeclaration,\n  Node,\n  ObjectLiteralExpression,\n  PropertyAccessExpression,\n  PropertyAssignment,\n  PropertyDeclaration,\n  ReturnStatement,\n  SourceFile,\n  TypeNode,\n  VariableDeclaration\n} from \"ts-morph\"\nimport { extractEnclosingEffectFnName, extractProgramName } from \"./analysis-utils\"\nimport type { EffectProgram } from \"./analysis-utils\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type { AnalyzerOptions, ServiceDefinition } from \"./types\"\n\nexport type { EffectProgram } from \"./analysis-utils\"\nimport {\n  getEffectLikeNamespaceAliases,\n  getNonProgramEffectImportNames,\n  isEffectLikeCallExpression,\n  isSpecifierUnderKnownEffectInternalsRoot\n} from \"./alias-resolution\"\nimport { isLikelyDirectEffectInitializer } from \"./analysis-patterns\"\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    n.startsWith(\".\") &&\n    (n.endsWith(\"Workflow.js\") || n.endsWith(\"Workflow.ts\") || n.endsWith(\"Activity.js\") || n.endsWith(\"Activity.ts\"))\n  ) 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: ReadonlyArray<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): ReadonlyArray<EffectProgram> => {\n  const programs: Array<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          | ArrowFunction\n          | 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: ReadonlyArray<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 = expression as PropertyAccessExpression\n      const objectText = propertyAccess.getExpression().getText()\n      const methodName = propertyAccess.getName()\n      isWorkflowInvocation = 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 = 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 = (methodName === \"execute\" || methodName === \"executeEncoded\") &&\n        workflowProgramBuilders.has(objectText) &&\n        !seenCallStarts.has(callStart)\n      if (isExecuteEntrypoint) {\n        const name = 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 (\n      (exprText === \"gen\" ||\n        (exprText.endsWith(\".gen\") &&\n          isEffectLikeCallExpression(call, sourceFile, effectImportNames, _opts.knownEffectInternalsRoot))) &&\n      !seenCallStarts.has(callStart)\n    ) {\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 = 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  // Error classes (Data.TaggedError, Data.Error, Schema.TaggedError) are\n  // types, not programs, so they are deliberately absent.\n  const DATA_SCHEMA_CLASS_PATTERNS = [\n    \"Data.TaggedClass\",\n    \"Data.Class\",\n    \"Schema.Class\",\n    \"Schema.TaggedClass\",\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 Array<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 Array<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 Array<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) => [...effectImportNames].some((alias) => text.includes(`${alias}.`)))\n}\n\n// =============================================================================\n// Service definitions\n// =============================================================================\n\nexport function extractServiceDefinitionsFromFile(sourceFile: SourceFile): Array<ServiceDefinition> {\n  const { SyntaxKind } = loadTsMorph()\n  const results: Array<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 (\n      !extText.includes(\"Context.Service\") && !extText.includes(\"Context.Tag\") && !extText.includes(\"Effect.Service\")\n    ) continue\n    let typeArgs: ReadonlyArray<TypeNode> = extExpr.getTypeArguments()\n    if (typeArgs.length < 2) {\n      const inner = extExpr.getExpression()\n      if (\n        inner && \"getTypeArguments\" in inner &&\n        typeof (inner as { getTypeArguments: () => Array<unknown> }).getTypeArguments === \"function\"\n      ) {\n        typeArgs = (inner as { getTypeArguments: () => ReadonlyArray<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: Array<string> = []\n      const properties: Array<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\") ||\n        classText.includes(\"equal(\")\n      const hasCustomHash = classText.includes(\"Hash.symbol\") || classText.includes(\"[Hash\") ||\n        classText.includes(\"hash(\")\n      results.push({\n        tagId: name,\n        methods,\n        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\") ||\n      classText.includes(\"equal(\")\n    const hasCustomHash = classText.includes(\"Hash.symbol\") || classText.includes(\"[Hash\") ||\n      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 * Project-wide / Cross-file Analysis (GAP 17)\n *\n * Analyzes a directory of TypeScript files and aggregates results.\n */\n\nimport { Effect } from \"effect\"\nimport { readFileSync } from \"fs\"\nimport { readdir, readFile, stat } from \"fs/promises\"\nimport { basename, extname, join, resolve } from \"path\"\nimport { assessAudit, type AuditAssessment } from \"./audit-assessment\"\nimport { assessIRFidelity, type FidelityFinding } from \"./fidelity-findings\"\nimport { extractProjectArchitecture, type ProjectArchitectureSummary } from \"./project-architecture\"\nimport { type ProjectCorpus, scanProjectCorpus } from \"./project-corpus\"\nimport { buildProjectServiceMap } from \"./service-registry\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type { ProjectServiceMap, StaticEffectIR } from \"./types\"\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/** Per-file failure for project analysis (Gap 3: no silent drops). */\nexport interface ProjectFileFailure {\n  readonly file: string\n  readonly error: string\n}\n\nexport interface ProjectAnalysisResult {\n  /** File path -> list of program IRs in that file */\n  readonly byFile: Map<string, ReadonlyArray<StaticEffectIR>>\n  /** All programs across the project */\n  readonly allPrograms: ReadonlyArray<StaticEffectIR>\n  /** Entry points (files that run Effect.runPromise / runSync / NodeRuntime.runMain) - heuristic + package.json */\n  readonly entryPointFiles: Array<string>\n  /** Total file count discovered */\n  readonly fileCount: number\n  /** Files that failed to analyze (error message included) - Gap 3 */\n  readonly failedFiles: ReadonlyArray<ProjectFileFailure>\n  /** Files that were analyzed but had zero Effect programs */\n  readonly zeroProgramFiles: ReadonlyArray<string>\n  /** Project-level deduplicated service map (when --service-map is enabled) */\n  readonly serviceMap?: ProjectServiceMap | undefined\n  /** Project-level runtime architecture summary (when enabled). */\n  readonly architecture?: ProjectArchitectureSummary | undefined\n}\n\nexport interface AnalyzeProjectOptions {\n  readonly tsconfig?: string | undefined\n  /** File extensions to discover; default ['.ts', '.tsx']. Include '.js'/.jsx' for best-effort JS (Gap 6). */\n  readonly extensions?: ReadonlyArray<string> | undefined\n  readonly maxDepth?: number | undefined\n  /** When true, include per-file durationMs in outcomes (improve.md §7 optional timing). */\n  readonly includePerFileTiming?: boolean | undefined\n  /** Optional false-positive review: paths matching any of these (substring or path segment) are excluded from suspiciousZeros (improve.md §5). */\n  readonly excludeFromSuspiciousZeros?: ReadonlyArray<string> | undefined\n  /** Optional path to known Effect internals root for per-file analysis (improve.md §1). */\n  readonly knownEffectInternalsRoot?: string | undefined\n  /** When true, build the deduplicated project-level service map (--service-map). */\n  readonly buildServiceMap?: boolean | undefined\n  /** When true, build a project-level runtime architecture summary. */\n  readonly buildArchitecture?: boolean | undefined\n}\n\n/** Per-file outcome for coverage audit. */\nexport interface FileOutcome {\n  readonly file: string\n  readonly status: \"ok\" | \"fail\" | \"zero\"\n  readonly programCount?: number\n  readonly error?: string\n  /** When includePerFileTiming: analysis time in ms (improve.md §7). */\n  readonly durationMs?: number\n}\n\nexport type ZeroProgramCategory =\n  | \"barrel_or_index\"\n  | \"config_or_build\"\n  | \"test_or_dtslint\"\n  | \"type_only\"\n  | \"suspicious\"\n  | \"other\"\n\nexport interface ZeroProgramClassification {\n  readonly file: string\n  readonly category: ZeroProgramCategory\n  readonly importsEffect: boolean\n}\n\nexport interface ProjectFidelityFinding extends FidelityFinding {\n  readonly file: string\n  readonly programName: string\n}\n\n/** Coverage audit: discovered vs analyzed vs failed/zero, with per-file outcomes. */\nexport interface CoverageAuditResult {\n  readonly discovered: number\n  readonly analyzed: number\n  readonly zeroPrograms: number\n  readonly failed: number\n  readonly outcomes: ReadonlyArray<FileOutcome>\n  readonly assessment: AuditAssessment\n  /** unknownCount / totalNodes across all analyzed files (0–1). */\n  readonly unknownNodeRate: number\n  /** Repo-level aggregate: total node count across all analyzed programs (improve.md §5). */\n  readonly totalNodes: number\n  /** Repo-level aggregate: unknown node count across all analyzed programs (improve.md §5). */\n  readonly unknownNodes: number\n  /** Located fidelity evidence across every analyzed program. */\n  readonly fidelityFindings: ReadonlyArray<ProjectFidelityFinding>\n  /** Files that import from effect/@effect but produced zero programs. */\n  readonly suspiciousZeros: ReadonlyArray<string>\n  /** Per-category zero-program counts for triage. */\n  readonly zeroProgramCategoryCounts: Readonly<Record<ZeroProgramCategory, number>>\n  /** Per-file category for zero-program outcomes. */\n  readonly zeroProgramClassifications: ReadonlyArray<ZeroProgramClassification>\n  /** Top N files by unknown node rate (highest first), for --show-top-unknown. */\n  readonly topUnknownFiles?: ReadonlyArray<string>\n  /** Unknown node counts by reason. */\n  readonly unknownReasonCounts?: Readonly<Record<string, number>>\n  /** Top unknown reasons by count (highest first), for --show-top-unknown-reasons. */\n  readonly topUnknownReasons?: ReadonlyArray<{ reason: string; count: number }>\n  /** Audit execution time in ms (improve.md §7 performance validation). */\n  readonly durationMs?: number\n}\n\nconst DEFAULT_OPTIONS: Required<Omit<AnalyzeProjectOptions, \"tsconfig\">> = {\n  extensions: [\".ts\", \".tsx\"],\n  maxDepth: 10,\n  knownEffectInternalsRoot: undefined,\n  includePerFileTiming: false,\n  excludeFromSuspiciousZeros: [],\n  buildServiceMap: false,\n  buildArchitecture: false\n}\n\n/** Modules from `effect` that do NOT produce Effect programs on their own. */\nconst NON_PROGRAM_EFFECT_MODULES = new Set([\n  \"Option\",\n  \"Either\",\n  \"Predicate\",\n  \"Order\",\n  \"Equivalence\",\n  \"Hash\",\n  \"Equal\",\n  \"Inspectable\",\n  \"Pipeable\",\n  \"Types\",\n  \"Brand\",\n  \"Chunk\",\n  \"HashMap\",\n  \"HashSet\",\n  \"List\",\n  \"SortedMap\",\n  \"SortedSet\",\n  \"Duration\",\n  \"DateTime\",\n  \"BigInt\",\n  \"BigDecimal\",\n  \"Number\",\n  \"String\",\n  \"Struct\",\n  \"Tuple\",\n  \"ReadonlyArray\",\n  \"Array\",\n  \"Record\",\n  \"Schema\",\n  \"ServiceMap\",\n  \"Data\",\n  \"Match\",\n  \"Function\"\n])\n\nfunction fileImportsEffect(filePath: string): boolean {\n  try {\n    const content = readFileSync(filePath, \"utf-8\")\n    if (!/from\\s+[\"'](?:effect|effect\\/|@effect\\/)/.test(content)) return false\n\n    // Check if all runtime (non-type) named imports from \"effect\" are non-program modules\n    // `import type { ... }` lines are always safe (type-only, no runtime behavior)\n    const runtimeImportMatches = content.matchAll(/import\\s+{([^}]+)}\\s+from\\s+[\"']effect[\"']/g)\n    let hasAnyRuntimeImport = false\n    let allNonProgram = true\n    for (const match of runtimeImportMatches) {\n      // Skip if this is actually an `import type` statement (the regex above won't match `import type {`)\n      // But we need to check for inline `type` specifiers like `import { type Effect, Schema } from \"effect\"`\n      const names = match[1]!.split(\",\")\n        .map((s) => s.trim())\n        .filter((s) => !s.startsWith(\"type \")) // skip inline type imports\n        .map((s) => s.split(/\\s+as\\s+/)[0]!.trim())\n        .filter(Boolean)\n      for (const name of names) {\n        hasAnyRuntimeImport = true\n        if (!NON_PROGRAM_EFFECT_MODULES.has(name)) {\n          allNonProgram = false\n          break\n        }\n      }\n      if (!allNonProgram) break\n    }\n\n    if (hasAnyRuntimeImport && allNonProgram) return false\n\n    // Check for namespace imports: import * as X from \"effect\" or \"effect/...\"\n    const hasNamespaceImport = /import\\s+\\*\\s+as\\s+\\w+\\s+from\\s+[\"'](?:effect|effect\\/|@effect\\/)/.test(content)\n    if (hasNamespaceImport) return true\n\n    // Check for named/namespace imports from effect submodules (e.g. \"effect/Effect\", \"@effect/...\")\n    // These weren't caught by the exact \"effect\" regex above\n    const hasSubmoduleImport = /import\\s+{[^}]+}\\s+from\\s+[\"'](?:effect\\/|@effect\\/)/.test(content)\n    if (hasSubmoduleImport) return true\n\n    // If only `import type` statements exist (no runtime imports at all), not suspicious\n    if (!hasAnyRuntimeImport) return false\n\n    return true\n  } catch {\n    return false\n  }\n}\n\nfunction isTypeOnlyZeroCandidate(filePath: string): boolean {\n  try {\n    const content = readFileSync(filePath, \"utf-8\")\n    const hasRuntimeLikeEffectUsage = /\\bEffect\\./.test(content) ||\n      /\\bLayer\\./.test(content) ||\n      /\\bStream\\./.test(content) ||\n      /\\bSchema\\./.test(content) ||\n      /\\byield\\*/.test(content) ||\n      /\\bpipe\\(/.test(content) ||\n      /\\brunPromise\\b/.test(content) ||\n      /\\brunSync\\b/.test(content) ||\n      /\\brunFork\\b/.test(content) ||\n      /\\bacquireRelease\\b/.test(content)\n    if (hasRuntimeLikeEffectUsage) return false\n\n    return (\n      /\\binterface\\b/.test(content) ||\n      /\\btype\\b/.test(content) ||\n      /\\bdeclare\\b/.test(content) ||\n      /^\\s*import\\s+type\\b/m.test(content) ||\n      /^\\s*export\\s+type\\b/m.test(content)\n    )\n  } catch {\n    return false\n  }\n}\n\nfunction isLightweightEffectAdapterFile(filePath: string): boolean {\n  try {\n    const content = readFileSync(filePath, \"utf-8\")\n    const hasProgramLikeUsage = /\\byield\\*/.test(content) ||\n      /\\bEffect\\.gen\\b/.test(content) ||\n      /\\bpipe\\(/.test(content) ||\n      /\\bEffect\\.run(?:Promise|Sync|Fork|Callback)\\b/.test(content) ||\n      /\\bacquireRelease\\b/.test(content) ||\n      /\\bLayer\\.(?:effect|scoped|merge|provide)\\b/.test(content)\n    if (hasProgramLikeUsage) return false\n\n    const effectConstructorMentions = content.match(/\\bEffect\\.(?:void|succeed|fail|sync|try|promise|async)\\b/g) ?? []\n    if (effectConstructorMentions.length === 0) return false\n\n    const callbackPropertyMentions = content.match(/(?:readonly\\s+)?[A-Za-z0-9_]+\\s*:\\s*\\([^)]*\\)\\s*=>/g) ?? []\n\n    return callbackPropertyMentions.length > 0\n  } catch {\n    return false\n  }\n}\n\nfunction detectExpectedZeroCategory(\n  filePath: string\n): Exclude<ZeroProgramCategory, \"suspicious\" | \"other\"> | undefined {\n  const normalized = filePath.replace(/\\\\/g, \"/\")\n  const base = basename(normalized).toLowerCase()\n\n  if (base === \"index.ts\" || base === \"index.tsx\" || /\\/index\\.[jt]sx?$/.test(normalized)) {\n    return \"barrel_or_index\"\n  }\n\n  if (\n    /(^|\\/)(__tests__|test|tests|dtslint)(\\/|$)/.test(normalized) ||\n    /\\.(test|spec|tst)\\.[jt]sx?$/.test(normalized)\n  ) {\n    return \"test_or_dtslint\"\n  }\n\n  if (\n    /(^|\\/)(vitest|vite|jest|webpack|rollup|tsup|esbuild|eslint|prettier|babel|playwright|typedoc|karma)\\.config\\.[jt]s$/\n      .test(normalized) ||\n    /(^|\\/)vitest\\.workspace\\.[jt]s$/.test(normalized)\n  ) {\n    return \"config_or_build\"\n  }\n\n  if (isTypeOnlyZeroCandidate(filePath)) {\n    return \"type_only\"\n  }\n\n  return undefined\n}\n// =============================================================================\n// Entry points from package.json (Gap 4: semantic entry-point detection)\n// =============================================================================\n\nasync function findPackageJsonDirs(\n  dir: string,\n  maxDepth: number,\n  currentDepth: number\n): Promise<Array<string>> {\n  if (currentDepth >= maxDepth) return []\n  const result: Array<string> = []\n  try {\n    const entries = await readdir(dir, { withFileTypes: true })\n    const hasPkg = entries.some((e) => e.isFile() && e.name === \"package.json\")\n    if (hasPkg) result.push(dir)\n    for (const ent of entries) {\n      if (ent.isDirectory() && ent.name !== \"node_modules\" && ent.name !== \".git\") {\n        result.push(\n          ...(await findPackageJsonDirs(join(dir, ent.name), maxDepth, currentDepth + 1))\n        )\n      }\n    }\n  } catch {\n    // ignore\n  }\n  return result\n}\n\nfunction resolveEntry(\n  pkgDir: string,\n  entry: string | undefined,\n  extensions: ReadonlyArray<string>\n): Array<string> {\n  if (!entry || typeof entry !== \"string\") return []\n  const normalized = entry.replace(/^\\.\\//, \"\")\n  const base = join(pkgDir, normalized)\n  const ext = extname(normalized)\n  if (ext) {\n    return [resolve(base)]\n  }\n  return extensions.map((e) => resolve(base + e))\n}\n\n/** Gap 4: Detect files that have Effect.runPromise / runSync / NodeRuntime.runMain at top level. */\nasync function fileHasTopLevelRunCall(filePath: string): Promise<boolean> {\n  try {\n    const { Project, SyntaxKind } = loadTsMorph()\n    const project = new Project({ skipAddingFilesFromTsConfig: true })\n    const sourceFile = project.addSourceFileAtPath(filePath)\n    const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)\n    const functionKinds = [\n      SyntaxKind.FunctionDeclaration,\n      SyntaxKind.FunctionExpression,\n      SyntaxKind.ArrowFunction,\n      SyntaxKind.MethodDeclaration\n    ]\n    for (const call of callExpressions) {\n      const parent = call.getParent()\n      if (parent?.getKind() !== SyntaxKind.ExpressionStatement) continue\n      let current: ReturnType<typeof parent.getParent> = parent\n      while (current) {\n        const kind = current.getKind()\n        if (kind === SyntaxKind.SourceFile) break\n        if (functionKinds.includes(kind)) break\n        current = current.getParent()\n      }\n      if (current?.getKind() !== SyntaxKind.SourceFile) continue\n      const exprText = call.getExpression().getText()\n      if (\n        exprText.includes(\".runPromise\") ||\n        exprText.includes(\".runSync\") ||\n        exprText.includes(\".runFork\") ||\n        exprText.includes(\".runCallback\") ||\n        exprText.includes(\"NodeRuntime.runMain\") ||\n        exprText.includes(\"BunRuntime.runMain\") ||\n        exprText.includes(\"DenoRuntime.runMain\") ||\n        exprText.includes(\"Runtime.runPromise\") ||\n        exprText.includes(\"Runtime.runSync\") ||\n        exprText.includes(\"Runtime.runFork\")\n      ) {\n        return true\n      }\n    }\n  } catch {\n    // ignore parse errors\n  }\n  return false\n}\n\nasync function getEntryPointsFromPackageJson(\n  dirPath: string,\n  extensions: ReadonlyArray<string>\n): Promise<Array<string>> {\n  const pkgDirs = await findPackageJsonDirs(dirPath, 10, 0)\n  const entryPaths: Array<string> = []\n  for (const pkgDir of pkgDirs) {\n    try {\n      const raw = await readFile(join(pkgDir, \"package.json\"), \"utf-8\")\n      const pkg = JSON.parse(raw) as { main?: string; module?: string; bin?: string | Record<string, string> }\n      const dirs = [resolveEntry(pkgDir, pkg.main, extensions), resolveEntry(pkgDir, pkg.module, extensions)]\n      if (typeof pkg.bin === \"string\") dirs.push(resolveEntry(pkgDir, pkg.bin, extensions))\n      else if (pkg.bin && typeof pkg.bin === \"object\") {\n        for (const v of Object.values(pkg.bin)) {\n          dirs.push(resolveEntry(pkgDir, typeof v === \"string\" ? v : undefined, extensions))\n        }\n      }\n      for (const list of dirs) {\n        for (const p of list) {\n          try {\n            const s = await stat(p).catch(() => null)\n            if (s?.isFile()) entryPaths.push(p)\n          } catch {\n            // skip\n          }\n        }\n      }\n    } catch {\n      // skip invalid or missing package.json\n    }\n  }\n  return [...new Set(entryPaths)]\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\n/**\n * Analyze all TypeScript files in a directory and return aggregated IRs.\n */\nexport function analyzeProjectCorpus(\n  corpus: ProjectCorpus,\n  options: AnalyzeProjectOptions = {}\n): Effect.Effect<ProjectAnalysisResult> {\n  const dirPath = corpus.root\n  const extensions = (options.extensions ?? DEFAULT_OPTIONS.extensions)!\n  return Effect.gen(function*() {\n    const files = corpus.files.map((entry) => entry.file)\n    const byFile = new Map<string, ReadonlyArray<StaticEffectIR>>()\n    const allPrograms: Array<StaticEffectIR> = []\n    const entryPointFiles: Array<string> = []\n    const failedFiles: Array<ProjectFileFailure> = []\n    const zeroProgramFiles: Array<string> = []\n\n    for (const entry of corpus.files) {\n      const file = entry.file\n      if (entry.status === \"fail\") {\n        failedFiles.push({ file, error: entry.error ?? \"Unknown analysis failure\" })\n        continue\n      }\n      if (entry.status === \"zero\") {\n        zeroProgramFiles.push(file)\n        continue\n      }\n      const programs = entry.programs\n      byFile.set(file, programs)\n      allPrograms.push(...programs)\n      for (const ir of programs) {\n        const nameLikeEntry = ir.root.programName === \"main\" || ir.root.programName.includes(\"run\")\n        const isRunCall = ir.root.source === \"run\"\n        if (nameLikeEntry || isRunCall) {\n          if (!entryPointFiles.includes(file)) entryPointFiles.push(file)\n        }\n      }\n    }\n\n    const packageEntryPaths = yield* Effect.promise(() => getEntryPointsFromPackageJson(dirPath, extensions))\n    for (const p of packageEntryPaths) {\n      if (files.includes(p) && !entryPointFiles.includes(p)) {\n        entryPointFiles.push(p)\n      }\n    }\n\n    for (const file of byFile.keys()) {\n      if (entryPointFiles.includes(file)) continue\n      const hasRun = yield* Effect.promise(() => fileHasTopLevelRunCall(file))\n      if (hasRun) entryPointFiles.push(file)\n    }\n\n    // Optionally build the deduplicated service map\n    let serviceMap: ProjectServiceMap | undefined\n    if (options.buildServiceMap) {\n      serviceMap = yield* Effect.try(() => {\n        const { Project } = loadTsMorph()\n        const project = new Project({\n          skipAddingFilesFromTsConfig: true,\n          compilerOptions: { allowJs: true }\n        })\n        // oxlint-disable-next-line typescript/no-explicit-any\n        const sourceFileMap = new Map<string, any>()\n        for (const file of byFile.keys()) {\n          // Files that cannot be loaded are skipped, not fatal. This stays a\n          // plain try/catch: it guards one synchronous ts-morph call inside an\n          // already-suspended Effect.try, so lifting it would only add a nested\n          // runtime.\n          try {\n            sourceFileMap.set(file, project.addSourceFileAtPath(file))\n          } catch {\n            continue\n          }\n        }\n        return buildProjectServiceMap(byFile, sourceFileMap)\n      }).pipe(\n        // Fall back to IR-only service map (no AST-level extraction)\n        Effect.orElseSucceed(() => buildProjectServiceMap(byFile))\n      )\n    }\n\n    const architecture = options.buildArchitecture\n      ? extractProjectArchitecture(files, { tsconfig: options.tsconfig })\n      : undefined\n\n    return {\n      byFile,\n      allPrograms,\n      entryPointFiles,\n      fileCount: files.length,\n      failedFiles,\n      zeroProgramFiles,\n      serviceMap,\n      architecture\n    }\n  })\n}\n\nexport function analyzeProject(\n  dirPath: string,\n  options: AnalyzeProjectOptions = {}\n): Effect.Effect<ProjectAnalysisResult> {\n  const extensions = options.extensions ?? DEFAULT_OPTIONS.extensions\n  const maxDepth = options.maxDepth ?? DEFAULT_OPTIONS.maxDepth\n  return scanProjectCorpus(dirPath, {\n    extensions,\n    maxDepth,\n    tsconfig: options.tsconfig,\n    knownEffectInternalsRoot: options.knownEffectInternalsRoot\n  }).pipe(\n    Effect.flatMap((corpus) => analyzeProjectCorpus(corpus, options))\n  )\n}\n\n// =============================================================================\n// Coverage audit (missing-gaps: discovered vs analyzed, failed/skipped list)\n// =============================================================================\n\n/**\n * Run a coverage audit over a directory: discover all .ts/.tsx files, analyze each,\n * and return counts plus per-file outcomes (ok / zero programs / failed with reason).\n * Does not swallow failures; every file gets an outcome.\n */\nexport function runCoverageAudit(\n  dirPath: string,\n  options: AnalyzeProjectOptions = {}\n): Effect.Effect<CoverageAuditResult> {\n  return scanProjectCorpus(dirPath, {\n    extensions: options.extensions ?? DEFAULT_OPTIONS.extensions,\n    maxDepth: options.maxDepth ?? DEFAULT_OPTIONS.maxDepth,\n    tsconfig: options.tsconfig,\n    includePerFileTiming: options.includePerFileTiming,\n    knownEffectInternalsRoot: options.knownEffectInternalsRoot\n  }).pipe(\n    Effect.flatMap((corpus) => runCoverageAuditFromCorpus(corpus, options))\n  )\n}\n\nexport function runCoverageAuditFromCorpus(\n  corpus: ProjectCorpus,\n  options: AnalyzeProjectOptions = {}\n): Effect.Effect<CoverageAuditResult> {\n  return Effect.sync(() => {\n    const outcomes: Array<FileOutcome> = []\n    let totalNodes = 0\n    let unknownNodes = 0\n    let sourceUnresolvedNodes = 0\n    const fidelityFindings: Array<ProjectFidelityFinding> = []\n    const fileUnknownRates: Array<{ file: string; total: number; unknown: number }> = []\n    const unknownReasonsCorpus = new Map<string, number>()\n\n    for (const entry of corpus.files) {\n      const file = entry.file\n      const durationMs = entry.durationMs\n      if (entry.status !== \"fail\") {\n        const count = entry.programs.length\n        let fileTotal = 0\n        let fileUnknown = 0\n        for (const ir of entry.programs) {\n          const fidelity = assessIRFidelity(ir)\n          const unknownFindings = fidelity.findings.filter(\n            (finding) => finding.kind === \"unknown-node\"\n          )\n          totalNodes += fidelity.sourceRepresentation.total\n          unknownNodes += unknownFindings.length\n          sourceUnresolvedNodes += fidelity.sourceRepresentation.total - fidelity.sourceRepresentation.resolved\n          fileTotal += fidelity.sourceRepresentation.total\n          fileUnknown += unknownFindings.length\n          for (const finding of fidelity.findings) {\n            fidelityFindings.push({\n              ...finding,\n              file,\n              programName: ir.root.programName\n            })\n            if (finding.kind === \"unknown-node\") {\n              const reason = finding.reason ?? \"Unknown reason\"\n              unknownReasonsCorpus.set(reason, (unknownReasonsCorpus.get(reason) ?? 0) + 1)\n            }\n          }\n        }\n        if (fileTotal > 0) {\n          fileUnknownRates.push({ file, total: fileTotal, unknown: fileUnknown })\n        }\n        outcomes.push(\n          count > 0\n            ? { file, status: \"ok\", programCount: count, ...(durationMs !== undefined ? { durationMs } : {}) }\n            : { file, status: \"zero\", programCount: 0, ...(durationMs !== undefined ? { durationMs } : {}) }\n        )\n      } else {\n        outcomes.push({\n          file,\n          status: \"fail\",\n          ...(entry.error === undefined ? {} : { error: entry.error }),\n          ...(durationMs !== undefined ? { durationMs } : {})\n        })\n      }\n    }\n\n    const discovered = corpus.files.length\n    const analyzed = outcomes.filter((o) => o.status === \"ok\").length\n    const zeroPrograms = outcomes.filter((o) => o.status === \"zero\").length\n    const failed = outcomes.filter((o) => o.status === \"fail\").length\n    const excludePatterns = options.excludeFromSuspiciousZeros ?? []\n    const isExcludedFromSuspicious = (filePath: string): boolean => {\n      const normalized = filePath.replace(/\\\\/g, \"/\")\n      return excludePatterns.some(\n        (p) => normalized.includes(p.replace(/\\\\/g, \"/\")) || normalized.endsWith(p.replace(/\\\\/g, \"/\"))\n      )\n    }\n    const zeroProgramCategoryCounts: Record<ZeroProgramCategory, number> = {\n      barrel_or_index: 0,\n      config_or_build: 0,\n      test_or_dtslint: 0,\n      type_only: 0,\n      suspicious: 0,\n      other: 0\n    }\n    const suspiciousZeros: Array<string> = []\n    const zeroProgramClassifications: Array<ZeroProgramClassification> = []\n\n    const zeroOutcomes = outcomes.filter((o) => o.status === \"zero\")\n    for (const o of zeroOutcomes) {\n      const importsEffect = fileImportsEffect(o.file)\n      const expectedCategory = detectExpectedZeroCategory(o.file)\n      const category: ZeroProgramCategory = importsEffect &&\n          !isExcludedFromSuspicious(o.file) &&\n          expectedCategory === undefined &&\n          !isLightweightEffectAdapterFile(o.file)\n        ? \"suspicious\"\n        : (expectedCategory ?? \"other\")\n\n      zeroProgramCategoryCounts[category]++\n      zeroProgramClassifications.push({ file: o.file, category, importsEffect })\n      if (category === \"suspicious\") suspiciousZeros.push(o.file)\n    }\n    const unknownNodeRate = totalNodes > 0 ? unknownNodes / totalNodes : 0\n    const assessment = assessAudit({\n      discoveredFiles: discovered,\n      effectFiles: analyzed,\n      failedFiles: failed,\n      totalNodes,\n      unresolvedNodes: sourceUnresolvedNodes\n    })\n    const topUnknownFiles = fileUnknownRates\n      .filter((f) => f.total > 0)\n      .sort((a, b) => (b.unknown / b.total) - (a.unknown / a.total))\n      .slice(0, 10)\n      .map((f) => f.file)\n\n    const unknownReasonCounts: Record<string, number> = {}\n    for (const [reason, n] of unknownReasonsCorpus) unknownReasonCounts[reason] = n\n    const topUnknownReasons = [...unknownReasonsCorpus.entries()]\n      .sort((a, b) => b[1] - a[1])\n      .slice(0, 20)\n      .map(([reason, count]) => ({ reason, count }))\n\n    const durationMs = corpus.durationMs\n    return {\n      discovered,\n      analyzed,\n      zeroPrograms,\n      failed,\n      outcomes,\n      assessment,\n      unknownNodeRate,\n      totalNodes,\n      unknownNodes,\n      fidelityFindings,\n      suspiciousZeros,\n      zeroProgramCategoryCounts,\n      zeroProgramClassifications,\n      topUnknownFiles,\n      unknownReasonCounts,\n      topUnknownReasons,\n      durationMs\n    }\n  })\n}\n","/** Unambiguous measurements for a project coverage audit. */\n\nexport interface AuditDimension {\n  readonly numerator: number\n  readonly denominator: number\n  readonly rate: number\n}\n\nexport interface AuditAssessment {\n  /** Files containing at least one Effect program / all discovered files. */\n  readonly effectAdoption: AuditDimension\n  /** Successfully analyzed Effect-bearing files / analyzed plus failed files. */\n  readonly analysisSuccess: AuditDimension\n  /** Resolved IR nodes / all IR nodes. */\n  readonly sourceResolution: AuditDimension\n}\n\nexport interface AuditAssessmentInput {\n  readonly discoveredFiles: number\n  readonly effectFiles: number\n  readonly failedFiles: number\n  readonly totalNodes: number\n  readonly unresolvedNodes: number\n}\n\nconst dimension = (\n  numerator: number,\n  denominator: number,\n  emptyRate: number\n): AuditDimension => ({\n  numerator,\n  denominator,\n  rate: denominator === 0 ? emptyRate : numerator / denominator\n})\n\nexport const assessAudit = (input: AuditAssessmentInput): AuditAssessment => ({\n  effectAdoption: dimension(input.effectFiles, input.discoveredFiles, 0),\n  analysisSuccess: dimension(\n    input.effectFiles,\n    input.effectFiles + input.failedFiles,\n    1\n  ),\n  sourceResolution: dimension(\n    input.totalNodes - input.unresolvedNodes,\n    input.totalNodes,\n    1\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: ReadonlyArray<StaticFlowNode>\n  readonly index: number\n}\n\nexport interface IRIndex {\n  readonly nodes: ReadonlyArray<StaticFlowNode>\n  readonly byId: ReadonlyMap<string, StaticFlowNode>\n  readonly parentById: ReadonlyMap<string, StaticFlowNode>\n  readonly spanPathById: ReadonlyMap<string, ReadonlyArray<string>>\n  readonly idsBySpanPath: ReadonlyMap<string, ReadonlyArray<string>>\n}\n\n/** Exhaustive child access with an empty-array identity for leaf nodes. */\nexport const childrenOf = (node: StaticFlowNode): ReadonlyArray<StaticFlowNode> =>\n  Option.getOrElse(getStaticChildren(node), () => [] as const)\n\n/** Depth-first pre-order traversal of an IR forest. */\nexport const visitIR = (\n  roots: ReadonlyArray<StaticFlowNode>,\n  visitor: (visit: IRVisit) => void\n): void => {\n  let index = 0\n  const visit = (\n    nodes: ReadonlyArray<StaticFlowNode>,\n    parent: StaticFlowNode | undefined,\n    ancestors: ReadonlyArray<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: ReadonlyArray<StaticFlowNode>\n): ReadonlyArray<StaticFlowNode> => {\n  const nodes: Array<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): ReadonlyArray<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: ReadonlyArray<string>): string => path.join(\"\\u001f\")\n\n/** Build all common indexes once for diagnostics, renderers, and overlays. */\nexport const indexIR = (ir: StaticEffectIR): IRIndex => {\n  const nodes: Array<StaticFlowNode> = []\n  const byId = new Map<string, StaticFlowNode>()\n  const parentById = new Map<string, StaticFlowNode>()\n  const spanPathById = new Map<string, ReadonlyArray<string>>()\n  const mutableIdsBySpanPath = new Map<string, Array<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 { indexIR, runtimeSpanName } from \"./ir\"\nimport type { SourceLocation, StaticEffectIR, StaticFlowNode } from \"./types\"\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: ReadonlyArray<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:\n        \"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 => total === 0 ? 1 : resolved / total\n\nexport const assessIRFidelity = (ir: StaticEffectIR): IRFidelityAssessment => {\n  const index = indexIR(ir)\n  const findings: Array<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","/* eslint-disable @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-redundant-type-constituents */\nimport { basename, relative, resolve } from \"path\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\n\nexport interface CommandDefinitionSummary {\n  readonly id: string\n  readonly file: string\n  readonly variableName: string\n  readonly commandName: string\n}\n\nexport interface RuntimeArchitectureStage {\n  readonly source: string\n  readonly kind: \"identifier\" | \"call\" | \"function\" | \"literal\" | \"object\" | \"expression\"\n}\n\nexport interface RuntimeArchitectureSummary {\n  readonly id: string\n  readonly file: string\n  readonly runtimeName: string\n  readonly constructor: string\n  readonly model: RuntimeArchitectureStage | undefined\n  readonly flagsSchema: RuntimeArchitectureStage | undefined\n  readonly flags: RuntimeArchitectureStage | undefined\n  readonly init: RuntimeArchitectureStage | undefined\n  readonly update: RuntimeArchitectureStage | undefined\n  readonly view: RuntimeArchitectureStage | undefined\n  readonly container: RuntimeArchitectureStage | undefined\n  readonly subscriptions: RuntimeArchitectureStage | undefined\n  readonly resources: RuntimeArchitectureStage | undefined\n  readonly managedResources: RuntimeArchitectureStage | undefined\n  readonly routing: RuntimeArchitectureStage | undefined\n  readonly routingHandlers: ReadonlyArray<string>\n  readonly crash: RuntimeArchitectureStage | undefined\n  readonly crashHandlers: ReadonlyArray<string>\n  readonly slowView: RuntimeArchitectureStage | undefined\n  readonly title: RuntimeArchitectureStage | undefined\n  readonly devtools: RuntimeArchitectureStage | undefined\n  readonly capabilities: ReadonlyArray<string>\n  readonly relatedCommands: ReadonlyArray<string>\n}\n\nexport interface ProjectArchitectureSummary {\n  readonly runtimes: ReadonlyArray<RuntimeArchitectureSummary>\n  readonly commandDefinitions: ReadonlyArray<CommandDefinitionSummary>\n  readonly layerAssemblies: ReadonlyArray<LayerAssemblySummary>\n  readonly filesScanned: number\n}\n\nexport interface LayerAssemblySummary {\n  readonly id: string\n  readonly file: string\n  readonly name: string\n  readonly constructor: string\n  readonly operations: ReadonlyArray<string>\n  readonly references: ReadonlyArray<string>\n}\n\ninterface ExtractProjectArchitectureOptions {\n  readonly tsconfig?: string | undefined\n}\n\nconst FEATURE_ORDER = [\n  \"flags\",\n  \"routing\",\n  \"subscriptions\",\n  \"resources\",\n  \"managedResources\",\n  \"crash\",\n  \"slowView\",\n  \"title\",\n  \"devtools\"\n] as const\n\nconst describeText = (text: string, fallback: string): string => {\n  const trimmed = text.replace(/\\s+/g, \" \").trim()\n  if (!trimmed) return fallback\n  if (trimmed.length <= 80) return trimmed\n  return `${trimmed.slice(0, 77)}...`\n}\n\nconst detectStageKind = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  expr: any,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n): RuntimeArchitectureStage[\"kind\"] => {\n  if (Node.isIdentifier(expr) || Node.isPropertyAccessExpression(expr)) return \"identifier\"\n  if (Node.isCallExpression(expr)) return \"call\"\n  if (Node.isArrowFunction(expr) || Node.isFunctionExpression(expr) || Node.isMethodDeclaration(expr)) return \"function\"\n  if (Node.isObjectLiteralExpression(expr)) return \"object\"\n  if (\n    Node.isStringLiteral(expr) ||\n    Node.isNumericLiteral(expr) ||\n    expr.getKindName() === \"TrueKeyword\" ||\n    expr.getKindName() === \"FalseKeyword\" ||\n    expr.getKindName() === \"NullKeyword\"\n  ) return \"literal\"\n  return \"expression\"\n}\n\nconst describeStage = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  expr: any,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n): RuntimeArchitectureStage => ({\n  source: describeText(expr.getText(), expr.getKindName()),\n  kind: detectStageKind(expr, Node)\n})\n\nconst getPropertyExpression = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  objectLiteral: any,\n  name: string,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n): any | undefined => {\n  const prop = objectLiteral.getProperty(name)\n  if (!prop) return undefined\n  if (Node.isPropertyAssignment(prop)) return prop.getInitializer()\n  if (Node.isShorthandPropertyAssignment(prop)) return prop.getNameNode()\n  if (Node.isMethodDeclaration(prop)) return prop\n  return undefined\n}\n\nconst extractNestedHandlers = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  expr: any,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n): ReadonlyArray<string> => {\n  if (!expr || !Node.isObjectLiteralExpression(expr)) return []\n  return expr.getProperties().flatMap(\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    (prop: any) => {\n      if (\n        Node.isPropertyAssignment(prop) ||\n        Node.isShorthandPropertyAssignment(prop) ||\n        Node.isMethodDeclaration(prop)\n      ) {\n        return [prop.getName()]\n      }\n      return []\n    }\n  )\n}\n\nconst inferCapabilities = (\n  summary: Omit<RuntimeArchitectureSummary, \"capabilities\" | \"relatedCommands\">\n): Array<string> => {\n  const features: Array<string> = []\n  if (summary.flags || summary.flagsSchema) features.push(\"flags\")\n  if (summary.routing) features.push(\"routing\")\n  if (summary.subscriptions) features.push(\"subscriptions\")\n  if (summary.resources) features.push(\"resources\")\n  if (summary.managedResources) features.push(\"managedResources\")\n  if (summary.crash) features.push(\"crash\")\n  if (summary.slowView) features.push(\"slowView\")\n  if (summary.title) features.push(\"title\")\n  if (summary.devtools) features.push(\"devtools\")\n  return FEATURE_ORDER.filter((feature) => features.includes(feature))\n}\n\nconst isMakeProgramCall = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  call: any,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n): boolean => {\n  const expression = call.getExpression()\n  const text = expression.getText()\n  return Node.isIdentifier(expression)\n    ? text === \"makeProgram\"\n    : Node.isPropertyAccessExpression(expression) && text.endsWith(\".makeProgram\")\n}\n\nconst isCommandDefineCall = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  call: any,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n): boolean => {\n  const expression = call.getExpression()\n  if (!Node.isPropertyAccessExpression(expression)) return false\n  return expression.getName() === \"define\" && expression.getExpression().getText().endsWith(\"Command\")\n}\n\nconst runtimeNameForCall = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  call: any,\n  filePath: string,\n  ordinal: number,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n): string => {\n  const parent = call.getParent()\n  if (parent && Node.isVariableDeclaration(parent)) return parent.getName()\n  return `${basename(filePath, \".ts\")}-runtime-${String(ordinal)}`\n}\n\nconst isLayerCall = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  call: any\n): boolean => {\n  const text = call.getExpression().getText()\n  return text.startsWith(\"Layer.\")\n}\n\nconst isLayerAssemblyRoot = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  call: any,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n): boolean => {\n  if (!isLayerCall(call)) return false\n  const parent = call.getParent()\n  if (!parent) return false\n  if (Node.isVariableDeclaration(parent) && parent.getInitializer() === call) return true\n  if (Node.isReturnStatement(parent) && parent.getExpression() === call) return true\n  return false\n}\n\nconst getLayerAssemblyName = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  call: any,\n  filePath: string,\n  ordinal: number,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n): string => {\n  const parent = call.getParent()\n  if (parent && Node.isVariableDeclaration(parent)) return parent.getName()\n  return `${basename(filePath, \".ts\")}-layer-${String(ordinal)}`\n}\n\nconst extractLayerAssembly = (\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  call: any,\n  filePath: string,\n  name: string,\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  Node: any\n): LayerAssemblySummary => {\n  const operations: Array<string> = []\n  const references = new Set<string>()\n\n  const collectLayerRefs = (\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    expr: any\n  ): void => {\n    if (!expr) return\n    if (Node.isIdentifier(expr)) {\n      const text = expr.getText()\n      if (![\"Layer\", \"Effect\"].includes(text)) references.add(text)\n      return\n    }\n    if (Node.isPropertyAccessExpression(expr)) {\n      const text = expr.getText()\n      if (!text.startsWith(\"Layer.\") && !text.startsWith(\"Effect.\")) {\n        references.add(text)\n      }\n      return\n    }\n    if (Node.isCallExpression(expr)) {\n      collectLayerCall(expr)\n      return\n    }\n    if (Node.isArrayLiteralExpression(expr)) {\n      for (const element of expr.getElements()) collectLayerRefs(element)\n    }\n  }\n\n  const collectLayerCall = (\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    current: any\n  ): void => {\n    const exprText = current.getExpression().getText()\n    if (exprText.startsWith(\"Layer.\")) {\n      operations.push(exprText.replace(/^Layer\\./, \"\"))\n    } else if (exprText.endsWith(\".pipe\")) {\n      operations.push(\"pipe\")\n      const pipeBase = current.getExpression().getExpression()\n      collectLayerRefs(pipeBase)\n      if (Node.isCallExpression(pipeBase)) {\n        collectLayerCall(pipeBase)\n      }\n    }\n    for (const arg of current.getArguments()) {\n      collectLayerRefs(arg)\n    }\n  }\n\n  collectLayerCall(call)\n\n  return {\n    id: `${filePath}:${name}`,\n    file: filePath,\n    name,\n    constructor: call.getExpression().getText(),\n    operations,\n    references: [...references]\n  }\n}\n\nexport function extractProjectArchitecture(\n  filePaths: ReadonlyArray<string>,\n  options: ExtractProjectArchitectureOptions = {}\n): ProjectArchitectureSummary {\n  try {\n    const { Project, Node } = loadTsMorph()\n    const project = options.tsconfig\n      ? new Project({ tsConfigFilePath: options.tsconfig })\n      : new Project({ skipAddingFilesFromTsConfig: true, compilerOptions: { allowJs: true } })\n\n    const sourceFiles = filePaths.flatMap((filePath) => {\n      try {\n        return [project.addSourceFileAtPath(filePath)]\n      } catch {\n        return []\n      }\n    })\n\n    const commands: Array<CommandDefinitionSummary> = []\n    const runtimes: Array<RuntimeArchitectureSummary> = []\n    const layerAssemblies: Array<LayerAssemblySummary> = []\n\n    for (const sourceFile of sourceFiles) {\n      const filePath = resolve(sourceFile.getFilePath())\n      let runtimeOrdinal = 0\n      let layerOrdinal = 0\n\n      sourceFile.forEachDescendant((node) => {\n        if (!Node.isCallExpression(node)) return undefined\n\n        if (isCommandDefineCall(node, Node)) {\n          const parent = node.getParent()\n          const variableName = parent && Node.isVariableDeclaration(parent)\n            ? parent.getName()\n            : `command-${String(commands.length + 1)}`\n          const firstArg = node.getArguments()[0]\n          const commandName = firstArg && Node.isStringLiteral(firstArg)\n            ? firstArg.getLiteralText()\n            : variableName\n          commands.push({\n            id: `${filePath}:${variableName}`,\n            file: filePath,\n            variableName,\n            commandName\n          })\n          return undefined\n        }\n\n        if (isLayerAssemblyRoot(node, Node)) {\n          layerOrdinal += 1\n          const layerName = getLayerAssemblyName(node, filePath, layerOrdinal, Node)\n          layerAssemblies.push(extractLayerAssembly(node, filePath, layerName, Node))\n          return undefined\n        }\n\n        if (!isMakeProgramCall(node, Node)) return undefined\n        const configArg = node.getArguments()[0]\n        if (!configArg || !Node.isObjectLiteralExpression(configArg)) return undefined\n\n        runtimeOrdinal += 1\n        const runtimeName = runtimeNameForCall(node, filePath, runtimeOrdinal, Node)\n        const model = getPropertyExpression(configArg, \"Model\", Node)\n        const flagsSchema = getPropertyExpression(configArg, \"Flags\", Node)\n        const flags = getPropertyExpression(configArg, \"flags\", Node)\n        const init = getPropertyExpression(configArg, \"init\", Node)\n        const update = getPropertyExpression(configArg, \"update\", Node)\n        const view = getPropertyExpression(configArg, \"view\", Node)\n        const container = getPropertyExpression(configArg, \"container\", Node)\n        const subscriptions = getPropertyExpression(configArg, \"subscriptions\", Node)\n        const resources = getPropertyExpression(configArg, \"resources\", Node)\n        const managedResources = getPropertyExpression(configArg, \"managedResources\", Node)\n        const routing = getPropertyExpression(configArg, \"routing\", Node)\n        const crash = getPropertyExpression(configArg, \"crash\", Node)\n        const slowView = getPropertyExpression(configArg, \"slowView\", Node)\n        const title = getPropertyExpression(configArg, \"title\", Node)\n        const devtools = getPropertyExpression(configArg, \"devtools\", Node)\n\n        const baseRuntime = {\n          id: `${filePath}:${runtimeName}`,\n          file: filePath,\n          runtimeName,\n          constructor: node.getExpression().getText(),\n          model: model ? describeStage(model, Node) : undefined,\n          flagsSchema: flagsSchema ? describeStage(flagsSchema, Node) : undefined,\n          flags: flags ? describeStage(flags, Node) : undefined,\n          init: init ? describeStage(init, Node) : undefined,\n          update: update ? describeStage(update, Node) : undefined,\n          view: view ? describeStage(view, Node) : undefined,\n          container: container ? describeStage(container, Node) : undefined,\n          subscriptions: subscriptions ? describeStage(subscriptions, Node) : undefined,\n          resources: resources ? describeStage(resources, Node) : undefined,\n          managedResources: managedResources ? describeStage(managedResources, Node) : undefined,\n          routing: routing ? describeStage(routing, Node) : undefined,\n          routingHandlers: extractNestedHandlers(routing, Node),\n          crash: crash ? describeStage(crash, Node) : undefined,\n          crashHandlers: extractNestedHandlers(crash, Node),\n          slowView: slowView ? describeStage(slowView, Node) : undefined,\n          title: title ? describeStage(title, Node) : undefined,\n          devtools: devtools ? describeStage(devtools, Node) : undefined\n        }\n\n        runtimes.push({\n          ...baseRuntime,\n          capabilities: inferCapabilities(baseRuntime),\n          relatedCommands: []\n        })\n        return undefined\n      })\n    }\n\n    const commandsByFile = new Map<string, Array<string>>()\n    for (const command of commands) {\n      const current = commandsByFile.get(command.file) ?? []\n      if (!current.includes(command.commandName)) current.push(command.commandName)\n      commandsByFile.set(command.file, current)\n    }\n\n    return {\n      runtimes: runtimes.map((runtime) => ({\n        ...runtime,\n        relatedCommands: commandsByFile.get(runtime.file) ?? []\n      })),\n      commandDefinitions: commands,\n      layerAssemblies,\n      filesScanned: sourceFiles.length\n    }\n  } catch {\n    return {\n      runtimes: [],\n      commandDefinitions: [],\n      layerAssemblies: [],\n      filesScanned: 0\n    }\n  }\n}\n\nexport function renderProjectArchitecture(\n  summary: ProjectArchitectureSummary,\n  baseDir?: string\n): string {\n  if (summary.runtimes.length === 0 && summary.layerAssemblies.length === 0) {\n    return \"(no runtime architecture detected)\"\n  }\n\n  const runtimeSections = summary.runtimes.map((runtime) => {\n    const fileLabel = baseDir\n      ? relative(baseDir, runtime.file) || basename(runtime.file)\n      : runtime.file\n    const lines: Array<string> = []\n    lines.push(`${runtime.runtimeName} (${fileLabel})`)\n    lines.push(`  Constructor: ${runtime.constructor}`)\n    lines.push(\n      `  Loop: ${\n        runtime.flags || runtime.flagsSchema ? \"Flags -> init -> Model + Commands\" : \"init -> Model + Commands\"\n      }`\n    )\n    lines.push(\"  Loop: Message -> update -> Model + Commands\")\n    lines.push(\"  Loop: Model -> view -> Html\")\n    if (runtime.subscriptions) {\n      lines.push(`  Subscriptions: ${runtime.subscriptions.source} -> Message stream`)\n    }\n    if (runtime.resources) {\n      lines.push(`  Resources: ${runtime.resources.source}`)\n    }\n    if (runtime.managedResources) {\n      lines.push(`  Managed resources: ${runtime.managedResources.source}`)\n    }\n    if (runtime.routing) {\n      const handlers = runtime.routingHandlers.length > 0\n        ? ` (${runtime.routingHandlers.join(\", \")})`\n        : \"\"\n      lines.push(`  Routing: ${runtime.routing.source}${handlers}`)\n    }\n    if (runtime.crash) {\n      const handlers = runtime.crashHandlers.length > 0\n        ? ` (${runtime.crashHandlers.join(\", \")})`\n        : \"\"\n      lines.push(`  Crash handling: ${runtime.crash.source}${handlers}`)\n    }\n    if (runtime.slowView) {\n      lines.push(`  Slow view: ${runtime.slowView.source}`)\n    }\n    if (runtime.title) {\n      lines.push(`  Title: ${runtime.title.source}`)\n    }\n    if (runtime.devtools) {\n      lines.push(`  Devtools: ${runtime.devtools.source}`)\n    }\n    if (runtime.relatedCommands.length > 0) {\n      lines.push(`  Commands in file: ${runtime.relatedCommands.join(\", \")}`)\n    }\n    if (runtime.capabilities.length > 0) {\n      lines.push(`  Capabilities: ${runtime.capabilities.join(\", \")}`)\n    }\n    return lines.join(\"\\n\")\n  })\n\n  const commandFiles = new Map<string, Array<string>>()\n  for (const command of summary.commandDefinitions) {\n    const fileLabel = baseDir\n      ? relative(baseDir, command.file) || basename(command.file)\n      : command.file\n    const current = commandFiles.get(fileLabel) ?? []\n    if (!current.includes(command.commandName)) current.push(command.commandName)\n    commandFiles.set(fileLabel, current)\n  }\n\n  const commandSection = commandFiles.size === 0\n    ? \"\"\n    : `\\n\\nCommand definitions:\\n${\n      [...commandFiles.entries()]\n        .map(([file, names]) => `  ${file}: ${names.join(\", \")}`)\n        .join(\"\\n\")\n    }`\n\n  const isTestLayer = (layer: LayerAssemblySummary): boolean =>\n    /(?:^|\\/)__tests__\\/|(?:^|\\/)test\\/|\\.test\\.[cm]?[jt]sx?$/.test(layer.file)\n\n  const renderLayerBlock = (title: string, layers: ReadonlyArray<LayerAssemblySummary>): string =>\n    layers.length === 0\n      ? \"\"\n      : `\\n\\n${title}:\\n${\n        layers\n          .map((layer) => {\n            const fileLabel = baseDir\n              ? relative(baseDir, layer.file) || basename(layer.file)\n              : layer.file\n            const refs = layer.references.length > 0 ? `\\n    References: ${layer.references.join(\", \")}` : \"\"\n            const ops = layer.operations.length > 0 ? layer.operations.join(\" -> \") : layer.constructor\n            return `  ${layer.name} (${fileLabel})\\n    Ops: ${ops}${refs}`\n          })\n          .join(\"\\n\")\n      }`\n\n  const appLayers = summary.layerAssemblies.filter((layer) => !isTestLayer(layer))\n  const testLayers = summary.layerAssemblies.filter((layer) => isTestLayer(layer))\n  const layerSection = renderLayerBlock(\"Layer assemblies\", appLayers) +\n    renderLayerBlock(\"Test layer assemblies\", testLayers)\n\n  return [\n    `Project architecture (${String(summary.runtimes.length)} runtime${summary.runtimes.length === 1 ? \"\" : \"s\"}, ${\n      String(summary.layerAssemblies.length)\n    } layer assembl${summary.layerAssemblies.length === 1 ? \"y\" : \"ies\"})`,\n    ...runtimeSections\n  ].join(\"\\n\\n\") + commandSection + layerSection\n}\n","/** Discover and analyze a project once so every project view uses the same facts. */\n\nimport { Clock, Effect } from \"effect\"\nimport { readdir } from \"fs/promises\"\nimport { extname, join } from \"path\"\nimport { analyze } from \"./analyze\"\nimport type { StaticEffectIR } from \"./types\"\n\nexport type ProjectCorpusFileStatus = \"ok\" | \"zero\" | \"fail\"\n\nexport interface ProjectCorpusFile {\n  readonly file: string\n  readonly status: ProjectCorpusFileStatus\n  readonly programs: ReadonlyArray<StaticEffectIR>\n  readonly error?: string | undefined\n  readonly durationMs?: number | undefined\n}\n\nexport interface ProjectCorpus {\n  readonly root: string\n  readonly files: ReadonlyArray<ProjectCorpusFile>\n  readonly durationMs: number\n}\n\nexport interface ScanProjectCorpusOptions {\n  readonly tsconfig?: string | undefined\n  readonly extensions?: ReadonlyArray<string> | undefined\n  readonly maxDepth?: number | undefined\n  readonly includePerFileTiming?: boolean | undefined\n  readonly knownEffectInternalsRoot?: string | undefined\n}\n\nconst DEFAULT_EXTENSIONS = [\".ts\", \".tsx\"] as const\nconst DEFAULT_MAX_DEPTH = 10\n\nexport const discoverProjectFiles = async (\n  dir: string,\n  extensions: ReadonlyArray<string> = DEFAULT_EXTENSIONS,\n  maxDepth = DEFAULT_MAX_DEPTH,\n  currentDepth = 0\n): Promise<ReadonlyArray<string>> => {\n  if (currentDepth >= maxDepth) return []\n  const files: Array<string> = []\n  try {\n    const entries = await readdir(dir, { withFileTypes: true })\n    for (const entry of entries) {\n      const fullPath = join(dir, entry.name)\n      if (entry.isDirectory()) {\n        if (entry.name !== \"node_modules\" && entry.name !== \".git\") {\n          files.push(\n            ...await discoverProjectFiles(\n              fullPath,\n              extensions,\n              maxDepth,\n              currentDepth + 1\n            )\n          )\n        }\n      } else if (entry.isFile() && extensions.includes(extname(entry.name))) {\n        files.push(fullPath)\n      }\n    }\n  } catch (error) {\n    // A file passed as the root is a one-file project, so every project-wide\n    // report (--error-channel, --service-health, ...) also works on one file.\n    if (currentDepth === 0 && (error as NodeJS.ErrnoException).code === \"ENOTDIR\") {\n      return extensions.includes(extname(dir)) ? [dir] : []\n    }\n    // An unreadable directory contributes no files. Individual analysis failures\n    // remain visible in the corpus once a file has been discovered.\n  }\n  return files.sort((left, right) => left.localeCompare(right))\n}\n\nexport const scanProjectCorpus = (\n  root: string,\n  options: ScanProjectCorpusOptions = {}\n): Effect.Effect<ProjectCorpus> =>\n  Effect.gen(function*() {\n    const startedAt = yield* Clock.currentTimeMillis\n    const files = yield* Effect.promise(() =>\n      discoverProjectFiles(\n        root,\n        options.extensions ?? DEFAULT_EXTENSIONS,\n        options.maxDepth ?? DEFAULT_MAX_DEPTH\n      )\n    )\n    const corpusFiles: Array<ProjectCorpusFile> = []\n\n    // Analysis remains sequential until node IDs and ts-morph projects are owned\n    // by the Analysis session instead of shared module globals.\n    for (const file of files) {\n      const fileStartedAt = options.includePerFileTiming === true ? yield* Clock.currentTimeMillis : 0\n      const result = yield* analyze(file, {\n        tsConfigPath: options.tsconfig,\n        knownEffectInternalsRoot: options.knownEffectInternalsRoot\n      }).all.pipe(\n        Effect.map((programs) => ({ _tag: \"ok\" as const, programs })),\n        Effect.catch((error) =>\n          Effect.succeed({\n            _tag: \"fail\" as const,\n            error: error instanceof Error ? error.message : String(error)\n          })\n        )\n      )\n      const durationMs = options.includePerFileTiming === true\n        ? (yield* Clock.currentTimeMillis) - fileStartedAt\n        : undefined\n\n      if (result._tag === \"ok\") {\n        corpusFiles.push({\n          file,\n          status: result.programs.length > 0 ? \"ok\" : \"zero\",\n          programs: result.programs,\n          ...(durationMs === undefined ? {} : { durationMs })\n        })\n        continue\n      }\n\n      const isZero = result.error.includes(\"No Effect programs found\") ||\n        result.error.includes(\"NO_EFFECTS_FOUND\")\n      corpusFiles.push({\n        file,\n        status: isZero ? \"zero\" : \"fail\",\n        programs: [],\n        ...(isZero ? {} : { error: result.error }),\n        ...(durationMs === undefined ? {} : { durationMs })\n      })\n    }\n\n    return {\n      root,\n      files: corpusFiles,\n      durationMs: (yield* Clock.currentTimeMillis) - startedAt\n    }\n  })\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Service Registry - builds a deduplicated service map for whole-codebase analysis.\n *\n * When the analyzer encounters `yield* SomeService`, this module creates a\n * first-class ServiceArtifact for that service, including its tag definition,\n * interface shape, layer implementations, consumers, and transitive dependencies.\n */\n\nimport { Option } from \"effect\"\nimport { loadTsMorph } from \"./ts-morph-loader\"\nimport type {\n  LayerImplementation,\n  ProjectServiceMap,\n  ServiceArtifact,\n  ServiceConsumerRef,\n  ServiceDefinition,\n  SourceLocation,\n  StaticEffectIR,\n  StaticFlowNode\n} from \"./types\"\nimport { getStaticChildren } from \"./types\"\n\n// Minimal interfaces for ts-morph's dynamically-loaded API so that values\n// flowing through the analyzer carry concrete types instead of `any`.\ninterface TsMorphSymbol {\n  getName(): string\n}\n\ninterface TsMorphType {\n  getProperties(): Array<TsMorphSymbol>\n  getCallSignatures(): Array<unknown>\n}\n\ninterface TsMorphTypeChecker {\n  getTypeAtLocation(node: unknown): TsMorphType\n  getTypeOfSymbolAtLocation(symbol: unknown, node: unknown): TsMorphType\n}\n\ninterface TsMorphProject {\n  getTypeChecker(): TsMorphTypeChecker\n}\n\ninterface TsMorphNode {\n  getName(): string\n  getText(): string\n  getStart(): number\n  getKind(): number\n  getExtends(): TsMorphNode | undefined\n  getExpression(): TsMorphNode | undefined\n  getTypeArguments(): Array<TsMorphNode>\n  getArguments?(): Array<TsMorphNode>\n  getInitializer(): TsMorphNode | undefined\n}\n\ninterface TsMorphSourceFile {\n  getDescendantsOfKind(kind: number): Array<TsMorphNode>\n  getFilePath(): string\n  getProject(): TsMorphProject\n  getLineAndColumnAtPos(pos: number): { line: number; column: number }\n}\n\n// Re-export for convenience\nexport type { ProjectServiceMap, ServiceArtifact }\n\n// =============================================================================\n// Service tag definition extraction (augmented with location + file info)\n// =============================================================================\n\ninterface ServiceTagInfo {\n  readonly tagId: string\n  readonly className: string\n  readonly filePath: string\n  readonly location: SourceLocation\n  readonly definition: ServiceDefinition\n  readonly interfaceTypeText?: string | undefined\n}\n\n/**\n * Extract service tag definitions from a source file, with location and file path info.\n * Augments the existing extractServiceDefinitionsFromFile pattern with richer metadata.\n */\nfunction extractServiceTagsFromFile(\n  sourceFile: TsMorphSourceFile,\n  filePath: string\n): Array<ServiceTagInfo> {\n  const { SyntaxKind } = loadTsMorph()\n  const results: Array<ServiceTagInfo> = []\n  const typeChecker = sourceFile.getProject().getTypeChecker()\n  const classDeclarations = sourceFile.getDescendantsOfKind(SyntaxKind.ClassDeclaration)\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 (\n      !extText.includes(\"Context.Service\") && !extText.includes(\"Context.Tag\") && !extText.includes(\"Effect.Service\")\n    ) continue\n\n    // Extract tag string from Context.Tag('TagName') if possible\n    let tagId = name\n    const tagMatch = /Context\\.Tag\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)/.exec(extText)\n    if (tagMatch?.[1]) {\n      tagId = tagMatch[1]\n    } else {\n      const serviceMatch = /Context\\.Service[\\s\\S]*?\\(\\s*\\)\\s*\\(\\s*['\"]([^'\"]+)['\"]/.exec(extText)\n      if (serviceMatch?.[1]) tagId = serviceMatch[1]\n    }\n\n    // Get type arguments for interface shape\n    let typeArgs: ReadonlyArray<TsMorphNode> = extExpr.getTypeArguments()\n    let expression: TsMorphNode | undefined = extExpr\n    while (typeArgs.length < 2) {\n      expression = expression.getExpression()\n      if (!expression) break\n      typeArgs = expression.getTypeArguments()\n    }\n\n    let definition: ServiceDefinition = { tagId, methods: [], properties: [] }\n    let interfaceTypeText: string | undefined\n\n    if (typeArgs.length >= 2) {\n      const interfaceTypeNode = typeArgs[1]\n      if (interfaceTypeNode) {\n        try {\n          interfaceTypeText = interfaceTypeNode.getText()\n          const type = typeChecker.getTypeAtLocation(interfaceTypeNode)\n          const methods: Array<string> = []\n          const properties: Array<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          definition = { tagId, methods, properties }\n        } catch {\n          // fall through with empty definition\n        }\n      }\n    }\n\n    const pos = classDecl.getStart()\n    const lineAndCol = sourceFile.getLineAndColumnAtPos(pos)\n\n    results.push({\n      tagId,\n      className: name,\n      filePath,\n      location: {\n        filePath,\n        line: lineAndCol.line,\n        column: lineAndCol.column - 1\n      },\n      definition,\n      interfaceTypeText\n    })\n  }\n\n  return results\n}\n\n// =============================================================================\n// Layer implementation extraction\n// =============================================================================\n\n/**\n * Extract layer implementations from a source file by scanning for\n * Layer.effect(Tag, ...), Layer.succeed(Tag, ...), Layer.sync(Tag, ...), etc.\n */\nfunction extractLayerImplementationsFromFile(\n  sourceFile: TsMorphSourceFile,\n  filePath: string,\n  identifierToServiceId: ReadonlyMap<string, string>\n): Array<{ readonly providesServiceId: string; readonly implementation: LayerImplementation }> {\n  const { SyntaxKind } = loadTsMorph()\n  const results: Array<{ providesServiceId: string; implementation: LayerImplementation }> = []\n\n  // Scan all variable declarations at top level for Layer.* calls\n  const varDeclarations = sourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration)\n\n  for (const varDecl of varDeclarations) {\n    const initializer = varDecl.getInitializer()\n    if (!initializer) continue\n\n    const initText = initializer.getText()\n\n    // Check for Layer.effect, Layer.succeed, Layer.sync, Layer.scoped patterns\n    const layerMatch = /Layer\\.(effect|succeed|sync|scoped)\\s*\\(\\s*/.exec(\n      initText\n    )\n    if (!layerMatch) continue\n\n    const kind = layerMatch[1] as \"effect\" | \"succeed\" | \"sync\" | \"scoped\"\n    const layerName = varDecl.getName()\n\n    // Try to find the service tag referenced as first argument\n    // Look for the first identifier in the call args that matches a known service\n    let providesServiceId: string | undefined\n\n    // Walk call expression to find first argument\n    if ((initializer.getKind()) === (SyntaxKind.CallExpression)) {\n      const args = initializer.getArguments?.()\n      if (args && args.length > 0) {\n        const firstArg = args[0]\n        if (!firstArg) continue\n        const firstArgText = firstArg.getText().trim()\n        providesServiceId = identifierToServiceId.get(firstArgText)\n      }\n    }\n\n    // Also try to extract from pipe chains: Layer.effect(...).pipe(Layer.provide(...))\n    // For now handle the unwrapped case and simple .pipe(Layer.provide(...))\n    if (!providesServiceId) {\n      // Try to match by text pattern: Layer.effect(ServiceName, ...)\n      for (const identifier of identifierToServiceId.keys()) {\n        if (\n          initText.includes(`Layer.${kind}(${identifier}`) ||\n          initText.includes(`Layer.${kind}(\\n${identifier}`)\n        ) {\n          providesServiceId = identifierToServiceId.get(identifier)\n          break\n        }\n      }\n    }\n\n    if (!providesServiceId) continue\n\n    // Extract required services from Layer.provide() in pipe chain\n    const requires: Array<string> = []\n    const provideMatch = /Layer\\.provide\\s*\\(([^)]+)\\)/.exec(initText)\n    if (provideMatch?.[1]) {\n      const provideArg = provideMatch[1].trim()\n      // Could be a single layer or Layer.mergeAll(...)\n      for (const [identifier, canonicalId] of identifierToServiceId.entries()) {\n        if (canonicalId === providesServiceId) continue\n        if (provideArg.includes(identifier) && !requires.includes(canonicalId)) {\n          requires.push(canonicalId)\n        }\n      }\n    }\n\n    // Also check for yield* inside Layer.effect body for service dependencies\n    const yieldServiceMatches = initText.matchAll(/yield\\*\\s+(\\w+)/g)\n    for (const m of yieldServiceMatches) {\n      const ident = m[1]\n      const canonical = ident ? identifierToServiceId.get(ident) : undefined\n      if (canonical && canonical !== providesServiceId && !requires.includes(canonical)) {\n        requires.push(canonical)\n      }\n    }\n    const yieldServiceMatchesAlt = initText.matchAll(/yield\\s*\\*\\s*(\\w+)/g)\n    for (const m of yieldServiceMatchesAlt) {\n      const ident = m[1]\n      const canonical = ident ? identifierToServiceId.get(ident) : undefined\n      if (canonical && canonical !== providesServiceId && !requires.includes(canonical)) {\n        requires.push(canonical)\n      }\n    }\n\n    const pos = varDecl.getStart()\n    const lineAndCol = sourceFile.getLineAndColumnAtPos(pos)\n\n    results.push({\n      providesServiceId,\n      implementation: {\n        name: layerName,\n        filePath,\n        location: {\n          filePath,\n          line: lineAndCol.line,\n          column: lineAndCol.column - 1\n        },\n        kind,\n        requires\n      }\n    })\n  }\n\n  return results\n}\n\n// =============================================================================\n// Consumer extraction from analyzed programs\n// =============================================================================\n\nfunction collectConsumers(\n  byFile: ReadonlyMap<string, ReadonlyArray<StaticEffectIR>>\n): Map<string, Array<ServiceConsumerRef>> {\n  const consumers = new Map<string, Array<ServiceConsumerRef>>()\n\n  for (const [filePath, irs] of byFile) {\n    for (const ir of irs) {\n      const programName = ir.root.programName\n\n      // From requiredServices on the program root\n      if (ir.root.requiredServices) {\n        for (const req of ir.root.requiredServices) {\n          const list = consumers.get(req.serviceId) ?? []\n          list.push({\n            programName,\n            filePath,\n            location: req.requiredAt\n          })\n          consumers.set(req.serviceId, list)\n        }\n      }\n\n      // Also walk the IR tree for service references in effect nodes\n      collectConsumersFromNodes(ir.root.children, programName, filePath, consumers)\n    }\n  }\n\n  return consumers\n}\n\nfunction collectConsumersFromNodes(\n  nodes: ReadonlyArray<StaticFlowNode>,\n  programName: string,\n  filePath: string,\n  consumers: Map<string, Array<ServiceConsumerRef>>\n): void {\n  for (const node of nodes) {\n    if (node.type === \"effect\" && node.serviceCall) {\n      const serviceId = node.serviceCall.serviceType\n      if (serviceId) {\n        const list = consumers.get(serviceId) ?? []\n        // Avoid duplicates for the same program\n        if (!list.some((c) => c.programName === programName && c.filePath === filePath)) {\n          list.push({\n            programName,\n            filePath,\n            location: node.location\n          })\n          consumers.set(serviceId, list)\n        }\n      }\n    }\n\n    const children = Option.getOrElse(getStaticChildren(node), () => [])\n    if (children.length > 0) {\n      collectConsumersFromNodes(children, programName, filePath, consumers)\n    }\n  }\n}\n\n// =============================================================================\n// Topological sort\n// =============================================================================\n\nfunction computeTopologicalOrder(\n  services: ReadonlyMap<string, ServiceArtifact>\n): Array<string> {\n  const result: Array<string> = []\n  const visited = new Set<string>()\n  const temp = new Set<string>()\n\n  function visit(id: string): void {\n    if (visited.has(id)) return\n    if (temp.has(id)) return // cycle\n    temp.add(id)\n    const artifact = services.get(id)\n    if (artifact) {\n      for (const dep of artifact.dependencies) {\n        visit(dep)\n      }\n    }\n    temp.delete(id)\n    visited.add(id)\n    result.push(id)\n  }\n\n  for (const id of services.keys()) {\n    visit(id)\n  }\n\n  return result\n}\n\n// =============================================================================\n// Transitive dependency computation\n// =============================================================================\n\nfunction computeTransitiveDeps(\n  serviceId: string,\n  layerImpls: ReadonlyArray<LayerImplementation>,\n  allLayersByService: ReadonlyMap<string, ReadonlyArray<LayerImplementation>>,\n  visited = new Set<string>()\n): Array<string> {\n  const deps: Array<string> = []\n  if (visited.has(serviceId)) return deps\n  visited.add(serviceId)\n\n  for (const layer of layerImpls) {\n    for (const req of layer.requires) {\n      if (!deps.includes(req)) {\n        deps.push(req)\n      }\n      // Recurse into the required service's layers\n      const reqLayers = allLayersByService.get(req)\n      if (reqLayers) {\n        for (const transitive of computeTransitiveDeps(req, reqLayers, allLayersByService, visited)) {\n          if (!deps.includes(transitive)) {\n            deps.push(transitive)\n          }\n        }\n      }\n    }\n  }\n\n  return deps\n}\n\n// =============================================================================\n// Main entry point\n// =============================================================================\n\n/**\n * Build a deduplicated project-level service map from analyzed program IRs.\n *\n * @param byFile Map of file path to analyzed programs in that file\n * @param sourceFiles Optional map of file path to ts-morph SourceFile for AST-level extraction.\n *   When not provided, only IR-level data (requiredServices, StaticLayerNode) is used.\n */\nexport function buildProjectServiceMap(\n  byFile: ReadonlyMap<string, ReadonlyArray<StaticEffectIR>>,\n  sourceFiles?: ReadonlyMap<string, any>\n): ProjectServiceMap {\n  // Step 1: Collect all service tag definitions\n  const serviceTagInfos = new Map<string, ServiceTagInfo>()\n\n  if (sourceFiles) {\n    for (const [filePath, sf] of sourceFiles) {\n      const tags = extractServiceTagsFromFile(sf as TsMorphSourceFile, filePath)\n      for (const tag of tags) {\n        // Use tagId (canonical tag string) as key, not className\n        if (!serviceTagInfos.has(tag.tagId)) {\n          serviceTagInfos.set(tag.tagId, tag)\n        }\n      }\n    }\n  }\n\n  // Also collect from IR metadata serviceDefinitions\n  for (const [filePath, irs] of byFile) {\n    for (const ir of irs) {\n      if (ir.metadata.serviceDefinitions) {\n        for (const def of ir.metadata.serviceDefinitions) {\n          if (!serviceTagInfos.has(def.tagId)) {\n            serviceTagInfos.set(def.tagId, {\n              tagId: def.tagId,\n              className: def.tagId,\n              filePath,\n              location: { filePath, line: 1, column: 0 },\n              definition: def\n            })\n          }\n        }\n      }\n    }\n  }\n\n  const knownServiceIds = new Set(serviceTagInfos.keys())\n  const identifierToServiceId = new Map<string, string>()\n  for (const [serviceId, tagInfo] of serviceTagInfos) {\n    // Allow matching layers by either canonical tag ID or the tag class name\n    if (!identifierToServiceId.has(serviceId)) identifierToServiceId.set(serviceId, serviceId)\n    if (!identifierToServiceId.has(tagInfo.className)) {\n      identifierToServiceId.set(tagInfo.className, serviceId)\n    }\n  }\n\n  // Also collect service IDs referenced in programs but not yet in the tag map\n  // (these may come from yield* SomeService without a tag definition in scope)\n  const allReferencedServiceIds = new Set<string>()\n  for (const irs of byFile.values()) {\n    for (const ir of irs) {\n      if (ir.root.requiredServices) {\n        for (const req of ir.root.requiredServices) {\n          allReferencedServiceIds.add(req.serviceId)\n        }\n      }\n    }\n  }\n\n  // Step 2: Collect layer implementations\n  const layersByService = new Map<string, Array<LayerImplementation>>()\n\n  if (sourceFiles) {\n    for (const [filePath, sf] of sourceFiles) {\n      const layers = extractLayerImplementationsFromFile(sf as TsMorphSourceFile, filePath, identifierToServiceId)\n      for (const match of layers) {\n        if (!knownServiceIds.has(match.providesServiceId)) continue\n        const list = layersByService.get(match.providesServiceId) ?? []\n        list.push(match.implementation)\n        layersByService.set(match.providesServiceId, list)\n      }\n    }\n  }\n\n  // Also extract layers from IR (StaticLayerNode with provides)\n  for (const [filePath, irs] of byFile) {\n    for (const ir of irs) {\n      collectLayersFromIR(ir.root.children, filePath, knownServiceIds, identifierToServiceId, layersByService, ir)\n    }\n  }\n\n  // Step 3: Collect consumers\n  const consumersByService = collectConsumers(byFile)\n\n  // Step 4: Build ServiceArtifact map\n  const services = new Map<string, ServiceArtifact>()\n  const unresolvedServices: Array<string> = []\n\n  // Build artifacts for known services\n  for (const [serviceId, tagInfo] of serviceTagInfos) {\n    const layerImpls = layersByService.get(serviceId) ?? []\n    const consumers = consumersByService.get(serviceId) ?? []\n    const dependencies = computeTransitiveDeps(serviceId, layerImpls, layersByService)\n\n    services.set(serviceId, {\n      serviceId,\n      className: tagInfo.className,\n      definitionFilePath: tagInfo.filePath,\n      definitionLocation: tagInfo.location,\n      definition: tagInfo.definition,\n      interfaceTypeText: tagInfo.interfaceTypeText,\n      layerImplementations: layerImpls,\n      consumers,\n      dependencies\n    })\n  }\n\n  // Track unresolved services (referenced but no tag definition)\n  // Include both requiredServices and serviceCall nodes (consumersByService)\n  const allReferenced = new Set(allReferencedServiceIds)\n  for (const refId of consumersByService.keys()) {\n    allReferenced.add(refId)\n  }\n  for (const refId of allReferenced) {\n    if (!services.has(refId)) {\n      unresolvedServices.push(refId)\n    }\n  }\n\n  // Step 5: Topological sort\n  const topologicalOrder = computeTopologicalOrder(services)\n\n  return {\n    services,\n    unresolvedServices,\n    topologicalOrder\n  }\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction collectLayersFromIR(\n  nodes: ReadonlyArray<StaticFlowNode>,\n  filePath: string,\n  knownServiceIds: ReadonlySet<string>,\n  identifierToServiceId: ReadonlyMap<string, string>,\n  layersByService: Map<string, Array<LayerImplementation>>,\n  ir: StaticEffectIR\n): void {\n  for (const node of nodes) {\n    if (node.type === \"layer\" && node.provides) {\n      for (const providedIdent of node.provides) {\n        const canonical = identifierToServiceId.get(providedIdent) ??\n          (knownServiceIds.has(providedIdent) ? providedIdent : undefined)\n        if (canonical && knownServiceIds.has(canonical)) {\n          const list = layersByService.get(canonical) ?? []\n          const requires = node.requires\n            ? node.requires\n              .map((r) => identifierToServiceId.get(r) ?? r)\n              .filter((r) => knownServiceIds.has(r))\n            : []\n          // Avoid duplicates\n          if (!list.some((l) => l.name === (node.name ?? ir.root.programName) && l.filePath === filePath)) {\n            list.push({\n              name: node.name ?? ir.root.programName,\n              filePath,\n              location: node.location ?? { filePath, line: 1, column: 0 },\n              kind: \"other\",\n              requires\n            })\n            layersByService.set(canonical, list)\n          }\n        }\n      }\n    }\n\n    const children = Option.getOrElse(getStaticChildren(node), () => [])\n    if (children.length > 0) {\n      collectLayersFromIR(children, filePath, knownServiceIds, identifierToServiceId, layersByService, ir)\n    }\n  }\n}\n","/**\n * Node analysis session.\n *\n * This is the single Node seam for configuring ts-morph and running file,\n * source, project, or coverage analysis. Importing internal analyzer modules is\n * deliberately not required to initialize the runtime.\n */\n\nimport \"./register-node-ts-morph\"\n\nimport type { Effect } from \"effect\"\nimport { analyze as analyzeFile } from \"./analyze\"\nimport {\n  analyzeProject,\n  analyzeProjectCorpus,\n  type AnalyzeProjectOptions,\n  type CoverageAuditResult,\n  type ProjectAnalysisResult,\n  runCoverageAudit,\n  runCoverageAuditFromCorpus\n} from \"./project-analyzer\"\nimport { type ProjectCorpus, scanProjectCorpus, type ScanProjectCorpusOptions } from \"./project-corpus\"\nimport { clearProjectCache } from \"./ts-morph-loader\"\nimport type { AnalysisError, AnalyzerOptions, StaticEffectIR } from \"./types\"\n\nexport interface AnalysisSession {\n  readonly file: (\n    filePath: string,\n    options?: AnalyzerOptions\n  ) => ReturnType<typeof analyzeFile>\n  readonly source: (\n    code: string,\n    options?: AnalyzerOptions\n  ) => ReturnType<typeof analyzeFile.source>\n  readonly corpus: (\n    dirPath: string,\n    options?: ScanProjectCorpusOptions\n  ) => Effect.Effect<ProjectCorpus>\n  readonly project: (\n    dirPath: string,\n    options?: AnalyzeProjectOptions\n  ) => Effect.Effect<ProjectAnalysisResult>\n  readonly projectFromCorpus: (\n    corpus: ProjectCorpus,\n    options?: AnalyzeProjectOptions\n  ) => Effect.Effect<ProjectAnalysisResult>\n  readonly audit: (\n    dirPath: string,\n    options?: AnalyzeProjectOptions\n  ) => Effect.Effect<CoverageAuditResult>\n  readonly auditFromCorpus: (\n    corpus: ProjectCorpus,\n    options?: AnalyzeProjectOptions\n  ) => Effect.Effect<CoverageAuditResult>\n  readonly clearCaches: () => void\n}\n\nexport const createAnalysisSession = (): AnalysisSession => ({\n  file: analyzeFile,\n  source: analyzeFile.source,\n  corpus: scanProjectCorpus,\n  project: analyzeProject,\n  projectFromCorpus: analyzeProjectCorpus,\n  audit: runCoverageAudit,\n  auditFromCorpus: runCoverageAuditFromCorpus,\n  clearCaches: clearProjectCache\n})\n\n/** Default session for ordinary Node callers. */\nexport const analysis = createAnalysisSession()\n\nexport type AnalysisEffect = Effect.Effect<\n  ReadonlyArray<StaticEffectIR>,\n  AnalysisError\n>\n","/** Diagram fidelity: whether the IR honestly represents the source program. */\n\nimport { assessIRFidelity, type FidelityFindingKind } from \"./fidelity-findings\"\nimport { indexIR, spanPathKey } from \"./ir\"\nimport type { SourceLocation, StaticEffectIR } from \"./types\"\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: ReadonlyArray<DiagramFidelityIssue>\n}\n\nexport const computeDiagramFidelity = (\n  ir: StaticEffectIR\n): DiagramFidelityReport => {\n  const assessment = assessIRFidelity(ir)\n  const issues: ReadonlyArray<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(\n      issues\n        .filter((issue) => issue.kind === \"duplicate-span-path\")\n        .map((issue) => issue.nodeId)\n    ).size,\n    unresolvedNodes: new Set(\n      issues\n        .filter((issue) => issue.kind !== \"duplicate-span-path\")\n        .map((issue) => issue.nodeId)\n    ).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${\n      report.issues.length === 1 ? \"\" : \"s\"\n    }`,\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: ReadonlyArray<string>\n): ReadonlyArray<string> => indexIR(ir).idsBySpanPath.get(spanPathKey(path)) ?? []\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: ReadonlyArray<string>\n  readonly status: RuntimeSpanStatus\n  readonly durationMs?: number | undefined\n}\n\nexport interface RuntimeTrace {\n  readonly spans: ReadonlyArray<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: ReadonlyArray<FlatSpan>): RuntimeTrace => {\n  const byId = new Map(spans.map((span) => [span.spanId, span] as const))\n  const pathFor = (span: FlatSpan, seen = new Set<string>()): ReadonlyArray<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: ReadonlyArray<Tracer.Span>\n): RuntimeTrace =>\n  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: ReadonlyArray<OpenTelemetryReadableSpan>\n): RuntimeTrace =>\n  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?: ReadonlyArray<SpanTreeNode> | undefined\n}\n\nexport interface SpanTree {\n  readonly spans: ReadonlyArray<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: Array<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","/**\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 { countMeaningfulNodes, DEFAULT_LABEL_MAX, truncateDisplayText } from \"../analysis-utils\"\nimport { buildDataFlowGraph } from \"../data-flow\"\nimport { analyzeErrorFlow, analyzeErrorPropagation } from \"../error-flow\"\nimport { indexIR, spanPathKey } from \"../ir\"\nimport type { RuntimeSpanStatus, RuntimeTrace } from \"../runtime-trace\"\nimport type {\n  EffectPath,\n  MermaidDetailLevel,\n  MermaidOptions,\n  MermaidStyles,\n  ProjectServiceMap,\n  StaticEffectIR,\n  StaticEffectNode,\n  StaticFiberNode,\n  StaticFlowNode,\n  StaticRetryNode\n} from \"../types\"\nimport { getStaticChildren } from \"../types\"\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:\n  & Required<\n    Omit<MermaidOptions, \"title\" | \"includeTypeSignatures\" | \"detail\" | \"dataFlowOverlay\" | \"errorFlowOverlay\">\n  >\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  /** Drawn dashed: a deferred step that sits outside the main sequence. */\n  dashed?: boolean\n}\n\ninterface Subgraph {\n  id: string\n  label: string\n  content: Array<string>\n}\n\ninterface RenderContext {\n  opts: ResolvedMermaidOptions\n  nodeCounter: number\n  edges: Array<Edge>\n  subgraphs: Array<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, Array<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: Array<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, Array<string>>\n): { lines: Array<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: Array<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    const arrow = edge.dashed ? \"-.->\" : \"-->\"\n    if (edge.label && (opts.showConditions || edge.dashed)) {\n      lines.push(`  ${edge.from} ${arrow}|${escapeLabel(edge.label)}| ${edge.to}`)\n    } else {\n      lines.push(`  ${edge.from} ${arrow} ${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: ReadonlyArray<StaticFlowNode>,\n  context: RenderContext,\n  lines: Array<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: Array<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 = 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?: Array<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(\" → \")}` : \"\"}${\n          node.sink && node.pipeline.at(-1)?.operation !== node.sink ? ` → ${node.sink}` : \"\"\n        }`,\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: Array<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 = 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      // acquire -> [operation] -> use -> release: the order the runtime runs them.\n      const acquireResult = renderNode(node.acquire, context, lines, depth + 1)\n      for (const lastId of acquireResult.lastNodeIds) {\n        context.edges.push({ from: lastId, to: nodeId })\n      }\n      let lastIds = [nodeId]\n      if (node.use) {\n        const useResult = renderNode(node.use, context, lines, depth + 1)\n        if (useResult.firstNodeId) {\n          context.edges.push({ from: nodeId, to: useResult.firstNodeId })\n          lastIds = useResult.lastNodeIds\n        }\n      }\n      const releaseResult = renderNode(node.release, context, lines, depth + 1)\n      // A scoped acquireRelease releases when its scope closes, after every\n      // later step, so the release hangs off the resource as a side edge.\n      if (releaseResult.firstNodeId && !node.use && node.resourceOperation?.startsWith(\"acquireRelease\")) {\n        context.edges.push({ from: nodeId, to: releaseResult.firstNodeId, label: \"on scope close\", dashed: true })\n      } else if (releaseResult.firstNodeId) {\n        const label = node.resourceOperation === \"onError\" ? \"on error\" : \"release\"\n        for (const lastId of lastIds) {\n          context.edges.push({ from: lastId, to: releaseResult.firstNodeId, label })\n        }\n        // onError cleanup runs only on failure; success skips it.\n        lastIds = node.resourceOperation === \"onError\"\n          ? [...lastIds, ...releaseResult.lastNodeIds]\n          : releaseResult.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: Array<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: Array<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: Array<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: Array<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 = 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 {\n          firstNodeId: causeId,\n          lastNodeIds: childResult.lastNodeIds.length > 0 ? childResult.lastNodeIds : [causeId]\n        }\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: Array<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      const sourceResult = node.source ? renderNode(node.source, context, lines, depth + 1) : undefined\n      if (sourceResult && sourceResult.lastNodeIds.length > 0) {\n        context.edges.push({ from: sourceResult.lastNodeIds[0]!, to: nodeId })\n      }\n      // A tap's callback runs alongside: a side branch, not the next step.\n      if (node.callback) {\n        const callbackResult = renderNode(node.callback, context, lines, depth + 1)\n        if (callbackResult.firstNodeId) {\n          context.edges.push({ from: nodeId, to: callbackResult.firstNodeId, label: node.transformType })\n        }\n      }\n      return { firstNodeId: sourceResult?.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({\n              from: sourceResult.lastNodeIds[0]!,\n              to: handlerResult.firstNodeId,\n              label: \"on interrupt\"\n            })\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: ReadonlyArray<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: ReadonlyArray<string>\n  readonly unmatchedSpanIds: ReadonlyArray<string>\n  readonly ambiguousSpanIds: ReadonlyArray<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: Array<string> = []\n  const suffixMatchedSpanIds: Array<string> = []\n  const unmatchedSpanIds: Array<string> = []\n  const ambiguousSpanIds: Array<string> = []\n  const usedStatuses = new Set<RuntimeSpanStatus>()\n  const assignments: Array<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: ReadonlyArray<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> => 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: ReadonlyArray<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: ReadonlyArray<DisplayPathStep>,\n  options: PathsMermaidOptions\n): Array<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: Array<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: ReadonlyArray<EffectPath>,\n  options: PathsMermaidOptions = {}\n): string {\n  const direction = options.direction ?? \"TB\"\n  const lines: Array<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, Array<string>> {\n  const map = new Map<string, Array<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: Array<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        if (node.use) visit(node.use)\n        visit(node.release)\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> => Effect.sync(() => renderEnhancedMermaid(ir, options))\n\n// =============================================================================\n// Enhanced diagram types (GAP 21)\n// =============================================================================\n\nfunction collectFiberNodes(\n  nodes: ReadonlyArray<StaticFlowNode>,\n  result: Array<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: Array<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: Array<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: ReadonlyArray<StaticFlowNode>,\n  result: Array<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: Array<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: Array<string> = [\"gantt\", \"  title Retry Schedule\", \"  section Attempts\"]\n  withSchedule.forEach((r, idx) => {\n    const info = r.scheduleInfo!\n    const max = 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: Array<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 { createGraph, genBFS, genCycles, getPathNodes, getTopologicalSort } from \"@statelyai/graph\"\nimport type { Graph } from \"@statelyai/graph\"\nimport { Option } from \"effect\"\nimport type { StaticEffectIR, StaticEffectNode, StaticFlowNode } from \"./types\"\nimport { getStaticChildren } from \"./types\"\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: Array<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: Array<DataFlowNode>\n  edges: Array<DataFlowEdge>\n  producedKeys: Set<string>\n  undefinedReads: Array<UndefinedRead>\n  duplicateWrites: Array<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: Array<string>\n}\n\n// =============================================================================\n// Execution-order collection (effect nodes only, sequential flow)\n// =============================================================================\n\nfunction collectEffectNodesInOrder(\n  nodes: ReadonlyArray<StaticFlowNode>,\n  result: Array<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: Array<DataFlowNode> = []\n  const edges: Array<DataFlowEdge> = []\n  const producedKeys = new Set<string>()\n  const keyProducers = new Map<string, Array<string>>()\n  const effectNodesOrdered: Array<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: Array<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: Array<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\n/** Step dependencies as a graph, without the implicit `__context__` source; one edge per step pair. */\nfunction toStepGraph(graph: DataFlowGraph): Graph {\n  const ids = new Set(graph.nodes.map((node) => node.id))\n  const pairs = new Set<string>()\n  const edges: Array<{ id: string; sourceId: string; targetId: string }> = []\n  for (const edge of graph.edges) {\n    const pair = JSON.stringify([edge.from, edge.to])\n    if (ids.has(edge.from) && ids.has(edge.to) && !pairs.has(pair)) {\n      pairs.add(pair)\n      edges.push({ id: `${edges.length}`, sourceId: edge.from, targetId: edge.to })\n    }\n  }\n  return createGraph({ nodes: graph.nodes.map((node) => ({ id: node.id })), edges })\n}\n\nexport function getDataFlowOrder(\n  graph: DataFlowGraph\n): Array<string> | undefined {\n  return getTopologicalSort(toStepGraph(graph))?.map((node) => node.id)\n}\n\nexport function getProducers(\n  graph: DataFlowGraph,\n  stepId: string\n): Array<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): Array<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): Array<string> {\n  return [...genBFS(toStepGraph(graph), { from: stepId, direction: \"incoming\" })]\n    .map((node) => node.id)\n    .filter((id) => id !== stepId)\n}\n\n/** Returns up to `limit` circular dependencies. */\nexport function findCycles(graph: DataFlowGraph, limit = 100): Array<Array<string>> {\n  const cycles: Array<Array<string>> = []\n  if (limit <= 0) return cycles\n  for (const cycle of genCycles(toStepGraph(graph))) {\n    cycles.push(getPathNodes(cycle).slice(0, -1).map((node) => node.id))\n    if (cycles.length >= limit) break\n  }\n  return cycles\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\nexport interface DataFlowValidation {\n  valid: boolean\n  issues: Array<DataFlowIssue>\n}\n\nexport interface DataFlowIssue {\n  severity: \"error\" | \"warning\"\n  type: \"undefined-read\" | \"duplicate-write\" | \"cycle\"\n  message: string\n  stepIds: Array<string>\n  key?: string\n}\n\nexport function validateDataFlow(graph: DataFlowGraph): DataFlowValidation {\n  const issues: Array<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: Array<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 { Option } from \"effect\"\nimport { splitTopLevelUnion } from \"./type-extractor\"\nimport type { StaticCauseNode, StaticEffectIR, StaticErrorHandlerNode, StaticFlowNode } from \"./types\"\nimport { getStaticChildren } from \"./types\"\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * What a handler does to the errors it takes off the channel. `catchTag` and\n * `orDie` both make `E` smaller, but one recovers from the error and the other\n * turns it into a defect that still crashes the fiber behind an `E` of `never`.\n */\nexport type ErrorDisposition =\n  /** Dealt with — the error is recovered from. */\n  | \"handled\"\n  /** Still in `E`, under a different type (mapError, orElseFail, sandbox). */\n  | \"transformed\"\n  /** Left `E` as a defect — `E` says `never`, the fiber can still die. */\n  | \"defect\"\n  /** Silently became a success (ignore, orElseSucceed). */\n  | \"swallowed\"\n\n/**\n * Which of the incoming errors a handler takes. `'none'` covers the `filter*`\n * operators: they test the success value, so they add to `E` (or add a defect)\n * without removing anything — `filterOrFail` is `Effect<A, E, R> => Effect<B, E2 | E, R>`.\n */\ntype HandlerScope = \"all\" | \"tags\" | \"partial\" | \"none\"\n\ninterface HandlerEntry {\n  readonly disposition: ErrorDisposition\n  readonly scope: HandlerScope\n  /** For operators that always take one known error, whatever `E` holds. */\n  readonly tags?: ReadonlyArray<string>\n}\n\nconst HANDLER_TABLE: Record<StaticErrorHandlerNode[\"handlerType\"], HandlerEntry> = {\n  catch: { disposition: \"handled\", scope: \"all\" },\n  catchCause: { disposition: \"handled\", scope: \"all\" },\n  catchDefect: { disposition: \"handled\", scope: \"all\" },\n  catchEager: { disposition: \"handled\", scope: \"all\" },\n  catchTag: { disposition: \"handled\", scope: \"tags\" },\n  catchTags: { disposition: \"handled\", scope: \"tags\" },\n  catchIf: { disposition: \"handled\", scope: \"partial\" },\n  catchSome: { disposition: \"handled\", scope: \"partial\" },\n  catchSomeCause: { disposition: \"handled\", scope: \"partial\" },\n  catchSomeDefect: { disposition: \"handled\", scope: \"partial\" },\n  catchFilter: { disposition: \"handled\", scope: \"partial\" },\n  catchCauseIf: { disposition: \"handled\", scope: \"partial\" },\n  catchCauseFilter: { disposition: \"handled\", scope: \"partial\" },\n  catchReason: { disposition: \"handled\", scope: \"partial\" },\n  catchReasons: { disposition: \"handled\", scope: \"partial\" },\n  // Exclude<E, Cause.NoSuchElementError> — one named error, never a share of\n  // whatever else `E` happens to hold. (Effect 3 spells it NoSuchElementException.)\n  catchNoSuchElement: {\n    disposition: \"handled\",\n    scope: \"tags\",\n    tags: [\"NoSuchElementError\", \"NoSuchElementException\"]\n  },\n  orElse: { disposition: \"handled\", scope: \"all\" },\n  filterOrElse: { disposition: \"handled\", scope: \"none\" },\n  firstSuccessOf: { disposition: \"handled\", scope: \"all\" },\n  match: { disposition: \"handled\", scope: \"all\" },\n  matchCause: { disposition: \"handled\", scope: \"all\" },\n  matchEffect: { disposition: \"handled\", scope: \"all\" },\n  matchCauseEffect: { disposition: \"handled\", scope: \"all\" },\n  eventually: { disposition: \"handled\", scope: \"all\" },\n  mapError: { disposition: \"transformed\", scope: \"all\" },\n  mapErrorCause: { disposition: \"transformed\", scope: \"all\" },\n  mapBoth: { disposition: \"transformed\", scope: \"all\" },\n  orElseFail: { disposition: \"transformed\", scope: \"all\" },\n  filterOrFail: { disposition: \"transformed\", scope: \"none\" },\n  sandbox: { disposition: \"transformed\", scope: \"all\" },\n  unsandbox: { disposition: \"transformed\", scope: \"all\" },\n  parallelErrors: { disposition: \"transformed\", scope: \"all\" },\n  flip: { disposition: \"transformed\", scope: \"all\" },\n  orDie: { disposition: \"defect\", scope: \"all\" },\n  orDieWith: { disposition: \"defect\", scope: \"all\" },\n  filterOrDie: { disposition: \"defect\", scope: \"none\" },\n  filterOrDieMessage: { disposition: \"defect\", scope: \"none\" },\n  ignore: { disposition: \"swallowed\", scope: \"all\" },\n  ignoreLogged: { disposition: \"swallowed\", scope: \"all\" },\n  orElseSucceed: { disposition: \"swallowed\", scope: \"all\" }\n}\n\n/** What this handler does to the errors it removes from the channel. */\nexport const errorDisposition = (\n  handlerType: StaticErrorHandlerNode[\"handlerType\"]\n): ErrorDisposition => lookupHandler(handlerType)?.disposition ?? \"handled\"\n\n/** IR can arrive from JSON, so a handler type this build does not know is possible. */\nconst lookupHandler = (\n  handlerType: StaticErrorHandlerNode[\"handlerType\"]\n): HandlerEntry | undefined => (HANDLER_TABLE as Partial<Record<string, HandlerEntry>>)[handlerType]\n\nexport interface StepErrorInfo {\n  stepId: string\n  stepName?: string | undefined\n  errors: Array<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: Array<string>\n  narrowedBy?: {\n    handler: StaticErrorHandlerNode[\"handlerType\"]\n    removedErrors: Array<string>\n    addedErrors: Array<string>\n  }\n  defects: Array<string>\n  interruptible: boolean\n}\n\nexport interface ErrorPropagationAnalysis {\n  propagation: Array<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: Array<string>\n  stepErrors: Array<StepErrorInfo>\n  errorToSteps: Map<string, Array<string>>\n  stepsWithoutErrors: Array<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: Array<string>\n  undeclaredErrors: Array<string>\n  computedErrors: Array<string>\n}\n\n// =============================================================================\n// Helpers: parse error type string (e.g. \"A | B\" or \"never\")\n// =============================================================================\n\n/**\n * Does a handler's tag name this error? Tags are bare (`'NoSuchElementError'`,\n * a `catchTag` literal); the checker may print the error qualified\n * (`Cause.NoSuchElementError` — a namespace member, `import * as`, Effect 3's\n * `declare namespace Cause`). Compare with the qualifier dropped, but keep the\n * qualified name as the error's identity everywhere else: `A.Error` and\n * `B.Error` are two errors, not one.\n */\nconst matchesTag = (error: string, tag: string): boolean =>\n  error === tag ||\n  error.replace(/^(?:[A-Za-z_$][\\w$]*\\.)+(?=[A-Za-z_$])/, \"\") === tag\n\nconst matchingAny = (errors: ReadonlyArray<string>, tags: ReadonlyArray<string>): Array<string> =>\n  errors.filter((e) => tags.some((tag) => matchesTag(e, tag)))\n\nfunction parseErrorTypes(errorType: string): Array<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: ReadonlyArray<StaticFlowNode>,\n  result: Array<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: Array<StepErrorInfo> = []\n  const allErrorsSet = new Set<string>()\n  const errorToSteps = new Map<string, Array<string>>()\n  const stepsWithoutErrors: Array<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: stepsWithoutErrors.length === 0 && stepErrors.length > 0\n  }\n}\n\n// =============================================================================\n// Error Propagation & Narrowing (GAP 4)\n// =============================================================================\n\nfunction unionErrors(a: Array<string>, b: Array<string>): Array<string> {\n  return Array.from(new Set([...a, ...b])).sort()\n}\n\nfunction withoutErrors(current: Array<string>, removed: Array<string>): Array<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): Array<string> {\n  const out: Array<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: ReadonlyArray<StaticFlowNode>,\n  errorsIn: Array<string>,\n  result: Array<ErrorPropagation>\n): Array<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: Array<string> = []\n      const entry = lookupHandler(handler.handlerType)\n      const scope = entry?.scope ?? \"all\"\n      const fixedTags = entry?.tags\n      if (scope === \"tags\") {\n        if (handler.handlerType === \"catchTag\" && handler.errorTag) {\n          // Remove the error under the spelling it is carried in; fall back to\n          // the bare tag when the source's errors could not be resolved at all.\n          const matched = matchingAny(sourceErrors, [handler.errorTag])\n          removed.push(...(matched.length > 0 ? matched : [handler.errorTag]))\n        } else if (handler.errorTags && handler.errorTags.length > 0) {\n          removed.push(...matchingAny(sourceErrors, handler.errorTags))\n        } else if (fixedTags) {\n          removed.push(...matchingAny(sourceErrors, fixedTags))\n        } else if (handler.handlerType === \"catchTags\") {\n          // Object-form catchTags without extracted keys: fall back to the\n          // heuristic that error-like names are the ones being caught.\n          removed.push(...sourceErrors.filter((e) => /Error$|^[A-Z]/.test(e)))\n        }\n        // A catchTag whose tag is not a literal removes nothing rather than guessing.\n      } else if (scope === \"partial\") {\n        // Predicate/reason catches remove a subset we cannot infer.\n        removed.push(...sourceErrors.slice(0, Math.ceil(sourceErrors.length / 2)))\n      } else if (scope !== \"none\") {\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: Array<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: Array<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): Array<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): Array<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: Array<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: 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: Array<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: Array<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 = 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","/**\n * Side-effect-free walkthroughs of an Effect program.\n *\n * `generatePaths` enumerates every path at once, which explodes combinatorially\n * and gives you no way to steer. A walkthrough is the other half: one step at a\n * time, with every branch offered as an explicit choice rather than guessed.\n * The timeline is immutable, so `rewind` truncates the future and lets another\n * branch be explored from any earlier point.\n *\n * Nothing is executed and no value is invented. Where the IR cannot say what\n * happens — an `unknown` or `opaque` node — the step says so instead of\n * pretending.\n */\n\nimport { Option } from \"effect\"\nimport { getStaticChildren, isStaticErrorHandlerNode, type StaticEffectIR, type StaticFlowNode } from \"./types\"\n\nexport type ChoiceKind =\n  | \"sequence\"\n  | \"success\"\n  | \"failure\"\n  | \"condition\"\n  | \"branch\"\n  | \"opaque\"\n\nexport interface WalkChoice {\n  readonly id: string\n  readonly label: string\n  readonly kind: ChoiceKind\n  /** The node this choice would step onto. */\n  readonly nodeId: string\n}\n\nexport interface WalkStep {\n  readonly nodeId: string\n  readonly label: string\n  /** How this step was reached; absent for the plain sequential case. */\n  readonly via?: ChoiceKind\n}\n\n/**\n * A position in a program: what has happened, and what can happen next.\n *\n * Opaque by design — the cursor it carries is an implementation detail, so a\n * walkthrough can only be moved with `advance`, `advanceWhileLinear`, and\n * `rewind`.\n */\nexport interface Walkthrough {\n  readonly timeline: ReadonlyArray<WalkStep>\n  /** What can happen next. Empty exactly when `done`. */\n  readonly choices: ReadonlyArray<WalkChoice>\n  readonly done: boolean\n  readonly [CursorId]: Cursor\n}\n\n/**\n * Key for the walk cursor. Exported only because it appears in `Walkthrough`;\n * a symbol keeps the cursor out of spreads, JSON, and consumer code.\n *\n * @internal\n */\nexport const CursorId: unique symbol = Symbol(\"effect-analyzer/walkthrough-cursor\")\n\ninterface Cursor {\n  /** Nodes still to visit, outermost first. */\n  readonly frontier: ReadonlyArray<StaticFlowNode>\n  /** The IR being walked, so `rewind` can replay from the start. */\n  readonly ir: StaticEffectIR\n  /** Choice ids taken so far, replayed by `rewind`. */\n  readonly taken: ReadonlyArray<string>\n}\n\n/** Wrappers that carry no step of their own — step into their children. */\nconst isTransparent = (node: StaticFlowNode): boolean => node.type === \"generator\" || node.type === \"pipe\"\n\nconst labelOf = (node: StaticFlowNode): string => {\n  const named = node as { displayName?: string; name?: string; callee?: string }\n  return named.displayName ?? named.name ?? named.callee ?? node.type\n}\n\nconst childrenOf = (node: StaticFlowNode): ReadonlyArray<StaticFlowNode> =>\n  Option.getOrElse(getStaticChildren(node), () => [] as ReadonlyArray<StaticFlowNode>)\n\n/** Expand wrappers until the head of the frontier is a node worth showing. */\nfunction normalize(frontier: ReadonlyArray<StaticFlowNode>): ReadonlyArray<StaticFlowNode> {\n  const [head, ...rest] = frontier\n  if (head === undefined) return []\n  if (!isTransparent(head)) return frontier\n  return normalize([...childrenOf(head), ...rest])\n}\n\nfunction choicesFor(frontier: ReadonlyArray<StaticFlowNode>): ReadonlyArray<WalkChoice> {\n  const [head, ...rest] = frontier\n  if (head === undefined) return []\n\n  if (isStaticErrorHandlerNode(head)) {\n    const success: WalkChoice = {\n      id: `${head.id}:success`,\n      label: `${labelOf(head)} — succeeds`,\n      kind: \"success\",\n      nodeId: head.source.id\n    }\n    if (!head.handler) return [success]\n    return [\n      success,\n      {\n        id: `${head.id}:failure`,\n        label: `${labelOf(head)} — fails, handler runs`,\n        kind: \"failure\",\n        nodeId: head.handler.id\n      }\n    ]\n  }\n\n  if (head.type === \"conditional\" || head.type === \"decision\" || head.type === \"switch\") {\n    return childrenOf(head).map((child, index) => ({\n      id: `${head.id}:cond:${index}`,\n      label: `${labelOf(head)} — ${labelOf(child)}`,\n      kind: \"condition\" as const,\n      nodeId: child.id\n    }))\n  }\n\n  if (head.type === \"race\" || head.type === \"parallel\") {\n    return childrenOf(head).map((child, index) => ({\n      id: `${head.id}:branch:${index}`,\n      label: `${labelOf(head)} — ${labelOf(child)}`,\n      kind: \"branch\" as const,\n      nodeId: child.id\n    }))\n  }\n\n  if (head.type === \"unknown\" || head.type === \"opaque\") {\n    return [\n      {\n        id: `${head.id}:opaque`,\n        label: `${labelOf(head)} — not analyzable, contents unknown`,\n        kind: \"opaque\",\n        nodeId: head.id\n      }\n    ]\n  }\n\n  void rest\n  return [\n    {\n      id: `${head.id}:next`,\n      label: labelOf(head),\n      kind: \"sequence\",\n      nodeId: head.id\n    }\n  ]\n}\n\nconst build = (\n  ir: StaticEffectIR,\n  frontier: ReadonlyArray<StaticFlowNode>,\n  timeline: ReadonlyArray<WalkStep>,\n  taken: ReadonlyArray<string>\n): Walkthrough => {\n  const normalized = normalize(frontier)\n  const choices = choicesFor(normalized)\n  return {\n    timeline,\n    choices,\n    done: choices.length === 0,\n    [CursorId]: { frontier: normalized, ir, taken }\n  }\n}\n\nconst cursorOf = (walk: Walkthrough): Cursor => walk[CursorId]\n\n/** Start at the top of a program with nothing taken yet. */\nexport function beginWalkthrough(ir: StaticEffectIR): Walkthrough {\n  return build(ir, ir.root.children, [], [])\n}\n\n/** Take one offered choice. Throws if the id is not currently on offer. */\nexport function advance(walk: Walkthrough, choiceId: string): Walkthrough {\n  const choice = walk.choices.find((c) => c.id === choiceId)\n  if (!choice) {\n    throw new Error(\n      `Choice \"${choiceId}\" is not available. On offer: ${walk.choices.map((c) => c.id).join(\", \") || \"(none)\"}`\n    )\n  }\n\n  const { frontier, ir, taken } = cursorOf(walk)\n  const [head, ...rest] = frontier\n  if (head === undefined) return walk\n\n  const next = ((): ReadonlyArray<StaticFlowNode> => {\n    if (isStaticErrorHandlerNode(head)) {\n      return choice.kind === \"failure\" && head.handler\n        ? [head.source, head.handler, ...rest]\n        : [head.source, ...rest]\n    }\n    if (choice.kind === \"condition\" || choice.kind === \"branch\") {\n      const child = childrenOf(head).find((c) => c.id === choice.nodeId)\n      return child ? [child, ...rest] : rest\n    }\n    return rest\n  })()\n\n  // The error-handler frontier is re-entered rather than consumed, so the step\n  // is recorded only once the concrete node underneath is taken.\n  const timeline = head.type === \"error-handler\"\n    ? walk.timeline\n    : [\n      ...walk.timeline,\n      {\n        nodeId: choice.nodeId,\n        label: labelOf(head),\n        ...(choice.kind === \"sequence\" ? {} : { via: choice.kind })\n      }\n    ]\n\n  return build(ir, next, timeline, [...taken, choiceId])\n}\n\n/** Follow the program while exactly one thing can happen next. */\nexport function advanceWhileLinear(walk: Walkthrough): Walkthrough {\n  let current = walk\n  for (let only = current.choices[0]; current.choices.length === 1 && only; only = current.choices[0]) {\n    current = advance(current, only.id)\n  }\n  return current\n}\n\n/**\n * Return to the state after `stepCount` steps, discarding everything after it.\n * Replays the retained choices, so the result is a real walkthrough that can be\n * advanced down a different branch.\n */\nexport function rewind(walk: Walkthrough, stepCount: number): Walkthrough {\n  if (stepCount >= walk.timeline.length) return walk\n  const { ir, taken } = cursorOf(walk)\n  let current = beginWalkthrough(ir)\n  for (const choiceId of taken) {\n    if (current.timeline.length >= stepCount) break\n    current = advance(current, choiceId)\n  }\n  return current\n}\n"],"mappings":"ubAAA,IAAAA,GAAA,GAAAC,GAAAD,GAAA,aAAAE,GAAA,uBAAAC,GAAA,aAAAC,GAAA,qBAAAC,GAAA,qBAAAC,GAAA,2BAAAC,GAAA,0BAAAC,GAAA,0BAAAC,GAAA,kCAAAC,GAAA,wBAAAC,GAAA,WAAAC,GAAA,yBAAAC,GAAA,2BAAAC,GAAA,sBAAAC,KAAA,eAAAC,GAAAhB,ICAA,IAAAiB,GAA8B,kBCA9B,IAAAC,GAAA,GAcIC,GAAsC,KACtCC,GAAsC,KACpCC,GAAe,IAAI,IAMnBC,GAAoBC,GACF,WAAiD,SAClD,mBAAmBA,CAAE,EAGtCC,GAAkB,IAA4B,CAClD,IAAMC,EAAgBH,GAAiB,aAAa,GAAKA,GAAiB,QAAQ,EAC5EI,EAAgBD,GAClB,OAAOA,GAAkB,UACzB,kBAAmBA,EAClBA,EAAc,cACf,OAEJ,GAAI,CAACC,EACH,OAAO,KAGT,GAAI,CAEF,OADgBA,EAAcR,GAAY,GAAG,EAC9B,UAAU,CAC3B,MAAQ,CACN,OAAO,IACT,CACF,EAMO,IAAMS,GAAoBC,GAAgC,CAC/DC,GAAgBD,EAChBE,GAAgB,IAClB,EAQO,IAAMC,EAAc,IAAqB,CAC9C,GAAIC,GACF,OAAOA,GAGT,IAAMC,EAAmBC,KAAgB,GAAKC,GAAgB,EAE9D,GAAI,CAACF,EACH,MAAM,IAAI,MACR,0JACF,EAGF,OAAAD,GAAgBC,EACTA,CACT,EAEaG,GAAiBC,GAAmC,CAC/D,IAAMC,EAAWD,GAAgB,cAC3BE,EAASC,GAAa,IAAIF,CAAQ,EACxC,GAAIC,EACF,OAAOA,EAGT,GAAM,CAAE,QAAAE,CAAQ,EAAIV,EAAY,EAC1BW,EAAyC,CAAC,EAC5CL,IACFK,EAAQ,iBAAmBL,GAE7B,IAAMM,EAAU,IAAIF,EAAQC,CAAO,EACnC,OAAAF,GAAa,IAAIF,EAAUK,CAAO,EAC3BA,CACT,EAEaC,GAAoB,IAAY,CAC3CJ,GAAa,MAAM,CACrB,EAEaK,GAA0B,CACrCC,EACAC,EAAW,YACI,CACf,GAAM,CAAE,QAAAN,CAAQ,EAAIV,EAAY,EAQhC,OAPgB,IAAIU,EAAQ,CAC1B,sBAAuB,GACvB,gBAAiB,CACf,OAAQ,GACR,gBAAiB,EACnB,CACF,CAAC,EACc,iBAAiBM,EAAUD,CAAI,CAChD,EDjHA,IAAAE,GAAA,GAKaC,GAAqB,OAAO,YAAe,SAAW,WAAaD,GAAY,IAE5FE,GAAiB,OACC,kBAAcD,EAAkB,EACjC,UAAU,CAC1B,EEkBD,IAAAE,EAA+B,kBCjB/B,IAAAC,GAAuB,kBCNvB,IAAAC,GAAuB,kBCsBhB,IAAMC,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,CAC1C,UACA,UACA,UACA,WACA,cACA,gBACA,YACA,UACA,UACA,WACA,MACA,KACA,SACF,CAAC,EAEYC,GAAiB,IAAI,IAA0C,CAC1E,MACA,UACA,WACA,cACA,gBACA,WACF,CAAC,EAQM,IAAMC,GAAmBC,GAA4BA,KAAUC,GAEzDC,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,GAAeJ,GAA4BA,EAAO,WAAW,QAAQ,GAAKA,KAAUE,GAEpFG,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,GAAeP,GAA4BA,EAAO,WAAW,QAAQ,GAAKA,KAAUK,GAEpFG,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,GAAcV,GACzBA,EAAO,WAAW,OAAO,IAAMA,KAAUQ,IAAe,cAAc,KAAKR,CAAM,GAEtEW,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,GAAkBZ,GAC7BA,EAAO,WAAW,WAAW,IAAMA,KAAUW,IAAmB,kBAAkB,KAAKX,CAAM,GAElFa,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,QACA,gBACA,SACA,SACA,UACA,SACA,WACA,UACA,OACA,OACA,SACA,QACA,MACA,MACA,UACA,UACA,SACA,SACA,OACA,UACA,UACA,SACA,eACA,SACA,WACA,iBACF,CAAC,EAEYC,GAA0B,IAAI,IAAI,CAE7C,SACA,QACA,SACA,QACA,SACA,WACA,YACA,UACA,kBACA,QACA,QACA,UACA,iBACA,QACA,OAEA,OACA,SACA,SACA,QACA,UACA,UACA,OACA,YACA,YAEA,QACA,SACA,SACA,WACA,IAEA,SACA,SACA,SAEA,WACA,cACA,WACA,WAEA,QACA,cACA,cACA,aAEA,MACA,kBACA,UAEA,SACA,QACA,WACA,WACA,YACA,QACA,SACA,SACA,WACA,QACA,cACA,QACA,cACA,QACA,OACA,SACA,QACA,QACA,WAEA,OACA,UACA,UACA,OAEA,MACA,OACA,OACA,OACA,SACA,SACA,UACA,YACA,aAEA,oBACA,qBACA,kBACA,oBACA,qBACA,aACA,kBACA,eACA,UACA,iBACA,kBACA,iBACA,kBACA,iBACA,gBAEA,UAEA,YACA,cACA,cAEA,MACA,YACA,WACA,SACA,mBAEA,SACA,gBACA,eACA,WAEA,UACA,MACA,UACA,YACA,WAEA,YACA,cACA,UACA,aAEA,UACA,QACF,CAAC,EAEYC,GAAsBnB,GAC7BA,EAAO,SAAS,GAAG,GACnBkB,GAAwB,IAAIlB,CAAM,EAAU,GACzC,sBAAsB,KAAKA,CAAM,EAO7BoB,GAA0BpB,GAAuC,CAC5E,GAAIA,EAAO,WAAW,UAAU,EAAG,MAAO,UAC1C,GAAIA,EAAO,WAAW,OAAO,EAAG,MAAO,OACvC,GAAIA,EAAO,SAAS,QAAQ,EAAG,MAAO,QACtC,GAAIA,EAAO,SAAS,OAAO,EAAG,MAAO,cACrC,GAAIA,EAAO,SAAS,eAAe,EAAG,MAAO,kBAE7C,GADIA,EAAO,SAAS,KAAK,GACrBA,EAAO,SAAS,aAAa,EAAG,MAAO,gBAC3C,GACEA,EAAO,SAAS,QAAQ,GACxBA,EAAO,SAAS,cAAc,GAC9BA,EAAO,SAAS,UAAU,GAC1BA,EAAO,SAAS,OAAO,GACvBA,EAAO,SAAS,UAAU,GAC1BA,EAAO,SAAS,UAAU,GAC1BA,EAAO,SAAS,OAAO,GAC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","names":["src_exports","__export","advance","advanceWhileLinear","analysis","assessIRFidelity","beginWalkthrough","computeDiagramFidelity","createAnalysisSession","formatDiagramFidelity","renderMermaidWithRuntimeTrace","renderStaticMermaid","rewind","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","clearProjectCache","createProjectFromSource","code","filePath","import_meta","nodeModuleLocation","setTsMorphLoader","import_effect","import_effect","import_effect","ERROR_HANDLER_PATTERNS","CONDITIONAL_PATTERNS","RESOURCE_PATTERNS","COLLECTION_PATTERNS","FIBER_PATTERNS","TRANSFORM_OPS","EFFECTFUL_TRANSFORMS","TAP_TRANSFORMS","isTransformCall","callee","TRANSFORM_OPS","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","ERROR_HANDLER_PATTERNS","CONDITIONAL_PATTERNS","RESOURCE_PATTERNS","COLLECTION_PATTERNS","FIBER_PATTERNS","getSemanticDescriptionWithAliases","effectAliases","direct","dotIndex","prefix","method","isLikelyDirectEffectInitializer","initializer","effectImportNames","nonProgramEffectImportNames","SyntaxKind","loadTsMorph","isNonProgramName","name","isRunEntrypointCalleeText","exprText","isDirectEffectCalleeText","isPipeCall","alias","isLikelyEffectCall","call","isMethodPipeCall","arg","base","isInSameScope","node","scope","current","k","blockContainsEffectLikeUsage","block","awaitExpr","expr","blockContainsRunEntrypointUsage","prop","init","body","bodyBlock","ret","awaited","conditional","text","isEffectPackageSpecifier","specifier","EFFECT_NAMESPACE_NAMES","KNOWN_INTERNAL_MODULES","parseServiceIdsFromContextType","requiredType","skip","normalized","s","getNumericLiteralFromNode","kind","n","unary","operand","v","EFFECT_TYPE_REGEX_3","EFFECT_TYPE_REGEX_2","taggedErrorTagsFromType","type","part","apparent","tagsFromTagProperty","own","symbol","tags","declaration","tagged","tagProperty","tagType","value","quoted","withErrorTags","signature","errorType","node","fromType","fromSource","taggedErrorTagsFromSource","errorTags","errorTypeName","sourceFile","name","cls","text","field","effectTypeSignatureFromTypeText","typeText","clean","s","match3","match2","tryResolveGenericFromInnerExpression","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","decl","returnTypeText","sigs","retType","retArgs","fromAnnotation","aliasSymbol","aliasName","aliasTypeArgs","extractServiceRequirements","requirements","locationNode","nodeTypeArgs","parent","varDecl","declaredType","extractRequirementsType","services","extractServicesFromContext","service","offset","line","column","location","contextType","contextMatch","extractTagIdentifier","parts","splitTopLevelUnion","match","splitTopLevelUnion","typeText","parts","current","depth","inString","i","ch","last","cleanTypeArg","s","LAYER_TYPE_REGEX","extractLayerTypeSignature","node","typeText","match","LAYER_TYPE_REGEX","cleanTypeArg","import_effect","AnalysisError","code","message","location","isStaticErrorHandlerNode","node","getStaticChildren","node","y","retryNode","list","n","src","op","children","c","EFFECT_RUNTIME_PRIMITIVE_NAMES","isRuntimePrimitiveDependency","name","firstSegment","CANONICAL_EFFECT_SERVICE_NAMES","canonicalizeServiceDisplayName","DEFAULT_OPTIONS","idCounter","resetIdCounter","generateId","isConcurrent","concurrency","nodeTextCache","getNodeText","node","text","programErrorTypes","programErrorType","nodes","err","splitTopLevelUnion","collectErrorTypes","set","visit","list","part","children","getStaticChildren","collectDependencies","byName","reqs","r","displayName","callee","looksLikeService","KNOWN_EFFECT_NAMESPACES","BUILT_IN_TYPE_NAMES","extractLocation","filePath","includeLocations","sourceFile","pos","line","column","endPos","end","extractJSDocDescription","jsDocs","firstJsDoc","comment","description","c","tagIndex","rawText","descriptionMatch","leadingComments","lastComment","commentText","cleaned","extractJSDocTags","tryGetJsDocText","n","SyntaxKind","loadTsMorph","current","kind","grandparent","parseJSDocTags","params","returns","throws","example","tagPattern","match","tag","rest","paramMatch","value","exampleStart","nextTagMatch","getJSDocFromParentVariable","parent","parentKind","isJsOrJsxPath","path","extractYieldVariableName","yieldNode","extractProgramName","getEnclosingVariableName","start","propertyName","containerName","ancestor","depth","extractEnclosingEffectFnName","callExpr","exprText","args","firstArg","createEmptyStats","DEFAULT_LABEL_MAX","truncateDisplayText","s","max","DEFAULT_LABEL_MAX","truncate","extractFunctionName","callee","withoutArgs","parts","receiver","KNOWN_EFFECT_NAMESPACES","BUILT_IN_TYPE_NAMES","computeDisplayName","node","variableName","fnName","wrapper","truncate","ops","op","channelOps","sinkOps","countMeaningfulNodes","nodes","count","walk","list","children","getStaticChildren","computeSemanticRole","desc","unwrapExpression","expr","SyntaxKind","loadTsMorph","import_effect","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","import_effect","createAnalysisContext","getAnalyze","withServiceScope","deps","serviceScope","node","sourceFile","filePath","opts","warnings","stats","scope","bindAnalysisContext","context","analyzer","args","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","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","channelOpCategory","op","sinkOpCategory","parseEffectAllOptions","optionsNode","SyntaxKind","loadTsMorph","concurrency","batching","discard","prop","isShorthand","name","init","text","type","literal","DURATION_UNITS","parseScheduleInfo","scheduleText","baseStrategy","maxRetries","recursMatch","recurUpToMatch","timesMatch","delayMatch","initialDelay","jittered","conditions","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","lastArg","concurrency","parseEffectAllOptions","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","outerDeps","serviceScope","withServiceScope","transformType","TRANSFORM_OPS","isEffectful","EFFECTFUL_TRANSFORMS","source","fnText","callback","callbackArg","TAP_TRANSFORMS","callbackKind","transformNode","import_effect","classifyErrorHandlerName","callee","analyzeErrorHandlerCall","outerDeps","call","sourceFile","filePath","opts","warnings","stats","serviceScope","deps","withServiceScope","args","handlerType","source","handler","SyntaxKind","loadTsMorph","isEffect","n","isHandlerShaped","isDataFirstSource","analyze","analyzeHandler","expr","receiver","handlerArg","generateId","errorTag","errorTags","tagHandlers","tagArg","a","objArg","p","body","tag","t","handlerNode","extractLocation","computeDisplayName","computeSemanticRole","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","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","isConcurrent","branchLabels","child","computeDisplayName","parallelNode","generateId","extractLocation","computeSemanticRole","analyzeRaceCall","arg","raceLabels","raceNode","import_effect","analyzeResourceCall","outerDeps","call","callee","sourceFile","filePath","opts","warnings","stats","serviceScope","deps","withServiceScope","args","resourceOperation","acquire","release","useEffect","generateId","expr","receiver","loadTsMorph","propAccess","exprSource","resourceNode","extractLocation","computeDisplayName","computeSemanticRole","import_effect","followConst","node","SyntaxKind","loadTsMorph","current","hop","symbol","init","d","optionValue","obj","name","prop","shorthand","asOptions","resolveRetryPolicy","policy","resolved","options","scheduleArg","scheduleExpr","scheduleText","times","info","parseScheduleInfo","predicates","splitPolicyCall","call","sourceFile","args","expr","receiver","getAliasesForFile","analyzePolicySource","deps","sourceNode","filePath","opts","warnings","stats","generateId","analyzeRetryCall","split","source","schedule","scheduleInfo","scheduleNode","hasFallback","retryNode","extractLocation","computeDisplayName","computeSemanticRole","analyzeTimeoutCall","durationArg","duration","getNodeText","calleeText","timeoutNode","analyzeScheduleCall","callee","scheduleOp","SCHEDULE_OP_MAP","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","import_effect","classifyStreamOperator","op","classifyStreamConstructor","callee","opName","constructorType","analyzeStreamCall","deps","call","sourceFile","filePath","opts","warnings","stats","serviceScope","args","SyntaxKind","loadTsMorph","baseExpr","analyzedBase","effectiveSource","pipeline","sink","backpressureStrategy","arg","analyzed","bareOp","category","streamNode","generateId","extractLocation","computeDisplayName","computeSemanticRole","isStreamArg","streamArgs","dataLast","isMerge","branchArgs","branches","source","isEffectful","callbackArg","callbackBody","buildCallbackSummaryNodes","buildPureCallbackSummaryNodes","opCategory","cardinality","windowSize","stride","getNumericLiteralFromNode","thisOp","effectiveConstructorType","srcStream","analyzeChannelCall","channelOpCategory","srcChan","channelNode","analyzeSinkCall","sinkOpCategory","srcSink","sinkNode","analysisContext","createAnalysisContext","analyzeEffectExpression","analyzeStreamCall","bindAnalysisContext","analyzeChannelCall","analyzeSinkCall","analyzeRetryCall","analyzeTimeoutCall","analyzeFiberCall","analyzeInterruptionCall","analyzeParallelCall","analyzeRaceCall","analyzeErrorHandlerCall","analyzeResourceCall","analyzeConditionalCall","analyzeLoopCall","analyzeCauseCall","analyzeTransformCall","SCHEMA_OPS","EFFECT_PIPE_OP_REGEX","pipeArgsIncludeEffectOp","call","arg","asErrorHandler","analyzed","stats","loadTsMorph","text","ERROR_HANDLER_PATTERNS","pattern","handlerType","classifyErrorHandlerName","node","generateId","computeDisplayName","computeSemanticRole","analyzePipeChain","sourceFile","filePath","opts","warnings","serviceScope","SyntaxKind","args","expr","isMethodPipe","baseExpr","transformArgs","baseNode","resolveIdentifierToLayerInitializer","baseSourceFile","basePath","project","inProject","added","initial","transformations","sourceOrderedSpanNames","spanNameDynamic","filteredTransformations","t","argText","match","spanNames","spanName","typeFlow","typeChecker","flow","initialSig","extractEffectTypeSignature","argNode","sig","innerSpanNames","mergedSpanNames","innermost","pipeNode","unwrapExpression","ternary","analyzeBranch","branch","whenTrue","whenFalse","condition","decisionNode","extractLocation","body","unknownNode","returnedExpr","stmt","analyzeEffectCall","operation","objectText","propertyName","serviceId","serviceEffectNode","isLikelyServiceStreamProperty","streamNode","inferredServiceCall","tryResolveServicePropertyAccess","isEffectCallee","getAliasesForFile","effectNode","normalizeEffectCallee","objLit","HANDLER_PROPS","props","handlerEntries","hasKnownHandler","prop","assignment","propName","initializer","tagText","newExpr","ctorText","ctorName","type","typeText","isYieldableError","unknownReason","callee","normalizedCallee","calleeOperation","location","isEffectMethodPipe","nodes","baseCallText","baseText","baseCallOrExprText","analyzeLayerCall","layerNode","analyzeConcurrencyPrimitiveCall","FIBER_PATTERNS","p","INTERRUPTION_PATTERNS","resourceOps","resourceOpPrefixes","isResourceOp","op","baseCall","baseCallee","baseOperation","conditionalOp","CONDITIONAL_PATTERNS","isSchemaOp","collectionOp","COLLECTION_PATTERNS","isTransformCall","isMatchCall","analyzeMatchCall","isCauseCall","isExitCall","analyzeExitCall","isScheduleCall","analyzeScheduleCall","callbackBody","usePattern","isConstructorWithCallback","c","asyncCallback","firstArg","fn","innerNodes","block","retExpr","isEffectLikeCallExpression","resumeParamName","resumeCallCount","visit","returnsCanceller","k","handlerSummaries","summarizeNamedCallbackHandlers","propAccess","callbackArg","callbackFn","callbackNodes","buildCallbackSummaryNodes","wrapperExpr","classifyUseCallbackKind","effectJSDoc","extractJSDocDescription","typeSignature","requiredServices","extractServiceRequirements","serviceCall","tryResolveServiceCall","serviceMethod","methodName","provideKind","contextArgText","constructorKind","fiberRefName","KNOWN_FIBER_REFS","refName","tracedName","strMatch","innerCall","innerCallee","fnArgs","wrappedCall","LIFTING_CALLEES","liftedCallName","wrappedAssignment","liftedAssignmentTarget","filteredRequiredServices","service","isEffectRuntimePrimitive","getSemanticDescriptionWithAliases","extractJSDocTags","TsNode","returned","liftedResult","inner","name","liftedThunk","thunk","tryProp","blockResult","result","target","statements","only","objExpr","objectName","firstSegment","KNOWN_EFFECT_NAMESPACES","normalized","normalizedFirstSegment","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","WORKFLOW_FACTORY_NAMES","isWorkflowFactoryCall","calleeText","name","isWorkflowMakeCall","call","expr","loadTsMorph","prop","args","third","SyntaxKind","isWorkflowPackageSpecifier","specifier","_currentFilePath","isWorkflowNamespaceFromPackage","localName","isActivityNamespaceFromPackage","objectArgHasAnyProperty","propertyNames","arg","props","names","p","isWorkflowMakeOptionsCall","importSpecifierByLocalName","currentFilePath","baseText","isActivityMakeOptionsCall","getWorkflowBodyNodeForRunCall","runCall","sourceFile","innerCall","varDecls","decl","initializer","isInsideEffectGen","node","current","text","isTopLevelVariableDeclaration","isYieldBoundDeclaration","getCallExpressionFromInitializer","awaited","buildDiscoveryInfo","discoveryConfidence","discoveryReason","EFFECT_FAMILY_TYPE_HINTS","hasEffectFamilyTypeHint","hint","DISCOVERY_CONFIDENCE_RANK","isRunCall","exprText","bodyContainsRunMainOrRunPromise","body","isIndirectRunMainWrapper","_sourceFile","kind","init","isRuntimeCurriedForm","innerExprText","findEffectPrograms","_opts","programs","seenCallStarts","workflowProgramBuilders","effectImportNames","getEffectLikeNamespaceAliases","nonProgramEffectImportNames","getNonProgramEffectImportNames","importDecl","def","ns","named","inferAliasBackedDiscovery","aliasName","isSpecifierUnderKnownEffectInternalsRoot","inferDirectInitializerDiscovery","inferFromNestedEffectAliasUsage","propertyAccesses","base","calls","c","callee","local","nested","inferTypeAnnotatedDiscovery","typeText","n","isExportedDecl","fnReturnTypeText","typeArgText","isProgramRootExported","program","inferMethodReturnDiscovery","returnStatements","ret","isLikelyDirectEffectInitializer","filePath","varDeclarations","initCall","genCalls","expression","callStart","isWorkflowInvocation","propertyAccess","objectText","methodName","extractProgramName","isEffectLikeCallExpression","extractEnclosingEffectFnName","pipeName","hasEffectInArgs","callInitializer","looksLikeEffect","typeDiscovery","topLevelStatements","stmt","calleeExpr","lastArg","lastArgText","baseName","DATA_SCHEMA_CLASS_PATTERNS","classDeclarations","classDecl","clause","clauseText","topLevelClasses","parent","className","members","properties","m","memberName","fullName","methods","method","getters","getter","functionDeclarations","fnDecl","returnTypeNode","threshold","confidence","alias","extractServiceDefinitionsFromFile","results","typeChecker","extExpr","extText","typeArgs","inner","interfaceTypeNode","type","sym","propName","classText","hasCustomEquality","hasCustomHash","r","analyzeProgram","program","sourceFile","filePath","opts","tsVersion","warnings","stats","createEmptyStats","children","analyzeProgramNode","programJSDoc","getJSDocFromParentVariable","typeChecker","typedNode","findOuterPipeOnGen","typeSignature","extractEffectTypeSignature","requiredServices","extractServiceRequirements","root","generateId","collectDependencies","programErrorTypes","extractLocation","extractJSDocTags","serviceDefinitions","extractServiceDefinitionsFromFile","node","programType","genCall","args","genChildren","analyzeGeneratorFunction","outerPipe","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","containsEarlyReturn","TsNode","found","child","containsGeneratorYield","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","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","switchStmt","clauses","hasFallthrough","hasDefault","currentLabels","currentBodyYields","currentIsDefault","caseClause","clauseStmts","clauseStmt","y","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","retStmt","descendantCalls","entry","valueText","earlyReturn","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","c","argCall","argExprText","text","argArgs","location","source","schedule","scheduleInfo","scheduleExpr","resolveRetryPolicy","scheduleNode","retryNode","lastArg","lastArgText","analyzeEffectFile","filePath","options","opts","DEFAULT_OPTIONS","ts","Project","loadTsMorph","project","isJsOrJsxPath","createProject","error","AnalysisError","existingFile","sourceFile","programs","findEffectPrograms","program","analyzeProgram","analyzeEffectSource","code","createProjectFromSource","createResult","programs","program","AnalysisError","p","name","found","available","analyze","filePath","options","resetIdCounter","programsEffect","analyzeEffectFile","code","analyzeEffectSource","import_effect","import_fs","import_promises","import_path","dimension","numerator","denominator","emptyRate","assessAudit","input","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","import_path","FEATURE_ORDER","describeText","text","fallback","trimmed","detectStageKind","expr","Node","describeStage","getPropertyExpression","objectLiteral","name","prop","extractNestedHandlers","inferCapabilities","summary","features","feature","isMakeProgramCall","call","expression","isCommandDefineCall","runtimeNameForCall","filePath","ordinal","parent","isLayerCall","isLayerAssemblyRoot","getLayerAssemblyName","extractLayerAssembly","operations","references","collectLayerRefs","collectLayerCall","element","current","exprText","pipeBase","arg","extractProjectArchitecture","filePaths","options","Project","loadTsMorph","project","sourceFiles","commands","runtimes","layerAssemblies","sourceFile","runtimeOrdinal","layerOrdinal","node","variableName","firstArg","commandName","layerName","configArg","runtimeName","model","flagsSchema","flags","init","update","view","container","subscriptions","resources","managedResources","routing","crash","slowView","title","devtools","baseRuntime","commandsByFile","command","runtime","import_effect","import_promises","import_path","DEFAULT_EXTENSIONS","DEFAULT_MAX_DEPTH","discoverProjectFiles","dir","extensions","maxDepth","currentDepth","files","entries","entry","fullPath","error","left","right","scanProjectCorpus","root","options","startedAt","corpusFiles","file","fileStartedAt","result","analyze","programs","durationMs","isZero","import_effect","extractServiceTagsFromFile","sourceFile","filePath","SyntaxKind","loadTsMorph","results","typeChecker","classDeclarations","classDecl","name","extExpr","extText","tagId","tagMatch","serviceMatch","typeArgs","expression","definition","interfaceTypeText","interfaceTypeNode","type","methods","properties","sym","propName","pos","lineAndCol","extractLayerImplementationsFromFile","identifierToServiceId","varDeclarations","varDecl","initializer","initText","layerMatch","kind","layerName","providesServiceId","args","firstArg","firstArgText","identifier","requires","provideMatch","provideArg","canonicalId","yieldServiceMatches","m","ident","canonical","yieldServiceMatchesAlt","collectConsumers","byFile","consumers","irs","ir","programName","req","list","collectConsumersFromNodes","nodes","node","serviceId","c","children","getStaticChildren","computeTopologicalOrder","services","result","visited","temp","visit","id","artifact","dep","computeTransitiveDeps","layerImpls","allLayersByService","deps","layer","reqLayers","transitive","buildProjectServiceMap","sourceFiles","serviceTagInfos","sf","tags","tag","def","knownServiceIds","tagInfo","allReferencedServiceIds","layersByService","layers","match","collectLayersFromIR","consumersByService","unresolvedServices","dependencies","allReferenced","refId","topologicalOrder","providedIdent","r","l","DEFAULT_OPTIONS","NON_PROGRAM_EFFECT_MODULES","fileImportsEffect","filePath","content","runtimeImportMatches","hasAnyRuntimeImport","allNonProgram","match","names","name","isTypeOnlyZeroCandidate","isLightweightEffectAdapterFile","detectExpectedZeroCategory","normalized","base","findPackageJsonDirs","dir","maxDepth","currentDepth","result","entries","e","ent","resolveEntry","pkgDir","entry","extensions","fileHasTopLevelRunCall","Project","SyntaxKind","loadTsMorph","callExpressions","functionKinds","call","parent","current","kind","exprText","getEntryPointsFromPackageJson","dirPath","pkgDirs","entryPaths","raw","pkg","dirs","v","list","p","analyzeProjectCorpus","corpus","options","files","byFile","allPrograms","entryPointFiles","failedFiles","zeroProgramFiles","file","programs","ir","nameLikeEntry","isRunCall","packageEntryPaths","serviceMap","project","sourceFileMap","buildProjectServiceMap","architecture","extractProjectArchitecture","analyzeProject","scanProjectCorpus","runCoverageAudit","runCoverageAuditFromCorpus","outcomes","totalNodes","unknownNodes","sourceUnresolvedNodes","fidelityFindings","fileUnknownRates","unknownReasonsCorpus","durationMs","count","fileTotal","fileUnknown","fidelity","assessIRFidelity","unknownFindings","finding","reason","discovered","analyzed","o","zeroPrograms","failed","excludePatterns","isExcludedFromSuspicious","zeroProgramCategoryCounts","suspiciousZeros","zeroProgramClassifications","zeroOutcomes","importsEffect","expectedCategory","category","unknownNodeRate","assessment","assessAudit","topUnknownFiles","f","a","b","unknownReasonCounts","n","topUnknownReasons","createAnalysisSession","analyze","scanProjectCorpus","analyzeProject","analyzeProjectCorpus","runCoverageAudit","runCoverageAuditFromCorpus","clearProjectCache","analysis","computeDiagramFidelity","ir","assessment","assessIRFidelity","issues","issue","formatDiagramFidelity","report","lines","location","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","import_graph","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","HANDLER_TABLE","lookupHandler","handlerType","HANDLER_TABLE","matchesTag","error","tag","matchingAny","errors","tags","e","parseErrorTypes","errorType","splitTopLevelUnion","collectEffectErrors","nodes","result","node","eff","children","getStaticChildren","analyzeErrorFlow","ir","stepErrors","allErrorsSet","errorToSteps","stepsWithoutErrors","step","steps","unionErrors","a","b","withoutErrors","current","removed","set","collectErrorsFromSubtree","out","visit","n","err","findCauseKindInSubtree","child","walkPropagation","errorsIn","own","handler","sourceErrors","entry","scope","fixedTags","matched","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","arrow","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","sig","filteredAnnotations","a","getNodeStyleClass","compactLeafTypes","summaryLabel","childResult","children","y","chain","forkId","joinId","modeLabel","i","child","branchResult","sourceResult","handlerNodeId","lastIds","handlerResult","wrapperId","acquireResult","useResult","releaseResult","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","callbackResult","chanId","sinkId","intId","renderStaticMermaid","TRACE_STYLES","renderMermaidWithRuntimeTrace","trace","irIndex","indexIR","matchedSpanIds","suffixMatchedSpanIds","unmatchedSpanIds","ambiguousSpanIds","usedStatuses","assignments","span","staticIds","exact","start","ids","spanPathKey","staticId","status","DEFAULT_ENHANCED_OPTIONS","DEFAULT_OPTIONS","import_effect","CursorId","isTransparent","node","labelOf","named","childrenOf","getStaticChildren","normalize","frontier","head","rest","choicesFor","isStaticErrorHandlerNode","success","child","index","build","ir","timeline","taken","normalized","choices","cursorOf","walk","beginWalkthrough","advance","choiceId","choice","next","c","advanceWhileLinear","current","only","rewind","stepCount"]}