effect-analyzer 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/analyze.ts","../src/types.ts","../src/static-analyzer.ts","../src/ts-morph-loader.ts","../src/analysis-utils.ts","../src/type-extractor.ts","../src/analysis-patterns.ts","../src/alias-resolution.ts","../src/program-discovery.ts","../src/core-analysis.ts","../src/effect-analysis.ts","../src/project-analyzer.ts","../src/service-registry.ts","../src/migration-assistant.ts","../src/output/mermaid.ts","../src/data-flow.ts","../src/error-flow.ts","../src/output/mermaid-railway.ts","../src/service-flow.ts","../src/output/mermaid-services.ts","../src/output/mermaid-errors.ts","../src/output/mermaid-decisions.ts","../src/output/mermaid-causes.ts","../src/output/mermaid-concurrency.ts","../src/output/mermaid-timeline.ts","../src/layer-graph.ts","../src/output/mermaid-layers.ts","../src/output/mermaid-retry.ts","../src/output/mermaid-testability.ts","../src/output/mermaid-dataflow.ts","../src/output/auto-diagram.ts","../src/complexity.ts","../src/diagram-quality.ts","../src/path-generator.ts","../src/diagram-quality-eslint.ts","../src/output/explain.ts","../src/output/summary.ts","../src/output/matrix.ts","../src/output/json.ts","../src/output/html.ts","../src/output/docs.ts","../src/output/showcase.ts","../src/composition-resolver.ts","../src/state-flow.ts","../src/scope-resource.ts","../src/observability.ts","../src/di-completeness.ts","../src/strict-diagnostics.ts","../src/output/test-matrix.ts","../src/config-analyzer.ts","../src/match-analyzer.ts","../src/platform-detection.ts","../src/http-api-extractor.ts","../src/schema-to-json-schema.ts","../src/output/api-docs.ts","../src/testing-patterns.ts","../src/version-compat.ts","../src/gen-yield-analysis.ts","../src/sql-patterns.ts","../src/rpc-patterns.ts","../src/request-batching.ts","../src/stm-analysis.ts","../src/playground-export.ts","../src/analysis-cache.ts","../src/const-inliner.ts","../src/diff/diff-engine.ts","../src/diff/render-markdown.ts","../src/diff/render-json.ts","../src/diff/render-mermaid.ts","../src/diff/resolve-source.ts","../src/output/auto-format.ts","../src/fiber-analysis.ts","../src/effect-linter.ts"],"sourcesContent":["/**\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 * @example\n * ```typescript\n * import { Effect } from \"effect\";\n * import { analyze } from \"effect-analyzer\";\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 { Effect, Option } from 'effect';\nimport { AnalysisError } from './types';\nimport type { StaticEffectIR, AnalyzerOptions } from './types';\nimport {\n analyzeEffectFile,\n analyzeEffectSource,\n resetIdCounter,\n} from './static-analyzer';\n\n/**\n * Result object from analyze() with fluent methods to retrieve programs.\n */\nexport interface AnalyzeResult {\n /**\n * Get single program. Fails if file has 0 or >1 programs.\n */\n readonly single: () => Effect.Effect<StaticEffectIR, AnalysisError>;\n\n /**\n * Get single program or None if not exactly one.\n */\n readonly singleOption: () => Effect.Effect<\n Option.Option<StaticEffectIR>\n >;\n\n /**\n * Get all programs as array.\n */\n readonly all: () => Effect.Effect<\n readonly StaticEffectIR[],\n AnalysisError\n >;\n\n /**\n * Get program by name. Fails if not found.\n */\n readonly named: (\n name: string,\n ) => Effect.Effect<StaticEffectIR, AnalysisError>;\n\n /**\n * Get first program. Fails if empty.\n */\n readonly first: () => Effect.Effect<StaticEffectIR, AnalysisError>;\n\n /**\n * Get first program or None if empty.\n */\n readonly firstOption: () => Effect.Effect<\n Option.Option<StaticEffectIR>\n >;\n}\n\nconst createResult = (\n programs: readonly StaticEffectIR[],\n): AnalyzeResult => ({\n single: () =>\n 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 ),\n );\n }),\n\n singleOption: () =>\n 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: () =>\n 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: () =>\n 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: () =>\n Effect.gen(function* () {\n const programs = yield* programsEffect;\n return yield* createResult(programs).single();\n }),\n\n singleOption: () =>\n 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: () =>\n Effect.gen(function* () {\n const programs = yield* programsEffect;\n return yield* createResult(programs).first();\n }),\n\n firstOption: () =>\n 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: () =>\n Effect.gen(function* () {\n const programs = yield* programsEffect;\n return yield* createResult(programs).single();\n }),\n\n singleOption: () =>\n 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: () =>\n Effect.gen(function* () {\n const programs = yield* programsEffect;\n return yield* createResult(programs).first();\n }),\n\n firstOption: () =>\n Effect.gen(function* () {\n const programs = yield* programsEffect;\n return yield* createResult(programs).firstOption();\n }).pipe(Effect.orDie),\n };\n};\n","/**\n * Static Effect Analysis - Type Definitions\n *\n * These types represent Effect code structure extracted through static analysis\n * (AST walking) rather than runtime execution.\n */\n\nimport { Effect, Option } from 'effect';\n\n// =============================================================================\n// Static Node Types\n// =============================================================================\n\n/**\n * Source code location for tracing back to original code.\n */\nexport interface SourceLocation {\n /** Absolute file path */\n readonly filePath: string;\n /** Line number (1-indexed) */\n readonly line: number;\n /** Column number (0-indexed) */\n readonly column: number;\n /** End line number */\n readonly endLine?: number | undefined;\n /** End column number */\n readonly endColumn?: number | undefined;\n}\n\n/**\n * Semantic role classification for display and styling.\n */\nexport type SemanticRole =\n | 'constructor'\n | 'service-call'\n | 'environment'\n | 'side-effect'\n | 'transform'\n | 'error-handler'\n | 'concurrency'\n | 'resource'\n | 'control-flow'\n | 'scheduling'\n | 'stream'\n | 'layer'\n | 'fiber'\n | 'unknown';\n\n/**\n * Structured JSDoc tag data extracted from comments.\n */\nexport interface JSDocTags {\n readonly params: readonly { readonly name: string; readonly description?: string }[];\n readonly returns?: string | undefined;\n readonly throws: readonly string[];\n readonly example?: string | undefined;\n}\n\n/**\n * Detail level for Mermaid diagram labels.\n */\nexport type MermaidDetailLevel = 'compact' | 'standard' | 'verbose';\n\n/**\n * Base properties shared by all static analysis nodes.\n */\nexport interface StaticBaseNode {\n /** Unique identifier for this node */\n readonly id: string;\n /** Human-readable name */\n readonly name?: string | undefined;\n /** Source location */\n readonly location?: SourceLocation | undefined;\n /** Pre-computed human-readable display label (e.g. \"user <- UserRepo.getById\") */\n readonly displayName?: string | undefined;\n /** Semantic role classification for styling and filtering */\n readonly semanticRole?: SemanticRole | undefined;\n}\n\n/**\n * A single Effect operation (yield* or direct call).\n */\nexport interface StaticEffectNode extends StaticBaseNode {\n readonly type: 'effect';\n /** The Effect being created (e.g., \"Effect.succeed\", \"Effect.sync\") */\n readonly callee: string;\n /** Description of what this effect does */\n readonly description?: string | undefined;\n /** JSDoc description extracted from comments above the effect */\n readonly jsdocDescription?: string | undefined;\n /** Structured JSDoc tags extracted from comments */\n readonly jsdocTags?: JSDocTags | undefined;\n /** Error type if statically determinable */\n readonly errorType?: string | undefined;\n /** Full type signature (A, E, R) - requires type extraction */\n readonly typeSignature?: EffectTypeSignature | undefined;\n /** Services required by this specific effect */\n readonly requiredServices?: ServiceRequirement[] | undefined;\n /** If this effect is a method call on a typed service object */\n readonly serviceCall?: {\n /** Resolved type name of the service object (e.g. 'UserRepo') */\n readonly serviceType: string;\n /** Method name being called (e.g. 'getById') */\n readonly methodName: string;\n /** Variable/expression name used at call site (e.g. 'repo') */\n readonly objectName: string;\n } | undefined;\n /** Resolved service method when call is e.g. yield* db.query() and db is bound to a service tag */\n readonly serviceMethod?: { readonly serviceId: string; readonly methodName: string } | undefined;\n /** Inner effects from Effect.sync/promise/async callback body (one level only) */\n readonly callbackBody?: readonly StaticFlowNode[] | undefined;\n /** Effect.async/asyncEffect only: resume/canceller callback patterns (GAP async callback interop). */\n readonly asyncCallback?: {\n readonly resumeParamName: string;\n readonly resumeCallCount: number;\n readonly returnsCanceller: boolean;\n } | undefined;\n /** Effect.provide only: whether context is provided via Layer, Context, or Runtime. */\n readonly provideKind?: 'layer' | 'context' | 'runtime' | undefined;\n /** Constructor subtype classification */\n readonly constructorKind?: 'sync' | 'promise' | 'async' | 'never' | 'void' | 'fromNullable' | 'fn' | 'fnUntraced' | undefined;\n /** FiberRef built-in name (e.g. currentLogLevel, currentConcurrency) */\n readonly fiberRefName?: string | undefined;\n /** Effect.fn traced name */\n readonly tracedName?: string | undefined;\n}\n\n/**\n * Generator-based effect block (Effect.gen).\n */\nexport interface StaticGeneratorNode extends StaticBaseNode {\n readonly type: 'generator';\n /** Variables yielded in the generator */\n readonly yields: {\n readonly variableName?: string | undefined;\n readonly effect: StaticFlowNode;\n }[];\n /** Final return value */\n readonly returnNode?: StaticFlowNode | undefined;\n /** JSDoc description extracted from comments above the generator function */\n readonly jsdocDescription?: string | undefined;\n /** Structured JSDoc tags extracted from comments */\n readonly jsdocTags?: JSDocTags | undefined;\n}\n\n/**\n * Pipe composition chain (effect.pipe(...)).\n */\nexport interface StaticPipeNode extends StaticBaseNode {\n readonly type: 'pipe';\n /** The initial effect */\n readonly initial: StaticFlowNode;\n /** Pipe transformations in order */\n readonly transformations: readonly StaticFlowNode[];\n /** Type flow through the pipe chain (A, E, R at each step) */\n readonly typeFlow?: readonly EffectTypeSignature[] | undefined;\n}\n\n/**\n * Concurrency mode for Effect.all / Effect.allWith.\n */\nexport type ConcurrencyMode = 'sequential' | 'bounded' | 'unbounded' | number;\n\n/**\n * Parallel execution (Effect.all, Effect.allPar).\n */\nexport interface StaticParallelNode extends StaticBaseNode {\n readonly type: 'parallel';\n /** Child effects running in parallel */\n readonly children: readonly StaticFlowNode[];\n /** Mode: sequential (all) or parallel (allPar) */\n readonly mode: 'sequential' | 'parallel';\n /** The callee (e.g., \"Effect.all\", \"Effect.allPar\") */\n readonly callee: string;\n /** Resolved concurrency: from options or inferred from mode (GAP 18) */\n readonly concurrency?: ConcurrencyMode | undefined;\n /** Request batching enabled (Effect.all with { batching: true }) */\n readonly batching?: boolean | undefined;\n /** Results discarded (Effect.all with { discard: true }) */\n readonly discard?: boolean | undefined;\n /** Labels for each parallel branch (from child displayNames) */\n readonly branchLabels?: readonly string[] | undefined;\n}\n\n/**\n * Race execution (Effect.race, Effect.raceAll).\n */\nexport interface StaticRaceNode extends StaticBaseNode {\n readonly type: 'race';\n /** Child effects racing */\n readonly children: readonly StaticFlowNode[];\n /** The callee */\n readonly callee: string;\n /** Labels for each race competitor */\n readonly raceLabels?: readonly string[] | undefined;\n}\n\n/**\n * Error handling (catchAll, catchTag, orElse, etc.).\n */\nexport interface StaticErrorHandlerNode extends StaticBaseNode {\n readonly type: 'error-handler';\n /** Type of handler: catchAll, catchTag, orElse, etc. */\n readonly handlerType:\n | 'catchAll'\n | 'catchTag'\n | 'catchAllCause'\n | 'catchIf'\n | 'catchSome'\n | 'catchSomeCause'\n | 'catchSomeDefect'\n | 'catchAllDefect'\n | 'catchTags'\n | 'orElse'\n | 'orElseFail'\n | 'orElseSucceed'\n | 'orDie'\n | 'orDieWith'\n | 'flip'\n | 'mapError'\n | 'mapErrorCause'\n | 'mapBoth'\n | 'sandbox'\n | 'unsandbox'\n | 'parallelErrors'\n | 'filterOrDie'\n | 'filterOrDieMessage'\n | 'filterOrElse'\n | 'filterOrFail'\n | 'match'\n | 'matchCause'\n | 'matchEffect'\n | 'matchCauseEffect'\n | 'firstSuccessOf'\n | 'ignore'\n | 'ignoreLogged'\n | 'eventually';\n /** The effect being handled */\n readonly source: StaticFlowNode;\n /** The handler (recovery) effect */\n readonly handler?: StaticFlowNode | undefined;\n /** For catchTag, the error tag being caught */\n readonly errorTag?: string | undefined;\n /** For catchTags (object form), the error tags being caught */\n readonly errorTags?: readonly string[] | undefined;\n /** Edge label for the error path (e.g. \"on DatabaseError\") */\n readonly errorEdgeLabel?: string | undefined;\n}\n\n/**\n * Schedule composition info (GAP 8).\n */\nexport interface ScheduleInfo {\n readonly baseStrategy:\n | 'fixed'\n | 'exponential'\n | 'fibonacci'\n | 'spaced'\n | 'linear'\n | 'cron'\n | 'windowed'\n | 'duration'\n | 'elapsed'\n | 'delays'\n | 'once'\n | 'stop'\n | 'count'\n | 'custom';\n readonly maxRetries?: number | 'unlimited' | undefined;\n readonly initialDelay?: string | undefined;\n readonly maxDelay?: string | undefined;\n readonly jittered: boolean;\n readonly conditions: readonly string[];\n readonly estimatedMaxDuration?: string | undefined;\n}\n\n/**\n * Retry/Schedule operation.\n */\nexport interface StaticRetryNode extends StaticBaseNode {\n readonly type: 'retry';\n /** The effect being retried */\n readonly source: StaticFlowNode;\n /** Schedule policy if statically determinable (expression text) */\n readonly schedule?: string | undefined;\n /** Parsed schedule when present (GAP 8 dedicated Schedule IR) */\n readonly scheduleNode?: StaticFlowNode | undefined;\n /** Whether it's a retryOrElse */\n readonly hasFallback: boolean;\n /** Decomposed schedule (GAP 8) */\n readonly scheduleInfo?: ScheduleInfo | undefined;\n /** Edge label for the retry path (e.g. \"retry: exponential(100ms)\") */\n readonly retryEdgeLabel?: string | undefined;\n}\n\n/**\n * Timeout operation.\n */\nexport interface StaticTimeoutNode extends StaticBaseNode {\n readonly type: 'timeout';\n /** The effect being timed out */\n readonly source: StaticFlowNode;\n /** Timeout duration if statically determinable */\n readonly duration?: string | undefined;\n /** Whether there's a fallback */\n readonly hasFallback: boolean;\n}\n\n/**\n * Resource acquisition (acquireRelease).\n */\nexport interface StaticResourceNode extends StaticBaseNode {\n readonly type: 'resource';\n /** Acquisition effect */\n readonly acquire: StaticFlowNode;\n /** Release effect */\n readonly release: StaticFlowNode;\n /** Use effect */\n readonly use?: StaticFlowNode | undefined;\n}\n\n/**\n * Conditional execution (Effect.if, when, unless).\n */\nexport interface StaticConditionalNode extends StaticBaseNode {\n readonly type: 'conditional';\n /** The condition as source string */\n readonly condition: string;\n /** Type of conditional */\n readonly conditionalType:\n | 'if'\n | 'when'\n | 'unless'\n | 'whenEffect'\n | 'whenFiberRef'\n | 'whenRef'\n | 'unlessEffect'\n | 'option'\n | 'either'\n | 'exit'\n | 'liftPredicate';\n /** Branch when condition is true */\n readonly onTrue: StaticFlowNode;\n /** Branch when condition is false (if present) */\n readonly onFalse?: StaticFlowNode | undefined;\n /** Semantic label for the condition (e.g. \"isAdmin\") */\n readonly conditionLabel?: string | undefined;\n /** Label for the true branch edge */\n readonly trueEdgeLabel?: string | undefined;\n /** Label for the false branch edge */\n readonly falseEdgeLabel?: string | undefined;\n}\n\n/**\n * Decision node for raw `if`, ternaries, short-circuits, and `Step.decide`.\n */\nexport interface StaticDecisionNode extends StaticBaseNode {\n readonly type: 'decision';\n /** Unique decision identifier */\n readonly decisionId: string;\n /** Human-readable label for the decision */\n readonly label: string;\n /** Condition expression source text */\n readonly condition: string;\n /** Origin of the decision construct */\n readonly source: 'effect-flow' | 'raw-if' | 'raw-ternary' | 'raw-short-circuit';\n /** Branch when condition is true */\n readonly onTrue: readonly StaticFlowNode[];\n /** Branch when condition is false (if present) */\n readonly onFalse?: readonly StaticFlowNode[] | undefined;\n}\n\n/**\n * A single case arm in a switch node.\n */\nexport interface StaticSwitchCase {\n /** Labels for this case (e.g. string/number literals) */\n readonly labels: readonly string[];\n /** Whether this is the default case */\n readonly isDefault: boolean;\n /** Body nodes for this case */\n readonly body: readonly StaticFlowNode[];\n}\n\n/**\n * Switch node for raw `switch` statements and `Step.branch`.\n */\nexport interface StaticSwitchNode extends StaticBaseNode {\n readonly type: 'switch';\n /** Optional switch identifier */\n readonly switchId?: string | undefined;\n /** Expression being switched on */\n readonly expression: string;\n /** Case arms */\n readonly cases: readonly StaticSwitchCase[];\n /** Origin of the switch construct */\n readonly source: 'effect-flow' | 'raw-js';\n /** Whether a default case is present */\n readonly hasDefault: boolean;\n /** Whether any case falls through to the next */\n readonly hasFallthrough: boolean;\n}\n\n/**\n * Try/catch/finally node for raw exception handling.\n */\nexport interface StaticTryCatchNode extends StaticBaseNode {\n readonly type: 'try-catch';\n /** Body of the try block */\n readonly tryBody: readonly StaticFlowNode[];\n /** Catch clause variable name */\n readonly catchVariable?: string | undefined;\n /** Body of the catch block */\n readonly catchBody?: readonly StaticFlowNode[] | undefined;\n /** Body of the finally block */\n readonly finallyBody?: readonly StaticFlowNode[] | undefined;\n /** Whether the try body contains a terminal statement (return/throw) */\n readonly hasTerminalInTry: boolean;\n}\n\n/**\n * Terminal node for `return`, `throw`, `break`, and `continue` statements.\n */\nexport interface StaticTerminalNode extends StaticBaseNode {\n readonly type: 'terminal';\n /** Kind of terminal statement */\n readonly terminalKind: 'return' | 'throw' | 'break' | 'continue';\n /** Label for labeled break/continue */\n readonly label?: string | undefined;\n /** Value expression (e.g. the returned/thrown value) */\n readonly value?: readonly StaticFlowNode[] | undefined;\n}\n\n/**\n * Opaque node for unsupported or unanalyzable constructs.\n */\nexport interface StaticOpaqueNode extends StaticBaseNode {\n readonly type: 'opaque';\n /** Reason why this construct could not be analyzed */\n readonly reason: string;\n /** Original source text of the construct */\n readonly sourceText: string;\n}\n\n/**\n * Cause module operation — construction or inspection of Effect Cause values.\n */\nexport interface StaticCauseNode extends StaticBaseNode {\n readonly type: 'cause';\n /** The specific Cause operation */\n readonly causeOp:\n | 'fail'\n | 'die'\n | 'interrupt'\n | 'parallel'\n | 'sequential'\n | 'empty'\n | 'failures'\n | 'defects'\n | 'interruptors'\n | 'squash'\n | 'squashWith'\n | 'pretty'\n | 'flatten'\n | 'isDie'\n | 'isFailure'\n | 'isInterrupted'\n | 'isEmpty'\n | 'map'\n | 'filter'\n | 'other';\n /** Whether this is a constructor (fail/die/interrupt/parallel/sequential/empty) */\n readonly isConstructor: boolean;\n /** For parallel/sequential: child cause nodes (GAP Cause structural traversal). */\n readonly children?: readonly StaticFlowNode[] | undefined;\n /** Cause kind classification */\n readonly causeKind?: 'fail' | 'die' | 'interrupt' | 'mixed' | undefined;\n}\n\n/**\n * Exit module operation — construction or inspection of Effect Exit values.\n */\nexport interface StaticExitNode extends StaticBaseNode {\n readonly type: 'exit';\n /** The specific Exit operation */\n readonly exitOp:\n | 'succeed'\n | 'fail'\n | 'die'\n | 'interrupt'\n | 'void'\n | 'unit'\n | 'match'\n | 'isSuccess'\n | 'isFailure'\n | 'isInterrupted'\n | 'when'\n | 'whenEffect'\n | 'exists'\n | 'contains'\n | 'flatten'\n | 'map'\n | 'mapBoth'\n | 'mapError'\n | 'flatMap'\n | 'zipWith'\n | 'tap'\n | 'tapBoth'\n | 'tapError'\n | 'other';\n /** Whether this is a constructor (succeed/fail/die/interrupt/void/unit) */\n readonly isConstructor: boolean;\n}\n\n/**\n * Schedule module operation — construction or composition of Schedule values (GAP 8 dedicated IR).\n */\nexport interface StaticScheduleNode extends StaticBaseNode {\n readonly type: 'schedule';\n /** The specific Schedule operation */\n readonly scheduleOp:\n | 'exponential'\n | 'fibonacci'\n | 'spaced'\n | 'fixed'\n | 'linear'\n | 'cron'\n | 'windowed'\n | 'duration'\n | 'elapsed'\n | 'delays'\n | 'once'\n | 'stop'\n | 'count'\n | 'forever'\n | 'jittered'\n | 'andThen'\n | 'intersect'\n | 'union'\n | 'compose'\n | 'zipWith'\n | 'addDelay'\n | 'modifyDelay'\n | 'check'\n | 'resetAfter'\n | 'resetWhen'\n | 'ensure'\n | 'driver'\n | 'mapInput'\n | 'other';\n /** Decomposed schedule (when parseable from expression text) */\n readonly scheduleInfo?: ScheduleInfo | undefined;\n}\n\n/**\n * Match module operation (Match.type / Match.when / Match.exhaustive etc.).\n */\nexport interface StaticMatchNode extends StaticBaseNode {\n readonly type: 'match';\n /** The specific Match operation */\n readonly matchOp:\n | 'type'\n | 'tag'\n | 'value'\n | 'when'\n | 'whenOr'\n | 'whenAnd'\n | 'not'\n | 'is'\n | 'exhaustive'\n | 'orElse'\n | 'option'\n | 'either'\n | 'discriminator'\n | 'discriminatorsExhaustive'\n | 'tags'\n | 'tagsExhaustive'\n | 'withReturnType'\n | 'run'\n | 'other';\n /** Tag names matched (for Match.tag, Match.when with tag literals, Match.tags) */\n readonly matchedTags?: readonly string[] | undefined;\n /** Whether this match arm makes the overall match exhaustive */\n readonly isExhaustive: boolean;\n}\n\n/**\n * Transformation step in a pipe chain (map, flatMap, andThen, tap, zip, as, etc.).\n * These preserve the Effect channel but transform A, E, or R.\n */\nexport interface StaticTransformNode extends StaticBaseNode {\n readonly type: 'transform';\n /** Specific transformation operation */\n readonly transformType:\n | 'map'\n | 'flatMap'\n | 'andThen'\n | 'tap'\n | 'tapBoth'\n | 'tapError'\n | 'tapErrorTag'\n | 'tapErrorCause'\n | 'tapDefect'\n | 'zipLeft'\n | 'zipRight'\n | 'zipWith'\n | 'zip'\n | 'as'\n | 'asVoid'\n | 'asSome'\n | 'asSomeError'\n | 'flatten'\n | 'ap'\n | 'negate'\n | 'merge'\n | 'other';\n /**\n * Whether this is an effectful transformation\n * (e.g. flatMap/andThen produce a new Effect, map does not).\n */\n readonly isEffectful: boolean;\n /** The source/input effect (if extractable from args, undefined for curried forms). */\n readonly source?: StaticFlowNode | undefined;\n /** The transformation function text (if simple enough to extract). */\n readonly fn?: string | undefined;\n /** Input type signature (before transform) */\n readonly inputType?: EffectTypeSignature | undefined;\n /** Output type signature (after transform) */\n readonly outputType?: EffectTypeSignature | undefined;\n}\n\n/**\n * Loop structure (forEach, loop).\n */\nexport interface StaticLoopNode extends StaticBaseNode {\n readonly type: 'loop';\n /** Type of loop / collection operation */\n readonly loopType:\n | 'forEach'\n | 'filter'\n | 'filterMap'\n | 'partition'\n | 'reduce'\n | 'validate'\n | 'replicate'\n | 'dropUntil'\n | 'dropWhile'\n | 'takeUntil'\n | 'takeWhile'\n | 'every'\n | 'exists'\n | 'findFirst'\n | 'head'\n | 'mergeAll'\n | 'loop'\n | 'for'\n | 'forOf'\n | 'forIn'\n | 'while'\n | 'doWhile';\n /** The iteration source */\n readonly iterSource?: string | undefined;\n /** Body of the loop */\n readonly body: StaticFlowNode;\n /** Whether the loop contains an early exit (break/return) */\n readonly hasEarlyExit?: boolean | undefined;\n /** Yield expressions in the loop header (e.g. for-of with yield* in initializer) */\n readonly headerYields?: readonly StaticFlowNode[] | undefined;\n /** Iteration variable name (for for-of/for-in loops) */\n readonly iterVariable?: string | undefined;\n}\n\n/**\n * Layer lifecycle (GAP 2).\n */\nexport type LayerLifecycle = 'default' | 'fresh' | 'scoped' | 'memoized';\n\n/**\n * Layer/service provision.\n */\nexport interface StaticLayerNode extends StaticBaseNode {\n readonly type: 'layer';\n /** Layer operations */\n readonly operations: readonly StaticFlowNode[];\n /** Whether this is a merged layer */\n readonly isMerged: boolean;\n /** Service tags this layer provides (GAP 2) */\n readonly provides?: readonly string[] | undefined;\n /** Service tags this layer requires (GAP 2) */\n readonly requires?: readonly string[] | undefined;\n /** Lifecycle (GAP 2) */\n readonly lifecycle?: LayerLifecycle | undefined;\n /** True when this layer is or contains Layer.MemoMap (GAP dedicated memo-map analysis). */\n readonly isMemoMap?: boolean | undefined;\n}\n\n/**\n * Stream operator in a pipeline (GAP 5).\n */\nexport interface StreamOperatorInfo {\n readonly operation: string;\n readonly isEffectful: boolean;\n readonly estimatedCardinality?: 'same' | 'fewer' | 'more' | 'unknown' | undefined;\n readonly category?:\n | 'constructor'\n | 'transform'\n | 'filter'\n | 'windowing'\n | 'merge'\n | 'broadcasting'\n | 'halting'\n | 'text'\n | 'backpressure'\n | 'error'\n | 'resource'\n | 'context'\n | 'sink'\n | 'conversion'\n | 'channel'\n | 'other'\n | undefined;\n /** Windowing: size for grouped/groupedWithin/sliding (GAP 2 windowing detail). */\n readonly windowSize?: number | undefined;\n /** Windowing: stride/step for sliding (GAP 2 windowing detail). */\n readonly stride?: number | undefined;\n}\n\n/**\n * Stream pipeline (GAP 5).\n */\nexport interface StaticStreamNode extends StaticBaseNode {\n readonly type: 'stream';\n readonly source: StaticFlowNode;\n readonly pipeline: readonly StreamOperatorInfo[];\n readonly sink?: string | undefined;\n readonly backpressureStrategy?: 'buffer' | 'drop' | 'sliding' | undefined;\n /** Classified constructor type when this is a Stream.from* / Stream.make / etc. */\n readonly constructorType?:\n | 'fromIterable'\n | 'fromArray'\n | 'fromQueue'\n | 'fromPubSub'\n | 'fromEffect'\n | 'fromAsyncIterable'\n | 'fromReadableStream'\n | 'fromEventListener'\n | 'fromSchedule'\n | 'range'\n | 'tick'\n | 'iterate'\n | 'unfold'\n | 'make'\n | 'empty'\n | 'never'\n | 'succeed'\n | 'fail'\n | 'fromMailbox'\n | 'fromSubscriptionRef'\n | 'other'\n | undefined;\n}\n\n/**\n * Concurrency primitive (Queue, PubSub, Deferred, Semaphore, Mailbox, Latch, FiberSet, FiberMap, FiberHandle, RateLimiter, SubscriptionRef) - GAP 6.\n */\nexport interface StaticConcurrencyPrimitiveNode extends StaticBaseNode {\n readonly type: 'concurrency-primitive';\n readonly primitive:\n | 'queue'\n | 'pubsub'\n | 'deferred'\n | 'semaphore'\n | 'mailbox'\n | 'latch'\n | 'fiberHandle'\n | 'fiberSet'\n | 'fiberMap'\n | 'rateLimiter'\n | 'cache'\n | 'scopedCache'\n | 'rcRef'\n | 'rcMap'\n | 'reloadable'\n | 'subscriptionRef';\n readonly operation:\n | 'create'\n | 'offer'\n | 'take'\n | 'takeAll'\n | 'publish'\n | 'subscribe'\n | 'await'\n | 'succeed'\n | 'fail'\n | 'withPermit'\n | 'run'\n | 'open'\n | 'close'\n | 'release'\n | 'available'\n | 'get'\n | 'set'\n | 'invalidate'\n | 'contains'\n | 'update'\n | 'reload'\n | 'end'\n | 'toStream'\n | 'changes';\n readonly strategy?: 'bounded' | 'unbounded' | 'sliding' | 'dropping' | undefined;\n readonly capacity?: number | undefined;\n /** For Semaphore take(n) / release(n): permit count when first arg is numeric literal (GAP 13). */\n readonly permitCount?: number | undefined;\n readonly source?: StaticFlowNode | undefined;\n /** Lifecycle options (e.g. FiberHandle.run { onlyIfMissing: true }) */\n readonly lifecycleOptions?: Record<string, unknown> | undefined;\n}\n\n/**\n * Fiber operation (fork, join, interrupt) - GAP 1.\n */\nexport interface StaticFiberNode extends StaticBaseNode {\n readonly type: 'fiber';\n readonly operation:\n | 'fork'\n | 'forkScoped'\n | 'forkDaemon'\n | 'forkAll'\n | 'forkIn'\n | 'forkWithErrorHandler'\n | 'join'\n | 'await'\n | 'interrupt'\n | 'interruptFork'\n | 'poll'\n | 'status'\n | 'all'\n | 'awaitAll'\n | 'children'\n | 'dump'\n | 'scoped'\n | 'inheritAll'\n | 'map'\n | 'mapEffect'\n | 'mapFiber'\n | 'roots'\n | 'getCurrentFiber';\n readonly fiberSource?: StaticFlowNode | undefined;\n readonly joinPoint?: string | undefined;\n readonly isScoped: boolean;\n readonly isDaemon: boolean;\n /** Scope context: 'safe' when fiber is inside Effect.scoped or after Scope.make */\n readonly scopeContext?: string | undefined;\n}\n\n/**\n * Interruption region (interruptible/uninterruptible/mask/onInterrupt).\n */\nexport interface StaticInterruptionNode extends StaticBaseNode {\n readonly type: 'interruption';\n /** The interruption operation */\n readonly interruptionType:\n | 'interrupt'\n | 'interruptWith'\n | 'interruptible'\n | 'uninterruptible'\n | 'interruptibleMask'\n | 'uninterruptibleMask'\n | 'onInterrupt'\n | 'disconnect'\n | 'allowInterrupt';\n /** The wrapped effect (for interruptible/uninterruptible/mask) */\n readonly source?: StaticFlowNode | undefined;\n /** The interrupt handler (for onInterrupt) */\n readonly handler?: StaticFlowNode | undefined;\n}\n\n/**\n * Unknown or unanalyzable code block.\n */\nexport interface StaticUnknownNode extends StaticBaseNode {\n readonly type: 'unknown';\n /** Reason why this couldn't be analyzed */\n readonly reason: string;\n /** The source code that couldn't be analyzed */\n readonly sourceCode?: string | undefined;\n}\n\n/** Channel operator or constructor (improve.md §8). */\nexport interface ChannelOperatorInfo {\n readonly operation: string;\n readonly category?: 'constructor' | 'transform' | 'pipe' | 'other' | undefined;\n}\n\n/**\n * Channel pipeline node (improve.md §8 dedicated Channel analysis).\n */\nexport interface StaticChannelNode extends StaticBaseNode {\n readonly type: 'channel';\n readonly source?: StaticFlowNode | undefined;\n readonly pipeline: readonly ChannelOperatorInfo[];\n}\n\n/** Sink operator (improve.md §8). */\nexport interface SinkOperatorInfo {\n readonly operation: string;\n readonly category?: 'constructor' | 'transform' | 'other' | undefined;\n}\n\n/**\n * Sink pipeline node (improve.md §8 dedicated Sink analysis).\n */\nexport interface StaticSinkNode extends StaticBaseNode {\n readonly type: 'sink';\n readonly source?: StaticFlowNode | undefined;\n readonly pipeline: readonly SinkOperatorInfo[];\n}\n\n/**\n * Union of all static flow node types.\n */\nexport type StaticFlowNode =\n | StaticEffectNode\n | StaticGeneratorNode\n | StaticPipeNode\n | StaticParallelNode\n | StaticRaceNode\n | StaticErrorHandlerNode\n | StaticRetryNode\n | StaticTimeoutNode\n | StaticResourceNode\n | StaticConditionalNode\n | StaticLoopNode\n | StaticCauseNode\n | StaticExitNode\n | StaticScheduleNode\n | StaticMatchNode\n | StaticTransformNode\n | StaticLayerNode\n | StaticStreamNode\n | StaticChannelNode\n | StaticSinkNode\n | StaticConcurrencyPrimitiveNode\n | StaticFiberNode\n | StaticInterruptionNode\n | StaticDecisionNode\n | StaticSwitchNode\n | StaticTryCatchNode\n | StaticTerminalNode\n | StaticOpaqueNode\n | StaticUnknownNode;\n\n// =============================================================================\n// Static Effect IR\n// =============================================================================\n\n/**\n * Root node representing the analyzed effect program.\n */\nexport interface StaticEffectProgram extends StaticBaseNode {\n readonly type: 'program';\n /** Name of the program (from file name or variable) */\n readonly programName: string;\n /** Entry point: gen, direct, pipe, run, workflow-execute, or class */\n readonly source: 'generator' | 'direct' | 'pipe' | 'run' | 'workflow-execute' | 'class' | 'classProperty' | 'classMethod';\n /** Discovery confidence based on alias/path resolution vs heuristics */\n readonly discoveryConfidence?: 'high' | 'medium' | 'low';\n /** Best-effort reason used to classify this as an Effect program */\n readonly discoveryReason?: string | undefined;\n /** The root effect nodes */\n readonly children: readonly StaticFlowNode[];\n /** Dependencies (services required) */\n readonly dependencies: readonly DependencyInfo[];\n /** Error types */\n readonly errorTypes: readonly string[];\n /** Full type signature of the program (A, E, R) */\n readonly typeSignature?: EffectTypeSignature | undefined;\n /** All service requirements across the program */\n readonly requiredServices?: ServiceRequirement[] | undefined;\n /** Description */\n readonly description?: string | undefined;\n /** JSDoc description extracted from comments above the program */\n readonly jsdocDescription?: string | undefined;\n /** Structured JSDoc tags extracted from comments */\n readonly jsdocTags?: JSDocTags | undefined;\n}\n\n/**\n * Information about a dependency/service.\n */\nexport interface DependencyInfo {\n readonly name: string;\n readonly typeSignature?: string | undefined;\n readonly isLayer: boolean;\n}\n\n/**\n * Effect Type Signature - A, E, R parameters\n */\nexport interface EffectTypeSignature {\n /** Success type (A) */\n readonly successType: string;\n /** Error type (E) */\n readonly errorType: string;\n /** Requirements/Context type (R) */\n readonly requirementsType: string;\n /** Whether the type was successfully extracted */\n readonly isInferred: boolean;\n /** Confidence level of the type extraction */\n readonly typeConfidence: 'declared' | 'inferred' | 'unknown';\n /** Raw type string from TypeScript */\n readonly rawTypeString?: string;\n}\n\n/** Stream type args — Stream<A, E, R> (21.3 type extraction) */\nexport interface StreamTypeSignature {\n readonly successType: string;\n readonly errorType: string;\n readonly requirementsType: string;\n readonly rawTypeString?: string;\n}\n\n/** Layer type args — Layer<ROut, E, RIn> (provides, error, requires) (21.3 type extraction) */\nexport interface LayerTypeSignature {\n readonly providedType: string;\n readonly errorType: string;\n readonly requiredType: string;\n readonly rawTypeString?: string;\n}\n\n/** Schedule type args — Schedule<Out, In, R> (21.3 type extraction) */\nexport interface ScheduleTypeSignature {\n readonly outputType: string;\n readonly inputType: string;\n readonly requirementsType: string;\n readonly rawTypeString?: string;\n}\n\n/** Cause type args — Cause<E> (21.3 type extraction) */\nexport interface CauseTypeSignature {\n readonly errorType: string;\n readonly rawTypeString?: string;\n}\n\n/**\n * Service requirement extracted from Context type\n */\nexport interface ServiceRequirement {\n /** Service identifier (tag key) */\n readonly serviceId: string;\n /** Service type name */\n readonly serviceType: string;\n /** Where this requirement originates */\n readonly requiredAt: SourceLocation;\n}\n\n// =============================================================================\n// Schema Analysis Types\n// =============================================================================\n\n/**\n * Schema validation path - represents a field that can fail validation\n */\nexport interface SchemaValidationPath {\n /** Field path (e.g., \"user.email\" or \"items[0].name\") */\n readonly path: string;\n /** Schema type at this path */\n readonly schemaType: string;\n /** Validation constraints (e.g., minLength, pattern) */\n readonly constraints: readonly SchemaConstraint[];\n /** Whether this field is optional */\n readonly isOptional: boolean;\n /** Location in source code */\n readonly location?: SourceLocation | undefined;\n}\n\n/**\n * Schema validation constraint\n */\nexport interface SchemaConstraint {\n /** Constraint type (e.g., \"minLength\", \"pattern\", \"range\") */\n readonly type: string;\n /** Constraint value */\n readonly value: string | number | boolean;\n /** Human-readable description */\n readonly description: string;\n}\n\n/**\n * Schema decode/encode operation analysis\n */\nexport interface SchemaOperation {\n /** Operation type */\n readonly operation: 'decode' | 'encode' | 'decodeUnknown' | 'encodeUnknown';\n /** Schema being used */\n readonly schemaName: string;\n /** Source type (encoded) */\n readonly sourceType: string;\n /** Target type (decoded) */\n readonly targetType: string;\n /** Validation paths that can fail */\n readonly validationPaths: readonly SchemaValidationPath[];\n /** Whether error handling is present */\n readonly hasErrorHandling: boolean;\n /** Location in source code */\n readonly location?: SourceLocation | undefined;\n}\n\n/**\n * Schema composition information\n */\nexport interface SchemaComposition {\n /** Schema name */\n readonly schemaName: string;\n /** Composition type */\n readonly compositionType:\n | 'struct'\n | 'union'\n | 'array'\n | 'record'\n | 'tuple'\n | 'class'\n | 'recursive'\n | 'optional'\n | 'nullable'\n | 'transform'\n | 'filter'\n | 'brand'\n | 'literal'\n | 'enum'\n | 'refinement'\n | 'datetime'\n | 'effect-type'\n | 'serializable';\n /** Child schemas */\n readonly children: readonly string[];\n /** Validation paths */\n readonly validationPaths: readonly SchemaValidationPath[];\n}\n\n/**\n * Complete Schema analysis result\n */\nexport interface SchemaAnalysis {\n /** All Schema.decode/encode operations found */\n readonly operations: readonly SchemaOperation[];\n /** Schema compositions detected */\n readonly compositions: readonly SchemaComposition[];\n /** Missing error handlers for Schema operations */\n readonly unhandledOperations: readonly SchemaOperation[];\n}\n\n/**\n * Complete static Effect IR.\n */\nexport interface StaticEffectIR {\n readonly root: StaticEffectProgram;\n readonly metadata: StaticAnalysisMetadata;\n readonly references: ReadonlyMap<string, StaticEffectIR>;\n}\n\n/**\n * Service interface shape extracted from Context.Tag / Effect.Service class (GAP service interface tracking).\n */\nexport interface ServiceDefinition {\n /** Tag/service identifier (class name or tag string). */\n readonly tagId: string;\n /** Method names from the service interface type. */\n readonly methods: readonly string[];\n /** Property names (non-callable members) from the service interface type. */\n readonly properties: readonly string[];\n /** Whether class implements [Equal.symbol] */\n readonly hasCustomEquality?: boolean | undefined;\n /** Whether class implements [Hash.symbol] */\n readonly hasCustomHash?: boolean | undefined;\n}\n\n/**\n * Metadata about the static analysis.\n */\nexport interface StaticAnalysisMetadata {\n readonly analyzedAt: number;\n readonly filePath: string;\n readonly tsVersion?: string | undefined;\n readonly warnings: readonly AnalysisWarning[];\n readonly stats: AnalysisStats;\n /** Service interface shapes (methods/properties) from Context.Tag/Effect.Service in this file. */\n readonly serviceDefinitions?: readonly ServiceDefinition[] | undefined;\n}\n\n/**\n * Warning generated during analysis.\n */\nexport interface AnalysisWarning {\n readonly code: string;\n readonly message: string;\n readonly location?: SourceLocation | undefined;\n}\n\n/**\n * Statistics about the analysis.\n */\nexport interface AnalysisStats {\n totalEffects: number;\n parallelCount: number;\n raceCount: number;\n errorHandlerCount: number;\n retryCount: number;\n timeoutCount: number;\n resourceCount: number;\n loopCount: number;\n conditionalCount: number;\n layerCount: number;\n interruptionCount: number;\n unknownCount: number;\n decisionCount: number;\n switchCount: number;\n tryCatchCount: number;\n terminalCount: number;\n opaqueCount: number;\n}\n\n// =============================================================================\n// Diagram Quality Types\n// =============================================================================\n\nexport type DiagramReadabilityBand = 'good' | 'ok' | 'noisy';\n\nexport interface DiagramQualityMetrics {\n readonly stepCountDetailed: number;\n readonly stepCountSummary: number;\n readonly collapsedGroupsSummary: number;\n readonly logRatio: number;\n readonly sideEffectRatio: number;\n readonly anonymousNodeCount: number;\n readonly anonymousRatio: number;\n readonly unknownNodeCount: number;\n readonly serviceCallCount: number;\n readonly namedServiceCallRatio: number;\n readonly pipeChainCount: number;\n readonly maxPipeChainLength: number;\n}\n\nexport interface DiagramQuality {\n readonly score: number;\n readonly band: DiagramReadabilityBand;\n readonly metrics: DiagramQualityMetrics;\n readonly reasons: readonly string[];\n readonly tips: readonly string[];\n}\n\nexport interface DiagramTopOffenderEntry {\n readonly filePath: string;\n readonly metricValue: number;\n readonly tip: string;\n}\n\nexport interface DiagramTopOffendersReport {\n readonly largestPrograms: readonly DiagramTopOffenderEntry[];\n readonly mostAnonymousNodes: readonly DiagramTopOffenderEntry[];\n readonly mostUnknownNodes: readonly DiagramTopOffenderEntry[];\n readonly highestLogRatio: readonly DiagramTopOffenderEntry[];\n}\n\nexport interface DiagramQualityWithFile {\n readonly filePath: string;\n readonly quality: DiagramQuality;\n}\n\n/**\n * Options for the static analyzer.\n */\nexport interface AnalyzerOptions {\n readonly tsConfigPath?: string | undefined;\n readonly resolveReferences?: boolean | undefined;\n readonly maxReferenceDepth?: number | undefined;\n readonly includeLocations?: boolean | undefined;\n readonly assumeImported?: boolean | undefined;\n /** Enable effect-workflow patterns (Workflow.make / Workflow.run). Use the \"effect-workflow\" entrypoint for this. */\n readonly enableEffectWorkflow?: boolean | undefined;\n /** Optional path to known Effect internals root; local/relative imports under this path are treated as Effect-like (improve.md §1). */\n readonly knownEffectInternalsRoot?: string | undefined;\n /** Optional minimum confidence threshold for discovered programs. */\n readonly minDiscoveryConfidence?: 'low' | 'medium' | 'high' | undefined;\n /** When true, only keep discovered programs whose roots are exported (or top-level run statements). */\n readonly onlyExportedPrograms?: boolean | undefined;\n /** Enable effect-flow analysis for raw control-flow constructs (if/switch/try-catch/loops). */\n readonly enableEffectFlow?: boolean | undefined;\n}\n\n// =============================================================================\n// Effect-based Analysis Result\n// =============================================================================\n\n/**\n * Result of static analysis - wrapped in Effect for composability.\n */\nexport type AnalysisResult = Effect.Effect<StaticEffectIR, AnalysisError>;\n\n/**\n * Errors that can occur during analysis.\n */\nexport class AnalysisError extends Error {\n readonly code: string;\n readonly location?: SourceLocation | undefined;\n\n constructor(\n code: string,\n message: string,\n location?: SourceLocation ,\n ) {\n super(message);\n this.code = code;\n this.location = location;\n this.name = 'AnalysisError';\n }\n}\n\n// =============================================================================\n// Path Analysis Types\n// =============================================================================\n\n/**\n * A single execution path through the effect program.\n */\nexport interface EffectPath {\n readonly id: string;\n readonly description: string;\n readonly steps: readonly PathStepRef[];\n readonly conditions: readonly PathCondition[];\n readonly hasLoops: boolean;\n readonly hasUnresolvedRefs: boolean;\n}\n\n/**\n * Reference to a step in a path.\n */\nexport interface PathStepRef {\n readonly nodeId: string;\n readonly name?: string | undefined;\n readonly repeated: boolean;\n}\n\n/**\n * A condition for a path.\n */\nexport interface PathCondition {\n readonly expression: string;\n readonly mustBe: boolean;\n readonly location?: SourceLocation | undefined;\n}\n\n// =============================================================================\n// Complexity Types\n// =============================================================================\n\n/**\n * Complexity metrics for an effect program.\n */\nexport interface ComplexityMetrics {\n readonly cyclomaticComplexity: number;\n readonly pathCount: number | 'unbounded';\n readonly maxDepth: number;\n readonly maxParallelBreadth: number;\n readonly decisionPoints: number;\n readonly cognitiveComplexity: number;\n}\n\n/**\n * Complexity thresholds.\n */\nexport interface ComplexityThresholds {\n readonly cyclomaticWarning: number;\n readonly cyclomaticError: number;\n readonly pathCountWarning: number;\n readonly maxDepthWarning: number;\n}\n\n// =============================================================================\n// Test Matrix Types\n// =============================================================================\n\n/**\n * Test coverage matrix.\n */\nexport interface TestMatrix {\n readonly paths: readonly TestPath[];\n readonly conditions: readonly TestCondition[];\n readonly summary: TestMatrixSummary;\n}\n\n/**\n * A path in the test matrix.\n */\nexport interface TestPath {\n readonly id: string;\n readonly suggestedTestName: string;\n readonly description: string;\n readonly setupConditions: readonly string[];\n readonly expectedSteps: readonly string[];\n readonly priority: 'high' | 'medium' | 'low';\n}\n\n/**\n * A condition affecting tests.\n */\nexport interface TestCondition {\n readonly expression: string;\n readonly affectedPathsWhenTrue: readonly string[];\n readonly affectedPathsWhenFalse: readonly string[];\n}\n\n/**\n * Test matrix summary.\n */\nexport interface TestMatrixSummary {\n readonly totalPaths: number;\n readonly highPriorityPaths: number;\n readonly totalConditions: number;\n readonly minTestsForCoverage: number;\n}\n\n// =============================================================================\n// Type Guards (using Effect Option)\n// =============================================================================\n\nexport const isStaticEffectNode = (\n node: StaticFlowNode,\n): node is StaticEffectNode => node.type === 'effect';\n\nexport const isStaticGeneratorNode = (\n node: StaticFlowNode,\n): node is StaticGeneratorNode => node.type === 'generator';\n\nexport const isStaticPipeNode = (\n node: StaticFlowNode,\n): node is StaticPipeNode => node.type === 'pipe';\n\nexport const isStaticParallelNode = (\n node: StaticFlowNode,\n): node is StaticParallelNode => node.type === 'parallel';\n\nexport const isStaticRaceNode = (\n node: StaticFlowNode,\n): node is StaticRaceNode => node.type === 'race';\n\nexport const isStaticErrorHandlerNode = (\n node: StaticFlowNode,\n): node is StaticErrorHandlerNode => node.type === 'error-handler';\n\nexport const isStaticRetryNode = (\n node: StaticFlowNode,\n): node is StaticRetryNode => node.type === 'retry';\n\nexport const isStaticTimeoutNode = (\n node: StaticFlowNode,\n): node is StaticTimeoutNode => node.type === 'timeout';\n\nexport const isStaticResourceNode = (\n node: StaticFlowNode,\n): node is StaticResourceNode => node.type === 'resource';\n\nexport const isStaticConditionalNode = (\n node: StaticFlowNode,\n): node is StaticConditionalNode => node.type === 'conditional';\n\nexport const isStaticLoopNode = (\n node: StaticFlowNode,\n): node is StaticLoopNode => node.type === 'loop';\n\nexport const isStaticLayerNode = (\n node: StaticFlowNode,\n): node is StaticLayerNode => node.type === 'layer';\n\nexport const isStaticCauseNode = (\n node: StaticFlowNode,\n): node is StaticCauseNode => node.type === 'cause';\n\nexport const isStaticExitNode = (\n node: StaticFlowNode,\n): node is StaticExitNode => node.type === 'exit';\n\nexport const isStaticScheduleNode = (\n node: StaticFlowNode,\n): node is StaticScheduleNode => node.type === 'schedule';\n\nexport const isStaticMatchNode = (\n node: StaticFlowNode,\n): node is StaticMatchNode => node.type === 'match';\n\nexport const isStaticTransformNode = (\n node: StaticFlowNode,\n): node is StaticTransformNode => node.type === 'transform';\n\nexport const isStaticStreamNode = (\n node: StaticFlowNode,\n): node is StaticStreamNode => node.type === 'stream';\n\nexport const isStaticChannelNode = (\n node: StaticFlowNode,\n): node is StaticChannelNode => node.type === 'channel';\n\nexport const isStaticSinkNode = (\n node: StaticFlowNode,\n): node is StaticSinkNode => node.type === 'sink';\n\n/**\n * Collect all `StreamOperatorInfo` entries from a stream node, traversing\n * nested `source` links (for curried pipe-style chains not yet flattened).\n */\nexport const collectStreamPipeline = (node: StaticStreamNode): readonly StreamOperatorInfo[] => {\n const ops: StreamOperatorInfo[] = [];\n const seen = new Set<string>();\n let current: StaticFlowNode = node;\n while (current.type === 'stream') {\n const s: StaticStreamNode = current;\n if (seen.has(s.id)) break;\n seen.add(s.id);\n // pipeline is already flattened if data-last; just collect\n ops.unshift(...s.pipeline);\n current = s.source;\n }\n return ops;\n};\n\nexport const isStaticConcurrencyPrimitiveNode = (\n node: StaticFlowNode,\n): node is StaticConcurrencyPrimitiveNode => node.type === 'concurrency-primitive';\n\nexport const isStaticFiberNode = (\n node: StaticFlowNode,\n): node is StaticFiberNode => node.type === 'fiber';\n\nexport const isStaticInterruptionNode = (\n node: StaticFlowNode,\n): node is StaticInterruptionNode => node.type === 'interruption';\n\nexport const isStaticUnknownNode = (\n node: StaticFlowNode,\n): node is StaticUnknownNode => node.type === 'unknown';\n\nexport const isStaticDecisionNode = (node: StaticFlowNode): node is StaticDecisionNode => node.type === 'decision';\nexport const isStaticSwitchNode = (node: StaticFlowNode): node is StaticSwitchNode => node.type === 'switch';\nexport const isStaticTryCatchNode = (node: StaticFlowNode): node is StaticTryCatchNode => node.type === 'try-catch';\nexport const isStaticTerminalNode = (node: StaticFlowNode): node is StaticTerminalNode => node.type === 'terminal';\nexport const isStaticOpaqueNode = (node: StaticFlowNode): node is StaticOpaqueNode => node.type === 'opaque';\n\n// =============================================================================\n// Output Types\n// =============================================================================\n\n/**\n * Options for JSON output rendering.\n */\nexport interface JSONRenderOptions {\n readonly pretty: boolean;\n readonly includeMetadata: boolean;\n readonly compact: boolean;\n}\n\n/**\n * Style definitions for Mermaid diagram output.\n */\nexport interface MermaidStyles {\n readonly effect: string;\n readonly generator: string;\n readonly pipe: string;\n readonly parallel: string;\n readonly race: string;\n readonly errorHandler: string;\n readonly retry: string;\n readonly timeout: string;\n readonly resource: string;\n readonly conditional: string;\n readonly loop: string;\n readonly layer: string;\n readonly stream?: string | undefined;\n readonly concurrencyPrimitive?: string | undefined;\n readonly fiber?: string | undefined;\n readonly unknown: string;\n /** Start node style */\n readonly start?: string | undefined;\n /** End node style */\n readonly end?: string | undefined;\n /** Decision node style */\n readonly decision?: string | undefined;\n /** Switch node style */\n readonly switch?: string | undefined;\n /** Try/catch node style */\n readonly tryCatch?: string | undefined;\n /** Terminal node style */\n readonly terminal?: string | undefined;\n /** Opaque node style */\n readonly opaque?: string | undefined;\n /** Cause node style */\n readonly cause?: string | undefined;\n /** Exit node style */\n readonly exit?: string | undefined;\n /** Schedule node style */\n readonly schedule?: string | undefined;\n /** Match node style */\n readonly match?: string | undefined;\n /** Transform node style */\n readonly transform?: string | undefined;\n /** Channel node style */\n readonly channel?: string | undefined;\n /** Sink node style */\n readonly sink?: string | undefined;\n /** Interruption node style */\n readonly interruption?: string | undefined;\n}\n\n/**\n * Options for Mermaid diagram output.\n */\nexport interface MermaidOptions {\n readonly direction: 'TB' | 'LR' | 'BT' | 'RL';\n readonly includeIds: boolean;\n readonly includeDescriptions: boolean;\n readonly styles: MermaidStyles;\n readonly compact: boolean;\n readonly title?: string | undefined;\n /** Include type signatures (A, E, R) on effect nodes */\n readonly includeTypeSignatures?: boolean | undefined;\n /** Wrap parallel/race blocks in subgraphs */\n readonly useSubgraphs?: boolean | undefined;\n /** Show condition labels on edges (e.g. true/false for conditionals) */\n readonly showConditions?: boolean | undefined;\n /** Level of detail in node labels: compact (callee only), standard (+ variable names), verbose (+ types + roles) */\n readonly detail?: MermaidDetailLevel | undefined;\n /** Overlay data-flow variable annotations on edges and warning classes on nodes */\n readonly dataFlowOverlay?: boolean | undefined;\n /** Overlay error-flow annotations (error types, unhandled errors) on nodes */\n readonly errorFlowOverlay?: boolean | undefined;\n}\n\n/**\n * Get children of a node as an Option.\n * Accepts StaticFlowNode or StaticEffectProgram (root) so that walking from ir.root works.\n */\nexport const getStaticChildren = (\n node: StaticFlowNode | StaticEffectProgram,\n): Option.Option<readonly StaticFlowNode[]> => {\n switch (node.type) {\n case 'program':\n return Option.some(node.children);\n case 'generator':\n return Option.some(node.yields.map((y) => y.effect));\n case 'pipe':\n return Option.some([node.initial, ...node.transformations]);\n case 'parallel':\n case 'race':\n return Option.some([...node.children]);\n case 'error-handler':\n return Option.some(\n node.handler ? [node.source, node.handler] : [node.source],\n );\n case 'retry': {\n const retryNode = node;\n const list = ([retryNode.source, retryNode.scheduleNode] as (StaticFlowNode | undefined)[]).filter(\n (n): n is StaticFlowNode => n !== undefined,\n );\n return list.length > 0 ? Option.some(list) : Option.none();\n }\n case 'timeout': {\n const src = node.source as StaticFlowNode | undefined;\n return src ? Option.some([src]) : Option.none();\n }\n case 'resource':\n return Option.some(\n node.use\n ? [node.acquire, node.release, node.use]\n : [node.acquire, node.release],\n );\n case 'conditional':\n return Option.some(\n node.onFalse ? [node.onTrue, node.onFalse] : [node.onTrue],\n );\n case 'loop':\n return Option.some([node.body]);\n case 'cause':\n return node.children && node.children.length > 0\n ? Option.some(node.children)\n : Option.none();\n case 'exit':\n case 'schedule':\n case 'match':\n return Option.none();\n case 'transform':\n return node.source ? Option.some([node.source]) : Option.none();\n case 'layer':\n return Option.some([...node.operations]);\n case 'stream':\n return Option.some([node.source]);\n case 'channel':\n return node.source ? Option.some([node.source]) : Option.none();\n case 'sink':\n return node.source ? Option.some([node.source]) : Option.none();\n case 'concurrency-primitive':\n return node.source ? Option.some([node.source]) : Option.none();\n case 'fiber':\n return node.fiberSource ? Option.some([node.fiberSource]) : Option.none();\n case 'interruption': {\n const children: StaticFlowNode[] = [];\n if (node.source) children.push(node.source);\n if (node.handler) children.push(node.handler);\n return children.length > 0 ? Option.some(children) : Option.none();\n }\n case 'effect':\n return node.callbackBody && node.callbackBody.length > 0\n ? Option.some([...node.callbackBody])\n : Option.none();\n case 'decision':\n return Option.some([...node.onTrue, ...(node.onFalse ?? [])]);\n case 'switch':\n return Option.some(node.cases.flatMap(c => [...c.body]));\n case 'try-catch':\n return Option.some([...node.tryBody, ...(node.catchBody ?? []), ...(node.finallyBody ?? [])]);\n case 'terminal':\n return node.value ? Option.some([...node.value]) : Option.none();\n case 'opaque':\n return Option.none();\n default:\n return Option.none();\n }\n};\n\n// =============================================================================\n// Service Artifact Types (whole-codebase service mapping)\n// =============================================================================\n\n/**\n * A layer implementation that provides a service.\n */\nexport interface LayerImplementation {\n /** Name of the layer variable (e.g. 'UserRepoLive') */\n readonly name: string;\n /** File where the layer is defined */\n readonly filePath: string;\n /** Source location of the layer definition */\n readonly location: SourceLocation;\n /** Layer kind */\n readonly kind: 'effect' | 'succeed' | 'sync' | 'scoped' | 'other';\n /** Services required by this layer implementation */\n readonly requires: readonly string[];\n /** IR of the layer's implementation body (if analyzable) */\n readonly bodyIR?: StaticEffectIR | undefined;\n}\n\n/**\n * A reference to a program that consumes a service.\n */\nexport interface ServiceConsumerRef {\n /** Program name that uses this service */\n readonly programName: string;\n /** File containing the program */\n readonly filePath: string;\n /** Location of the yield* call */\n readonly location?: SourceLocation | undefined;\n}\n\n/**\n * First-class artifact for an Effect service, deduplicated at the project level.\n */\nexport interface ServiceArtifact {\n /** Unique service identifier (tag string, e.g. 'UserRepo') */\n readonly serviceId: string;\n /** Class name (may differ from serviceId if tag string differs) */\n readonly className: string;\n /** File where the service tag class is defined */\n readonly definitionFilePath: string;\n /** Source location of the class declaration */\n readonly definitionLocation: SourceLocation;\n /** Interface shape (methods, properties) */\n readonly definition: ServiceDefinition;\n /** Full type text of the service interface */\n readonly interfaceTypeText?: string | undefined;\n /** Layer implementations that provide this service */\n readonly layerImplementations: readonly LayerImplementation[];\n /** Programs that consume (yield*) this service */\n readonly consumers: readonly ServiceConsumerRef[];\n /** Services this service's layers depend on (transitive requirements) */\n readonly dependencies: readonly string[];\n}\n\n/**\n * Project-level deduplicated service map.\n */\nexport interface ProjectServiceMap {\n /** Map from serviceId to its artifact */\n readonly services: ReadonlyMap<string, ServiceArtifact>;\n /** Services referenced but with no tag definition found */\n readonly unresolvedServices: readonly string[];\n /** Topological order of services (leaves first) */\n readonly topologicalOrder: readonly string[];\n}\n\n// =============================================================================\n// Showcase Types\n// =============================================================================\n\nexport interface ShowcaseStepDetail {\n readonly stepId: string;\n readonly name: string;\n readonly callee: string;\n // Output type\n readonly outputType: string;\n readonly outputTypeKind: 'declared' | 'inferred' | 'unknown';\n readonly outputTypeDisplay: string;\n readonly outputTypeText: string;\n // Error type\n readonly errorTypeDisplay: string;\n readonly errors: readonly string[];\n // Dependency\n readonly depSource?: string | undefined;\n // Step kind\n readonly stepKind?: string | undefined;\n // Retry/timeout/resource/loop context (optional)\n readonly retry?: { readonly attempts: number | 'unlimited'; readonly backoff: string } | undefined;\n readonly timeout?: { readonly ms: string } | undefined;\n readonly kind?: 'resource' | undefined;\n readonly acquire?: string | undefined;\n readonly use?: string | undefined;\n readonly release?: string | undefined;\n readonly repeats?: 'loop' | undefined;\n readonly loopType?: string | undefined;\n readonly iterationSource?: string | undefined;\n}\n\nexport interface ShowcaseEntry {\n readonly title: string;\n readonly code: string;\n readonly mermaid: string;\n readonly stepDetails: readonly ShowcaseStepDetail[];\n}\n","/**\n * Static Effect Analyzer\n *\n * Uses ts-morph to walk the TypeScript AST and extract Effect structure\n * without executing the code. Built entirely with Effect for composability.\n *\n * Public API: analyzeEffectFile, analyzeEffectSource, resetIdCounter.\n * Implementation is split across analysis-utils, analysis-patterns, alias-resolution,\n * program-discovery, effect-analysis, and core-analysis.\n */\n\nimport { Effect } from 'effect';\nimport {\n loadTsMorph,\n createProject,\n createProjectFromSource,\n} from './ts-morph-loader';\nimport { AnalysisError } from './types';\nimport type { StaticEffectIR, AnalyzerOptions } from './types';\nimport { DEFAULT_OPTIONS, isJsOrJsxPath } from './analysis-utils';\nimport { findEffectPrograms } from './program-discovery';\nimport { analyzeProgram } from './core-analysis';\n\nexport { resetIdCounter } from './analysis-utils';\n\nexport const analyzeEffectFile = (\n filePath: string,\n options?: AnalyzerOptions,\n): Effect.Effect<readonly StaticEffectIR[], AnalysisError> =>\n Effect.gen(function* () {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const { ts, Project } = loadTsMorph();\n\n const project = yield* Effect.try({\n try: () => {\n if (isJsOrJsxPath(filePath)) {\n return new Project({\n skipAddingFilesFromTsConfig: true,\n compilerOptions: { allowJs: true },\n });\n }\n return createProject(opts.tsConfigPath);\n },\n catch: (error) =>\n new AnalysisError(\n 'PROJECT_CREATION_FAILED',\n `Failed to create project: ${String(error)}`,\n ),\n });\n\n const existingFile = project.getSourceFile(filePath);\n if (existingFile) {\n project.removeSourceFile(existingFile);\n }\n\n const sourceFile = yield* Effect.try({\n try: () => project.addSourceFileAtPath(filePath),\n catch: (error) =>\n new AnalysisError(\n 'FILE_NOT_FOUND',\n `Failed to load file ${filePath}: ${String(error)}`,\n ),\n });\n\n const programs = findEffectPrograms(sourceFile, opts);\n\n if (programs.length === 0) {\n return yield* Effect.fail(\n new AnalysisError(\n 'NO_EFFECTS_FOUND',\n `No Effect programs found in ${filePath}`,\n ),\n );\n }\n\n return yield* Effect.forEach(\n programs,\n (program) =>\n analyzeProgram(program, sourceFile, filePath, opts, ts.version),\n { concurrency: 'unbounded' },\n );\n });\n\nexport const analyzeEffectSource = (\n code: string,\n filePath = 'temp.ts',\n options?: AnalyzerOptions,\n): Effect.Effect<readonly StaticEffectIR[], AnalysisError> =>\n Effect.gen(function* () {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const { ts } = loadTsMorph();\n\n const sourceFile = yield* Effect.try({\n try: () => createProjectFromSource(code, filePath),\n catch: (error) =>\n new AnalysisError(\n 'SOURCE_PARSE_FAILED',\n `Failed to parse source: ${String(error)}`,\n ),\n });\n\n const programs = findEffectPrograms(sourceFile, opts);\n\n if (programs.length === 0) {\n return yield* Effect.fail(\n new AnalysisError(\n 'NO_EFFECTS_FOUND',\n `No Effect programs found in source`,\n ),\n );\n }\n\n return yield* Effect.forEach(\n programs,\n (program) =>\n analyzeProgram(program, sourceFile, filePath, opts, ts.version),\n { concurrency: 'unbounded' },\n );\n });\n","/**\n * Dynamic ts-morph loader to avoid direct dependency issues\n */\n\nimport { createRequire } from 'node:module';\nimport type { Project, SourceFile } from 'ts-morph';\n\nlet tsMorphModule: typeof import('ts-morph') | null = null;\nconst projectCache = new Map<string, Project>();\n\n/**\n * Load ts-morph dynamically (peer dependency)\n */\nexport const loadTsMorph = (): typeof import('ts-morph') => {\n if (!tsMorphModule) {\n try {\n const require = createRequire(import.meta.url);\n tsMorphModule = require('ts-morph');\n } catch {\n throw new Error(\n 'ts-morph is required but not installed. Please install it as a peer dependency: npm install ts-morph',\n );\n }\n }\n return tsMorphModule!;\n};\n\n/**\n * Create a ts-morph project\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\n/**\n * Clear cached ts-morph projects.\n */\nexport const clearProjectCache = (): void => {\n projectCache.clear();\n};\n\n/**\n * Create a project from source code (for testing)\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 * Shared utilities for static Effect analysis: options, ID generation,\n * location/JSDoc extraction, dependency/error aggregation, program naming.\n */\n\nimport type {\n Node,\n VariableDeclaration,\n PropertyAssignment,\n CallExpression,\n FunctionDeclaration,\n ClassDeclaration,\n PropertyDeclaration,\n MethodDeclaration,\n GetAccessorDeclaration,\n} from 'ts-morph';\nimport { Option } from 'effect';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n AnalysisStats,\n AnalyzerOptions,\n DependencyInfo,\n JSDocTags,\n SemanticRole,\n SourceLocation,\n StaticFlowNode,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { splitTopLevelUnion } from './type-extractor';\n\n// =============================================================================\n// Default Options\n// =============================================================================\n\nexport const DEFAULT_OPTIONS: Required<AnalyzerOptions> = {\n tsConfigPath: './tsconfig.json',\n resolveReferences: true,\n maxReferenceDepth: 5,\n includeLocations: true,\n assumeImported: false,\n enableEffectWorkflow: false,\n knownEffectInternalsRoot: undefined,\n minDiscoveryConfidence: 'low',\n onlyExportedPrograms: false,\n enableEffectFlow: false,\n};\n\n// =============================================================================\n// ID Generation\n// =============================================================================\n\nlet idCounter = 0;\n\nexport const resetIdCounter = (): void => {\n idCounter = 0;\n};\n\nexport const generateId = (): string => `effect-${++idCounter}`;\n\n// =============================================================================\n// Node text cache (reduce repeated getText() on large nodes - improve.md §7)\n// =============================================================================\n\nconst nodeTextCache = new WeakMap<Node, string>();\n\nexport function getNodeText(node: Node): string {\n let text = nodeTextCache.get(node);\n if (text === undefined) {\n text = node.getText();\n nodeTextCache.set(node, text);\n }\n return text;\n}\n\n// =============================================================================\n// Program-level aggregation (dependencies, error types)\n// =============================================================================\n\nexport function collectErrorTypes(nodes: readonly StaticFlowNode[]): string[] {\n const set = new Set<string>();\n const visit = (list: readonly StaticFlowNode[]) => {\n for (const node of list) {\n if (node.type === 'effect') {\n const err = node.typeSignature?.errorType?.trim();\n if (err && err !== 'never') {\n for (const part of splitTopLevelUnion(err)) {\n set.add(part);\n }\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) visit(children);\n }\n };\n visit(nodes);\n return Array.from(set).sort();\n}\n\nexport function collectDependencies(nodes: readonly StaticFlowNode[]): DependencyInfo[] {\n const byName = new Map<string, DependencyInfo>();\n const visit = (list: readonly StaticFlowNode[]) => {\n for (const node of list) {\n if (node.type === 'effect') {\n const reqs = (node).requiredServices;\n if (reqs) {\n for (const r of reqs) {\n if (!byName.has(r.serviceId)) {\n byName.set(r.serviceId, {\n name: r.serviceId,\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 const looksLikeService = /^[A-Z]/.test(callee)\n && !callee.startsWith('Effect.')\n && !callee.startsWith('Schema.')\n && !callee.startsWith('Data.')\n && !callee.startsWith('Config.')\n && !callee.startsWith('Command.')\n && !callee.startsWith('Stream.')\n && !callee.startsWith('Option.')\n && !callee.startsWith('Either.')\n && !callee.startsWith('Cause.')\n && !callee.startsWith('Exit.');\n if (looksLikeService && !byName.has(callee)) {\n byName.set(callee, {\n name: callee,\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 };\n};\n\n// =============================================================================\n// JSDoc Extraction\n// =============================================================================\n\n/**\n * Extract JSDoc description from a node.\n * Uses ts-morph's getJsDocs() method with fallback to leading comment ranges.\n * Extracts only the description text (before first @tag).\n */\nexport const extractJSDocDescription = (node: Node): string | undefined => {\n // Try to get JSDoc from the node directly using ts-morph\n const jsDocs = (\n node as unknown as {\n getJsDocs?: () => {\n getText: () => string;\n getComment?: () => string | { text: string }[];\n }[];\n }\n ).getJsDocs?.();\n\n if (jsDocs && jsDocs.length > 0) {\n const firstJsDoc = jsDocs[0];\n if (!firstJsDoc) return undefined;\n const comment = firstJsDoc.getComment?.();\n\n if (comment) {\n // Handle both string and array comment formats\n let description: string;\n if (typeof comment === 'string') {\n description = comment;\n } else if (Array.isArray(comment)) {\n description = comment.map((c) => c.text).join('\\n');\n } else {\n return undefined;\n }\n\n // Extract only the description (before first @tag)\n const tagIndex = description.search(/\\n\\s*@/);\n if (tagIndex !== -1) {\n description = description.substring(0, tagIndex);\n }\n\n return description.trim() || undefined;\n }\n\n // Fallback to parsing the raw JSDoc text\n const rawText = firstJsDoc.getText();\n const descriptionMatch = /\\/\\*\\*\\s*\\n?\\s*\\*\\s*([^@]*?)(?=\\n\\s*\\*\\s*@|\\*\\/)/.exec(rawText);\n if (descriptionMatch?.[1]) {\n return (\n descriptionMatch[1].replace(/\\n\\s*\\*\\s*/g, ' ').trim() || undefined\n );\n }\n }\n\n // Fallback: use leading comment ranges\n const leadingComments = node.getLeadingCommentRanges();\n if (leadingComments.length > 0) {\n const lastComment = leadingComments[leadingComments.length - 1];\n if (!lastComment) return undefined;\n\n const commentText = lastComment.getText();\n\n // Check if it's a JSDoc comment\n if (commentText.startsWith('/**')) {\n // Remove /** and */ and * prefixes\n const cleaned = commentText\n .replace(/^\\/\\*\\*\\s*/, '')\n .replace(/\\s*\\*\\/\\s*$/, '')\n .replace(/^\\s*\\*\\s?/gm, '')\n .trim();\n\n // Extract only the description (before first @tag)\n const tagIndex = cleaned.search(/\\n@/);\n if (tagIndex !== -1) {\n return cleaned.substring(0, tagIndex).trim() || undefined;\n }\n\n return cleaned || undefined;\n }\n }\n\n return undefined;\n};\n\n/**\n * Extract structured JSDoc tags (@param, @returns, @throws, @example) from a node.\n * Returns undefined if no structured tags are present.\n */\nexport const extractJSDocTags = (node: Node): JSDocTags | undefined => {\n const tryGetJsDocText = (n: Node): string | undefined => {\n const jsDocs = (\n n as unknown as {\n getJsDocs?: () => { getText: () => string }[];\n }\n ).getJsDocs?.();\n if (jsDocs && jsDocs.length > 0) {\n return jsDocs[0]!.getText();\n }\n // Fallback: leading comment ranges\n const leadingComments = n.getLeadingCommentRanges();\n if (leadingComments.length > 0) {\n const lastComment = leadingComments[leadingComments.length - 1];\n if (lastComment) {\n const commentText = lastComment.getText();\n if (commentText.startsWith('/**')) return commentText;\n }\n }\n return undefined;\n };\n\n // Try the node itself first\n let text = tryGetJsDocText(node);\n\n // Walk up to find JSDoc on parent statement (same logic as getJSDocFromParentVariable)\n if (!text) {\n const { SyntaxKind } = loadTsMorph();\n let current = node.getParent();\n // Walk through CallExpression → ArrowFunction → VariableDeclaration → VariableDeclarationList → VariableStatement\n while (current && !text) {\n const kind = current.getKind();\n if (kind === SyntaxKind.VariableStatement) {\n text = tryGetJsDocText(current);\n break;\n }\n if (kind === SyntaxKind.VariableDeclarationList) {\n const grandparent = current.getParent();\n if (grandparent) {\n text = tryGetJsDocText(grandparent);\n }\n break;\n }\n // Keep walking up through CallExpression, ArrowFunction, VariableDeclaration\n if (\n kind === SyntaxKind.CallExpression ||\n kind === SyntaxKind.ArrowFunction ||\n kind === SyntaxKind.VariableDeclaration ||\n kind === SyntaxKind.ParenthesizedExpression\n ) {\n current = current.getParent();\n } else {\n break;\n }\n }\n }\n\n if (!text) return undefined;\n return parseJSDocTags(text);\n};\n\nfunction parseJSDocTags(rawText: string): JSDocTags | undefined {\n const cleaned = rawText\n .replace(/^\\/\\*\\*/, '')\n .replace(/\\*\\/$/, '')\n .split('\\n')\n .map(line => line.replace(/^\\s*\\*\\s?/, ''))\n .join('\\n');\n\n const params: { name: string; description?: string }[] = [];\n let returns: string | undefined;\n const throws: string[] = [];\n let example: string | undefined;\n\n const tagPattern = /@(param|returns?|throws?|exception|example)\\s*(.*)/gi;\n let match: RegExpExecArray | null;\n\n while ((match = tagPattern.exec(cleaned)) !== null) {\n const tag = match[1]!.toLowerCase();\n const rest = match[2]!.trim();\n\n if (tag === 'param') {\n const paramMatch =\n /^(?:\\{[^}]*\\}\\s*)?(\\[?\\w+(?:=[^\\]]*)?]?)\\s*(?:-\\s*(.*))?$/.exec(rest);\n if (paramMatch) {\n const name = paramMatch[1]!.replace(/^\\[|\\]$/g, '').replace(/=.*/, '');\n const description = paramMatch[2]?.trim();\n params.push(description ? { name, description } : { name });\n }\n } else if (tag === 'returns' || tag === 'return') {\n returns = rest.replace(/^\\{[^}]*\\}\\s*/, '').trim() || undefined;\n } else if (tag === 'throws' || tag === 'throw' || tag === 'exception') {\n const value = rest.replace(/^\\{[^}]*\\}\\s*/, '').trim();\n if (value) throws.push(value);\n } else if (tag === 'example') {\n // @example may span multiple lines until next @tag or end of comment\n const exampleStart = match.index + match[0].length;\n const nextTagMatch = /\\n\\s*@\\w/.exec(cleaned.slice(exampleStart));\n if (nextTagMatch) {\n const block = cleaned.slice(match.index + match[0].length - rest.length, exampleStart + nextTagMatch.index);\n example = block.trim() || undefined;\n } else {\n const block = cleaned.slice(match.index + match[0].length - rest.length);\n example = block.trim() || undefined;\n }\n }\n }\n\n if (params.length === 0 && !returns && throws.length === 0 && !example) {\n return undefined;\n }\n\n return { params, returns, throws, example };\n}\n\n/**\n * Get JSDoc description from the parent variable declaration of a node.\n * Used to extract program-level JSDoc from the variable above an Effect program.\n */\nexport const getJSDocFromParentVariable = (node: Node): string | undefined => {\n const parent = node.getParent();\n const { SyntaxKind } = loadTsMorph();\n\n if (parent) {\n const parentKind = parent.getKind();\n\n if (parentKind === SyntaxKind.VariableDeclaration) {\n return extractJSDocDescription(parent);\n }\n\n // Check for arrow function assignment\n if (parentKind === SyntaxKind.ArrowFunction) {\n const grandparent = parent.getParent();\n if (grandparent?.getKind() === SyntaxKind.VariableDeclaration) {\n return extractJSDocDescription(grandparent);\n }\n }\n }\n\n return undefined;\n};\n\n// =============================================================================\n// Path / file helpers\n// =============================================================================\n\n/** Gap 6: .js/.jsx need allowJs and a minimal project so tsconfig does not exclude them. */\nexport function isJsOrJsxPath(path: string): boolean {\n return path.endsWith('.js') || path.endsWith('.jsx');\n}\n\n// =============================================================================\n// EffectProgram type (used by program-discovery and core-analysis)\n// =============================================================================\n\nexport interface EffectProgram {\n readonly name: string;\n readonly discoveryConfidence?: 'high' | 'medium' | 'low';\n readonly discoveryReason?: string;\n readonly node: CallExpression | FunctionDeclaration | VariableDeclaration | ClassDeclaration\n | PropertyDeclaration | MethodDeclaration | GetAccessorDeclaration;\n readonly type: 'generator' | 'direct' | 'pipe' | 'run' | 'workflow-execute' | 'class' | 'classProperty' | 'classMethod';\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/**\n * Truncate a string to `max` characters, appending an ellipsis if truncated.\n */\nconst truncate = (s: string, max: number): string =>\n s.length <= max ? s : `${s.slice(0, max)}…`;\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 prefix = variableName ?? node.name;\n return prefix ? `${prefix} <- ${node.callee}` : node.callee;\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 ? `${node.loopType}(${node.iterSource})` : node.loopType;\n\n case 'layer':\n return node.isMerged ? 'Layer (merged)' : 'Layer';\n\n case 'stream': {\n const ops = node.pipeline.map((op) => op.operation);\n const parts: string[] = ['Stream', ...ops];\n if (node.sink) parts.push(node.sink);\n return parts.join(' → ');\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 * 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) 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 * Type Signature Extractor\n *\n * Uses ts-morph's TypeChecker to extract Effect type parameters:\n * - A (Success type)\n * - E (Error type)\n * - R (Requirements/Context type)\n */\n\nimport type { Type, Node, TypeChecker, VariableDeclaration, CallExpression } from 'ts-morph';\nimport type {\n EffectTypeSignature,\n ServiceRequirement,\n SourceLocation,\n StreamTypeSignature,\n LayerTypeSignature,\n ScheduleTypeSignature,\n CauseTypeSignature,\n} from './types';\n\n// =============================================================================\n// Type Extraction\n// =============================================================================\n\n/** Regex to parse Effect<A, E, R> from type text when Type API fails */\nconst EFFECT_TYPE_REGEX_3 = /Effect(?:\\.Effect)?<([^,]+),\\s*([^,]+),\\s*([^>]+)>/;\n/** Regex to parse Effect<A, E> (2 params, R defaults to never in Effect v3) */\nconst EFFECT_TYPE_REGEX_2 = /Effect(?:\\.Effect)?<([^,>]+),\\s*([^,>]+)>/;\n\n/**\n * Build EffectTypeSignature from type text using regex (fallback when Type API has no type args).\n */\nexport function effectTypeSignatureFromTypeText(\n typeText: string,\n): EffectTypeSignature | undefined {\n const clean = (s: string) =>\n s\n .replace(/import\\([^)]+\\)\\./g, '')\n .replace(/typeof\\s+/g, '')\n .trim()\n .substring(0, 200);\n\n // Try 3-param: Effect<A, E, R>\n const match3 = EFFECT_TYPE_REGEX_3.exec(typeText);\n if (match3) {\n return {\n successType: clean(match3[1]!),\n errorType: clean(match3[2]!),\n requirementsType: clean(match3[3]!),\n isInferred: false,\n typeConfidence: 'inferred',\n rawTypeString: typeText,\n };\n }\n\n // Try 2-param: Effect<A, E> (R defaults to never in Effect v3)\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 * 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 return {\n successType: typeToString(aType),\n errorType: typeToString(eType),\n requirementsType: typeToString(rType),\n isInferred: true,\n typeConfidence: 'declared',\n rawTypeString: nodeType.getText(),\n };\n }\n\n // Fallback: parse A, E, R from type text when Type API doesn't provide type args\n const typeText = nodeType.getText();\n const fromText = effectTypeSignatureFromTypeText(typeText);\n if (fromText) return fromText;\n\n // Fallback: resolve the callee function's return type annotation\n const fromCallee = tryExtractFromCalleeReturnType(node);\n if (fromCallee) return fromCallee;\n\n return {\n successType: 'unknown',\n errorType: 'never',\n requirementsType: 'never',\n isInferred: false,\n typeConfidence: 'unknown',\n rawTypeString: typeText,\n };\n};\n\n/**\n * When a call expression's resolved type lacks type args, try to extract\n * Effect<A, E, R> from the callee function's declared return type annotation.\n *\n * For `yield* validate(input)` where `validate` is declared as:\n * `const validate = (input: T): Effect.Effect<A, E, R> => ...`\n * We resolve `validate` → get its return type annotation text → parse Effect<A, E, R>.\n */\nfunction tryExtractFromCalleeReturnType(node: Node): EffectTypeSignature | undefined {\n try {\n // Only works for call expressions\n if (!('getExpression' in node)) return undefined;\n const call = node as CallExpression;\n const callee = call.getExpression();\n\n // Try to get the callee's return type from its signature\n const calleeType = callee.getType();\n const callSignatures = calleeType.getCallSignatures();\n if (callSignatures.length > 0) {\n const returnType = callSignatures[0]!.getReturnType();\n\n // Try type arguments on the return type\n const returnArgs = extractTypeArguments(returnType);\n if (returnArgs) {\n const [aType, eType, rType] = returnArgs;\n return {\n successType: typeToString(aType),\n errorType: typeToString(eType),\n requirementsType: typeToString(rType),\n isInferred: true,\n typeConfidence: 'inferred',\n rawTypeString: returnType.getText(),\n };\n }\n\n // Try regex on the return type text\n const returnText = returnType.getText();\n const fromReturnText = effectTypeSignatureFromTypeText(returnText);\n if (fromReturnText) return fromReturnText;\n }\n\n // Try to resolve the callee to its declaration and read the return type annotation\n const symbol = callee.getSymbol();\n if (!symbol) return undefined;\n\n for (const decl of symbol.getDeclarations()) {\n // Get the return type annotation text from the declaration\n let returnTypeText: string | undefined;\n\n if ('getReturnType' in decl) {\n // Function/method declarations\n const declType = (decl as { getReturnType: () => Type }).getReturnType();\n returnTypeText = declType.getText();\n } else if ('getType' in decl) {\n // Variable declarations: get the type of the variable, then its call signatures\n const varType = (decl as { getType: () => Type }).getType();\n const sigs = varType.getCallSignatures();\n if (sigs.length > 0) {\n const retType = sigs[0]!.getReturnType();\n const retArgs = extractTypeArguments(retType);\n if (retArgs) {\n const [aType, eType, rType] = retArgs;\n return {\n successType: typeToString(aType),\n errorType: typeToString(eType),\n requirementsType: typeToString(rType),\n isInferred: true,\n typeConfidence: 'inferred',\n rawTypeString: retType.getText(),\n };\n }\n returnTypeText = retType.getText();\n }\n }\n\n if (returnTypeText) {\n const fromAnnotation = effectTypeSignatureFromTypeText(returnTypeText);\n if (fromAnnotation) {\n return { ...fromAnnotation, typeConfidence: 'inferred' };\n }\n }\n }\n } catch {\n // Callee resolution can fail for dynamic or unresolvable expressions\n }\n return undefined;\n}\n\n/**\n * Check if a type is an Effect type\n */\nconst isEffectType = (type: Type): boolean => {\n const symbol = type.getSymbol();\n const typeText = type.getText();\n \n // Check by symbol name\n if (symbol) {\n const name = symbol.getName();\n if (name === 'Effect' || name.includes('Effect')) {\n return true;\n }\n }\n \n // Check by type text pattern\n if (typeText.includes('Effect<') || typeText.startsWith('Effect.')) {\n return true;\n }\n \n // Check for Effect interface\n const aliasSymbol = type.getAliasSymbol();\n if (aliasSymbol) {\n const aliasName = aliasSymbol.getName();\n if (aliasName === 'Effect' || aliasName.includes('Effect')) {\n return true;\n }\n }\n \n return false;\n};\n\n/**\n * Extract type arguments from an Effect type\n * Returns [A, E, R] or undefined\n */\nconst extractTypeArguments = (type: Type): [Type, Type, Type] | undefined => {\n try {\n const typeArgs = type.getTypeArguments?.();\n if (!typeArgs || typeArgs.length < 3) {\n const aliasTypeArgs = type.getAliasTypeArguments?.();\n if (aliasTypeArgs && aliasTypeArgs.length >= 3) {\n return [aliasTypeArgs[0]!, aliasTypeArgs[1]!, aliasTypeArgs[2]!];\n }\n return undefined;\n }\n return [typeArgs[0]!, typeArgs[1]!, typeArgs[2]!];\n } catch {\n return undefined;\n }\n};\n\n/**\n * Convert a Type to a readable string\n */\nconst typeToString = (type: Type): string => {\n const text = type.getText();\n \n // Clean up the type string\n return text\n .replace(/import\\([^)]+\\)\\./g, '') // Remove import paths\n .replace(/typeof\\s+/g, '') // Remove typeof\n .substring(0, 200); // Limit length\n};\n\n// =============================================================================\n// Service Requirement Extraction\n// =============================================================================\n\n/**\n * Extract service requirements from a Context type\n */\nexport const extractServiceRequirements = (\n node: Node,\n _typeChecker: TypeChecker,\n): ServiceRequirement[] => {\n const requirements: ServiceRequirement[] = [];\n \n // Try to get the type - first from the node, then from type annotation\n let nodeType = node.getType();\n let locationNode: Node = node;\n \n // If node type doesn't have the required info, try to get declared type from variable\n let nodeTypeArgs: readonly Type[] | undefined;\n try {\n nodeTypeArgs = typeof nodeType.getTypeArguments === 'function' ? nodeType.getTypeArguments() : undefined;\n } catch {\n nodeTypeArgs = undefined;\n }\n if (!nodeTypeArgs || nodeTypeArgs.length < 3) {\n const parent = node.getParent();\n if (parent?.getKindName() === 'VariableDeclaration') {\n const varDecl = parent as VariableDeclaration;\n const declaredType = varDecl.getType();\n if (declaredType) {\n nodeType = declaredType;\n locationNode = varDecl;\n }\n }\n }\n \n // Check if type contains Context requirements\n const rType = extractRequirementsType(nodeType);\n if (!rType) return requirements;\n \n // Extract individual services from the Context type\n const services = extractServicesFromContext(rType);\n \n for (const service of services) {\n const sourceFile = locationNode.getSourceFile();\n const { line, column } = sourceFile.getLineAndColumnAtPos(locationNode.getStart());\n const location: SourceLocation = {\n filePath: sourceFile.getFilePath(),\n line,\n column,\n };\n \n requirements.push({\n serviceId: service.id,\n serviceType: service.typeName,\n requiredAt: location,\n });\n }\n \n return requirements;\n};\n\n/**\n * Extract the R (requirements) type from an Effect type\n */\nconst extractRequirementsType = (type: Type): Type | undefined => {\n const typeArgs = extractTypeArguments(type);\n if (!typeArgs) return undefined;\n \n return typeArgs[2]; // R is the third type parameter\n};\n\n/**\n * Extract individual service types from a Context type\n */\nconst extractServicesFromContext = (contextType: Type): { id: string; typeName: string }[] => {\n const services: { id: string; typeName: string }[] = [];\n \n // Check if it's Context<Tag>\n const typeText = contextType.getText();\n \n // Try to extract Tag identifier from Context<Tag>\n const contextMatch = /Context<([^>]+)>/.exec(typeText);\n if (contextMatch) {\n const tagType = contextMatch[1]!;\n services.push({\n id: extractTagIdentifier(tagType),\n typeName: tagType,\n });\n }\n \n // Check for intersection types (Context<A> | Context<B>)\n if (typeText.includes('|')) {\n const parts = splitTopLevelUnion(typeText);\n for (const part of parts) {\n const match = /Context<([^>]+)>/.exec(part);\n if (match) {\n services.push({\n id: extractTagIdentifier(match[1]!),\n typeName: match[1]!,\n });\n }\n }\n }\n \n // Check for never type (no requirements)\n if (typeText === 'never' || typeText === '{}') {\n return [];\n }\n \n return services;\n};\n\n/**\n * Extract tag identifier from a Tag type string\n */\nconst extractTagIdentifier = (tagType: string): string => {\n // Try to extract from Tag<\"identifier\", ...>\n const match = /Tag<[\"']([^\"']+)[\"']/.exec(tagType);\n if (match) {\n return match[1]!;\n }\n \n // Fallback: use the type name\n return tagType.split('<')[0]!.trim();\n};\n\n// =============================================================================\n// Type Transformation Tracking\n// =============================================================================\n\n/**\n * Track how an Effect type transforms through a pipe operation\n */\nexport const trackTypeTransformation = (\n inputType: EffectTypeSignature,\n operation: string,\n outputType: EffectTypeSignature,\n): { operation: string; typeChange: string } => {\n const changes: string[] = [];\n \n if (inputType.successType !== outputType.successType) {\n changes.push(`${inputType.successType} → ${outputType.successType}`);\n }\n \n if (inputType.errorType !== outputType.errorType) {\n changes.push(`${inputType.errorType} → ${outputType.errorType}`);\n }\n \n if (inputType.requirementsType !== outputType.requirementsType) {\n changes.push(`${inputType.requirementsType} → ${outputType.requirementsType}`);\n }\n \n return {\n operation,\n typeChange: changes.length > 0 ? changes.join(', ') : 'no change',\n };\n};\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Split a type string on top-level `|` only, respecting angle brackets and string literals.\n * e.g. `Envelope<\"A\" | \"B\"> | FooError` → `[\"Envelope<\\\"A\\\" | \\\"B\\\">\", \"FooError\"]`\n */\nexport function splitTopLevelUnion(typeText: string): string[] {\n const parts: string[] = [];\n let current = '';\n let depth = 0; // angle bracket depth\n let inString: string | null = null;\n\n for (let i = 0; i < typeText.length; i++) {\n const ch = typeText[i]!;\n\n if (inString) {\n current += ch;\n if (ch === inString && typeText[i - 1] !== '\\\\') {\n inString = null;\n }\n continue;\n }\n\n if (ch === '\"' || ch === \"'\" || ch === '`') {\n inString = ch;\n current += ch;\n continue;\n }\n\n if (ch === '<' || ch === '(') {\n depth++;\n current += ch;\n continue;\n }\n\n if (ch === '>' || ch === ')') {\n depth = Math.max(0, depth - 1);\n current += ch;\n continue;\n }\n\n if (ch === '|' && depth === 0) {\n parts.push(current.trim());\n current = '';\n continue;\n }\n\n current += ch;\n }\n\n const last = current.trim();\n if (last) parts.push(last);\n\n return parts.filter(Boolean);\n}\n\n/**\n * Format type signature for display\n */\nexport const formatTypeSignature = (sig: EffectTypeSignature): string => {\n return `Effect<${sig.successType}, ${sig.errorType}, ${sig.requirementsType}>`;\n};\n\n// =============================================================================\n// Stream / Layer / Schedule / Cause type extraction (21.3)\n// =============================================================================\n\nconst cleanTypeArg = (s: string): string =>\n s\n .replace(/import\\([^)]+\\)\\./g, '')\n .replace(/typeof\\s+/g, '')\n .trim()\n .substring(0, 200);\n\n/** Regexes for type args when Type API has no type arguments */\nconst STREAM_TYPE_REGEX = /Stream<([^,]+),\\s*([^,]+),\\s*([^>]+)>/;\nconst LAYER_TYPE_REGEX = /Layer<([^,]+),\\s*([^,]+),\\s*([^>]+)>/;\nconst SCHEDULE_TYPE_REGEX = /Schedule<([^,]+),\\s*([^,]+),\\s*([^>]+)>/;\nconst CAUSE_TYPE_REGEX = /Cause<([^>]+)>/;\n\n/**\n * Extract Stream<A, E, R> type args from a node's type (regex fallback).\n */\nexport function extractStreamTypeSignature(node: Node): StreamTypeSignature | undefined {\n const typeText = node.getType().getText();\n const match = STREAM_TYPE_REGEX.exec(typeText);\n if (!match) return undefined;\n return {\n successType: cleanTypeArg(match[1]!),\n errorType: cleanTypeArg(match[2]!),\n requirementsType: cleanTypeArg(match[3]!),\n rawTypeString: typeText,\n };\n}\n\n/**\n * Extract Layer<ROut, E, RIn> type args from a node's type (regex fallback).\n */\nexport function extractLayerTypeSignature(node: Node): LayerTypeSignature | undefined {\n const typeText = node.getType().getText();\n const match = LAYER_TYPE_REGEX.exec(typeText);\n if (!match) return undefined;\n return {\n providedType: cleanTypeArg(match[1]!),\n errorType: cleanTypeArg(match[2]!),\n requiredType: cleanTypeArg(match[3]!),\n rawTypeString: typeText,\n };\n}\n\n/**\n * Extract Schedule<Out, In, R> type args from a node's type (regex fallback).\n */\nexport function extractScheduleTypeSignature(node: Node): ScheduleTypeSignature | undefined {\n const typeText = node.getType().getText();\n const match = SCHEDULE_TYPE_REGEX.exec(typeText);\n if (!match) return undefined;\n return {\n outputType: cleanTypeArg(match[1]!),\n inputType: cleanTypeArg(match[2]!),\n requirementsType: cleanTypeArg(match[3]!),\n rawTypeString: typeText,\n };\n}\n\n/**\n * Extract Cause<E> type arg from a node's type (regex fallback).\n */\nexport function extractCauseTypeSignature(node: Node): CauseTypeSignature | undefined {\n const typeText = node.getType().getText();\n const match = CAUSE_TYPE_REGEX.exec(typeText);\n if (!match) return undefined;\n return {\n errorType: cleanTypeArg(match[1]!),\n rawTypeString: typeText,\n };\n}\n\n// =============================================================================\n// Schema\n// =============================================================================\n\n/**\n * Check if a type is a Schema type\n */\nexport const isSchemaType = (type: Type): boolean => {\n const symbol = type.getSymbol();\n if (symbol) {\n const name = symbol.getName();\n return name === 'Schema' || name.includes('Schema');\n }\n \n const typeText = type.getText();\n return typeText.includes('Schema<') || typeText.startsWith('Schema.');\n};\n\n/**\n * Extract Schema validation information\n */\nexport const extractSchemaInfo = (type: Type): { encoded: string; decoded: string } | undefined => {\n if (!isSchemaType(type)) return undefined;\n \n const typeArgs = type.getTypeArguments();\n if (typeArgs.length >= 2) {\n return {\n encoded: typeToString(typeArgs[1]!),\n decoded: typeToString(typeArgs[0]!),\n };\n }\n \n return undefined;\n};\n","/**\n * Pattern maps and semantic helpers for Effect API detection and classification.\n */\n\nimport type {\n Node,\n CallExpression,\n PropertyAccessExpression,\n ObjectLiteralExpression,\n PropertyAssignment,\n Block,\n AwaitExpression,\n ConditionalExpression,\n PrefixUnaryExpression,\n ArrowFunction,\n FunctionExpression,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n StaticTransformNode,\n StaticMatchNode,\n StaticCauseNode,\n StaticExitNode,\n StaticScheduleNode,\n} from './types';\n\n// =============================================================================\n// Error / conditional / resource / collection / fiber patterns\n// =============================================================================\n\nexport const ERROR_HANDLER_PATTERNS = [\n '.catchAll',\n '.catchTag',\n '.catchAllCause',\n '.catchIf',\n '.catchSome',\n '.catchSomeCause',\n '.catchSomeDefect',\n '.catchAllDefect',\n '.catchTags',\n '.orElse',\n '.orElseFail',\n '.orElseSucceed',\n '.orDie',\n '.orDieWith',\n '.flip',\n '.mapError',\n '.mapErrorCause',\n '.mapBoth',\n '.sandbox',\n '.unsandbox',\n '.parallelErrors',\n '.filterOrDie',\n '.filterOrDieMessage',\n '.filterOrElse',\n '.filterOrFail',\n '.match',\n '.matchCause',\n '.matchEffect',\n '.matchCauseEffect',\n '.firstSuccessOf',\n '.ignore',\n '.ignoreLogged',\n '.eventually',\n];\n\nexport const CONDITIONAL_PATTERNS = [\n '.if',\n '.when',\n '.whenEffect',\n '.whenFiberRef',\n '.whenRef',\n '.unless',\n '.unlessEffect',\n '.option',\n '.either',\n '.exit',\n '.liftPredicate',\n];\n\nexport const RESOURCE_PATTERNS = [\n '.acquireRelease',\n '.acquireUseRelease',\n '.ensuring',\n '.addFinalizer',\n '.onExit',\n '.onError',\n '.parallelFinalizers',\n '.sequentialFinalizers',\n '.finalizersMask',\n '.using',\n '.withEarlyRelease',\n];\n\nexport const COLLECTION_PATTERNS = [\n '.forEach',\n '.loop',\n '.filter',\n '.filterMap',\n '.partition',\n '.reduce',\n '.reduceRight',\n '.reduceWhile',\n '.reduceEffect',\n '.dropUntil',\n '.dropWhile',\n '.takeUntil',\n '.takeWhile',\n '.every',\n '.exists',\n '.findFirst',\n '.head',\n '.mergeAll',\n '.replicate',\n '.replicateEffect',\n '.validateAll',\n '.validateFirst',\n '.validate',\n '.validateWith',\n];\n\nexport const FIBER_PATTERNS = [\n 'Effect.fork',\n '.fork',\n '.forkAll',\n '.forkIn',\n '.forkWithErrorHandler',\n 'Fiber.',\n];\n\n// =============================================================================\n// Transform / Match / Cause / Exit / Schedule ops\n// =============================================================================\n\nexport const TRANSFORM_OPS: Record<string, StaticTransformNode['transformType']> = {\n 'Effect.map': 'map',\n 'Effect.flatMap': 'flatMap',\n 'Effect.andThen': 'andThen',\n 'Effect.tap': 'tap',\n 'Effect.tapBoth': 'tapBoth',\n 'Effect.tapError': 'tapError',\n 'Effect.tapErrorTag': 'tapErrorTag',\n 'Effect.tapErrorCause': 'tapErrorCause',\n 'Effect.tapDefect': 'tapDefect',\n 'Effect.zipLeft': 'zipLeft',\n 'Effect.zipRight': 'zipRight',\n 'Effect.zipWith': 'zipWith',\n 'Effect.zip': 'zip',\n 'Effect.as': 'as',\n 'Effect.asVoid': 'asVoid',\n 'Effect.asSome': 'asSome',\n 'Effect.asSomeError': 'asSomeError',\n 'Effect.flatten': 'flatten',\n 'Effect.ap': 'ap',\n 'Effect.negate': 'negate',\n 'Effect.merge': 'merge',\n};\nexport const EFFECTFUL_TRANSFORMS = new Set(['flatMap', 'andThen', 'tapBoth', 'tapError', 'tapErrorTag', 'tapErrorCause', 'tapDefect', 'zipWith', 'zipLeft', 'zipRight', 'zip', 'ap', 'flatten']);\nexport const isTransformCall = (callee: string): boolean => callee in TRANSFORM_OPS;\n\nexport const MATCH_OP_MAP: Record<string, StaticMatchNode['matchOp']> = {\n 'Match.type': 'type',\n 'Match.tag': 'tag',\n 'Match.value': 'value',\n 'Match.when': 'when',\n 'Match.whenOr': 'whenOr',\n 'Match.whenAnd': 'whenAnd',\n 'Match.not': 'not',\n 'Match.is': 'is',\n 'Match.exhaustive': 'exhaustive',\n 'Match.orElse': 'orElse',\n 'Match.option': 'option',\n 'Match.either': 'either',\n 'Match.discriminator': 'discriminator',\n 'Match.discriminatorsExhaustive': 'discriminatorsExhaustive',\n 'Match.tags': 'tags',\n 'Match.tagsExhaustive': 'tagsExhaustive',\n 'Match.withReturnType': 'withReturnType',\n 'Match.run': 'run',\n};\nexport const EXHAUSTIVE_OPS = new Set(['exhaustive', 'discriminatorsExhaustive', 'tagsExhaustive']);\nexport const isMatchCall = (callee: string): boolean =>\n callee.startsWith('Match.') && callee in MATCH_OP_MAP;\n\nexport const CAUSE_OP_MAP: Record<string, StaticCauseNode['causeOp']> = {\n 'Cause.fail': 'fail',\n 'Cause.die': 'die',\n 'Cause.interrupt': 'interrupt',\n 'Cause.parallel': 'parallel',\n 'Cause.sequential': 'sequential',\n 'Cause.empty': 'empty',\n 'Cause.failures': 'failures',\n 'Cause.defects': 'defects',\n 'Cause.interruptors': 'interruptors',\n 'Cause.squash': 'squash',\n 'Cause.squashWith': 'squashWith',\n 'Cause.pretty': 'pretty',\n 'Cause.flatten': 'flatten',\n 'Cause.isDie': 'isDie',\n 'Cause.isFailure': 'isFailure',\n 'Cause.isInterrupted': 'isInterrupted',\n 'Cause.isEmpty': 'isEmpty',\n 'Cause.map': 'map',\n 'Cause.filter': 'filter',\n};\nexport const CAUSE_CONSTRUCTORS = new Set(['fail', 'die', 'interrupt', 'parallel', 'sequential', 'empty']);\nexport const isCauseCall = (callee: string): boolean =>\n callee.startsWith('Cause.') && callee in CAUSE_OP_MAP;\n\nexport const EXIT_OP_MAP: Record<string, StaticExitNode['exitOp']> = {\n 'Exit.succeed': 'succeed',\n 'Exit.fail': 'fail',\n 'Exit.die': 'die',\n 'Exit.interrupt': 'interrupt',\n 'Exit.void': 'void',\n 'Exit.unit': 'unit',\n 'Exit.match': 'match',\n 'Exit.isSuccess': 'isSuccess',\n 'Exit.isFailure': 'isFailure',\n 'Exit.isInterrupted': 'isInterrupted',\n 'Exit.when': 'when',\n 'Exit.whenEffect': 'whenEffect',\n 'Exit.exists': 'exists',\n 'Exit.contains': 'contains',\n 'Exit.flatten': 'flatten',\n 'Exit.map': 'map',\n 'Exit.mapBoth': 'mapBoth',\n 'Exit.mapError': 'mapError',\n 'Exit.flatMap': 'flatMap',\n 'Exit.zipWith': 'zipWith',\n 'Exit.tap': 'tap',\n 'Exit.tapBoth': 'tapBoth',\n 'Exit.tapError': 'tapError',\n};\nexport const EXIT_CONSTRUCTORS = new Set(['succeed', 'fail', 'die', 'interrupt', 'void', 'unit']);\nexport const isExitCall = (callee: string): boolean =>\n callee.startsWith('Exit.') && (callee in EXIT_OP_MAP || /^Exit\\.\\w+$/.test(callee));\n\nexport const SCHEDULE_OP_MAP: Record<string, StaticScheduleNode['scheduleOp']> = {\n 'Schedule.exponential': 'exponential',\n 'Schedule.fibonacci': 'fibonacci',\n 'Schedule.spaced': 'spaced',\n 'Schedule.fixed': 'fixed',\n 'Schedule.linear': 'linear',\n 'Schedule.cron': 'cron',\n 'Schedule.windowed': 'windowed',\n 'Schedule.duration': 'duration',\n 'Schedule.elapsed': 'elapsed',\n 'Schedule.delays': 'delays',\n 'Schedule.once': 'once',\n 'Schedule.stop': 'stop',\n 'Schedule.count': 'count',\n 'Schedule.forever': 'forever',\n 'Schedule.jittered': 'jittered',\n 'Schedule.andThen': 'andThen',\n 'Schedule.intersect': 'intersect',\n 'Schedule.union': 'union',\n 'Schedule.compose': 'compose',\n 'Schedule.zipWith': 'zipWith',\n 'Schedule.addDelay': 'addDelay',\n 'Schedule.modifyDelay': 'modifyDelay',\n 'Schedule.check': 'check',\n 'Schedule.resetAfter': 'resetAfter',\n 'Schedule.resetWhen': 'resetWhen',\n 'Schedule.ensure': 'ensure',\n 'Schedule.driver': 'driver',\n 'Schedule.mapInput': 'mapInput',\n};\nexport const isScheduleCall = (callee: string): boolean =>\n callee.startsWith('Schedule.') && (callee in SCHEDULE_OP_MAP || /^Schedule\\.\\w+$/.test(callee));\n\nexport const INTERRUPTION_PATTERNS = [\n '.interruptible',\n '.uninterruptible',\n '.interruptibleMask',\n '.uninterruptibleMask',\n '.onInterrupt',\n '.disconnect',\n '.allowInterrupt',\n 'Effect.interrupt',\n '.interruptWith',\n];\n\nexport const DO_NOTATION_PATTERNS = [\n '.Do',\n '.bind',\n '.bindAll',\n '.bindTo',\n];\n\nexport const CACHING_PATTERNS = [\n '.cached',\n '.cachedWithTTL',\n '.cachedInvalidateWithTTL',\n '.cachedFunction',\n '.once',\n 'Cache.',\n 'ScopedCache.',\n];\n\n// =============================================================================\n// API prefixes and built-in / service classification\n// =============================================================================\n\nexport const API_PREFIXES = [\n 'Effect.',\n 'Layer.',\n 'Schedule.',\n 'Stream.',\n 'Queue.',\n 'PubSub.',\n 'Deferred.',\n 'Semaphore.',\n 'Mailbox.',\n 'SubscriptionRef.',\n 'Scope.',\n 'Fiber.',\n 'Runtime.',\n 'ManagedRuntime.',\n 'NodeRuntime.',\n 'BunRuntime.',\n 'DenoRuntime.',\n 'Cause.',\n 'Exit.',\n 'Data.',\n 'Option.',\n 'Either.',\n 'Chunk.',\n 'HashMap.',\n 'HashSet.',\n 'List.',\n 'SortedMap.',\n 'SortedSet.',\n 'RedBlackTree.',\n 'Trie.',\n 'Graph.',\n 'Match.',\n 'Config.',\n 'Schema.',\n 'Cache.',\n 'ScopedCache.',\n 'RcRef.',\n 'RcMap.',\n 'Reloadable.',\n 'Cache.',\n 'ScopedCache.',\n 'RateLimiter.',\n 'PartitionedSemaphore.',\n 'FiberSet.',\n 'FiberMap.',\n 'FiberHandle.',\n 'Metric.',\n 'Logger.',\n 'Tracer.',\n 'Context.',\n 'HttpClient.',\n 'HttpRouter.',\n 'HttpApi.',\n 'FileSystem.',\n 'Command.',\n 'Socket.',\n 'SocketServer.',\n 'Worker.',\n 'Terminal.',\n 'KeyValueStore.',\n 'Multipart.',\n 'Ndjson.',\n 'MsgPack.',\n 'OpenApi.',\n 'OpenApiJsonSchema.',\n 'Brand.',\n 'Encoding.',\n 'Predicate.',\n 'DateTime.',\n 'Cron.',\n 'BigDecimal.',\n 'HashRing.',\n 'Redacted.',\n 'GlobalValue.',\n 'Channel.',\n 'Sink.',\n 'CliApp.',\n 'Args.',\n 'Options.',\n 'AiModel.',\n 'AiToolkit.',\n 'Completions.',\n 'AiInput.',\n 'AiResponse.',\n 'NodeSdk.',\n 'WebSdk.',\n 'Entity.',\n 'ClusterSchema.',\n 'MessageState.',\n 'Sharding.',\n 'RpcGroup.',\n 'RpcApi.',\n 'RpcClient.',\n 'RpcRouter.',\n 'SqlResolver.',\n 'SqlMigrator.',\n 'Printer.',\n 'Doc.',\n 'DocTree.',\n 'PageWidth.',\n 'Optimize.',\n];\n\nexport const BUILT_IN_TYPE_NAMES = new Set([\n 'Array', 'ReadonlyArray', 'String', 'Number', 'Boolean', 'Object',\n 'Function', 'Promise', 'Math', 'Date', 'RegExp', 'Error', 'Map',\n 'Set', 'WeakMap', 'WeakSet', 'Symbol', 'BigInt', 'JSON', 'Console',\n 'process', 'Buffer', 'EventEmitter', 'Window', 'Document', 'AbortController',\n]);\n\nexport const KNOWN_EFFECT_NAMESPACES = new Set([\n 'Effect', 'Layer', 'Stream', 'Queue', 'PubSub', 'Deferred', 'Semaphore',\n 'Mailbox', 'SubscriptionRef', 'Scope', 'Fiber', 'Runtime', 'ManagedRuntime', 'Cause', 'Exit',\n 'Data', 'Option', 'Either', 'Chunk', 'HashMap', 'HashSet', 'List',\n 'SortedMap', 'SortedSet', 'Match', 'Config', 'Schema', 'Schedule',\n 'Metric', 'Tracer', 'Logger', 'FiberRef', 'FiberHandle', 'FiberSet',\n 'FiberMap', 'Cache', 'ScopedCache', 'RateLimiter', 'Supervisor',\n]);\n\nexport const isServiceTagCallee = (callee: string): boolean => {\n if (callee.includes('.')) return false;\n if (KNOWN_EFFECT_NAMESPACES.has(callee)) return false;\n return /^[A-Z][A-Za-z0-9]*$/.test(callee);\n};\n\n// =============================================================================\n// Semantic description and alias-aware helpers\n// =============================================================================\n\nexport const getSemanticDescription = (callee: string): string | undefined => {\n if (callee.startsWith('Channel.')) return 'channel';\n if (callee.startsWith('Sink.')) return 'sink';\n if (callee.endsWith('.never')) return 'never';\n if (callee.endsWith('.void')) return 'void-effect';\n if (callee.endsWith('.fromNullable')) return 'null-coalescing';\n if (callee.endsWith('.fn')) return 'function-lift';\n if (callee.endsWith('.fnUntraced')) return 'function-lift';\n if (\n callee.includes('.async') ||\n callee.includes('.asyncEffect') ||\n callee.includes('.promise') ||\n callee.includes('.sync') ||\n callee.includes('.suspend') ||\n callee.includes('.succeed') ||\n callee.includes('.fail') ||\n callee.includes('.try')\n ) return 'constructor';\n if (INTERRUPTION_PATTERNS.some((p) => callee.includes(p))) return 'interruption';\n if (DO_NOTATION_PATTERNS.some((p) => callee.includes(p))) return 'do-notation';\n if (CACHING_PATTERNS.some((p) => callee.includes(p) || callee.startsWith(p))) return 'caching';\n if (ERROR_HANDLER_PATTERNS.some((p) => callee.includes(p))) return 'error-handler';\n if (CONDITIONAL_PATTERNS.some((p) => callee.includes(p))) return 'conditional';\n if (RESOURCE_PATTERNS.some((p) => callee.includes(p))) return 'resource';\n if (COLLECTION_PATTERNS.some((p) => callee.includes(p))) return 'collection';\n if (FIBER_PATTERNS.some((p) => callee.includes(p))) return 'fiber';\n if (callee.startsWith('Stream.')) return 'stream';\n if (callee.startsWith('Layer.')) return 'layer';\n if (callee.startsWith('Schema.')) return 'schema';\n if (callee.startsWith('Config.')) return 'config';\n if (callee.startsWith('Cause.')) return 'cause';\n if (callee.startsWith('Exit.')) return 'exit';\n if (callee === 'Data.tagged' || callee === 'Data.taggedEnum') return 'tagged-enum';\n if (callee.startsWith('Data.')) return 'data';\n if (callee.startsWith('Option.')) return 'option';\n if (callee.startsWith('Either.')) return 'either';\n if (callee.startsWith('Match.')) return 'match';\n if (callee.startsWith('ManagedRuntime.')) return 'runtime';\n if (callee.startsWith('Runtime.')) return 'runtime';\n if (callee.startsWith('NodeRuntime.') || callee.startsWith('BunRuntime.') || callee.startsWith('DenoRuntime.')) return 'runtime';\n if (callee.startsWith('Scope.')) return 'scope';\n if (callee.startsWith('ScopedRef.') || callee.startsWith('RcRef.') || callee.startsWith('RcMap.')) return 'resource-ref';\n if (callee.startsWith('Reloadable.') || callee.startsWith('Resource.')) return 'reloadable';\n if (callee.startsWith('Micro.')) return 'micro';\n if (callee.startsWith('Brand.')) return 'brand';\n if (callee.startsWith('Encoding.')) return 'encoding';\n if (callee.startsWith('Predicate.')) return 'predicate';\n if (callee.startsWith('DateTime.')) return 'datetime';\n if (callee.startsWith('Cron.')) return 'cron';\n if (callee.startsWith('Redacted.')) return 'redacted';\n if (callee.startsWith('GlobalValue.')) return 'global-value';\n if (callee.startsWith('Supervisor.')) return 'supervisor';\n if (\n callee.includes('.locally') ||\n callee.includes('.locallyWith') ||\n callee.includes('.locallyScoped') ||\n callee.includes('.getFiberRefs') ||\n callee.includes('.setFiberRefs') ||\n callee.includes('.inheritFiberRefs') ||\n callee.includes('FiberRef.')\n ) return 'fiberref';\n if (\n callee.includes('.withConcurrency') ||\n callee.includes('.withScheduler') ||\n callee.includes('.withSchedulingPriority') ||\n callee.includes('.daemonChildren') ||\n callee.includes('.awaitAllChildren') ||\n callee.includes('.supervised')\n ) return 'structured-concurrency';\n if (\n callee.startsWith('Context.pick') ||\n callee.startsWith('Context.omit')\n ) return 'context';\n if (\n callee === 'Effect.provide' ||\n (callee.startsWith('Effect.') && callee.includes('.provide') && !callee.includes('provideService'))\n ) return 'context';\n if (\n callee.includes('.serviceOption') ||\n callee.includes('.serviceOptional') ||\n callee.includes('.serviceFunction') ||\n callee.includes('.serviceFunctionEffect') ||\n callee.includes('.serviceFunctions') ||\n callee.includes('.serviceConstants') ||\n callee.includes('.serviceMembers') ||\n callee.includes('.updateService')\n ) return 'service';\n if (\n callee.startsWith('CliApp.') ||\n callee.startsWith('Args.') ||\n callee.startsWith('Options.')\n ) return 'cli';\n if (\n callee.startsWith('AiModel.') ||\n callee.startsWith('AiToolkit.') ||\n callee.startsWith('Completions.') ||\n callee.startsWith('AiInput.') ||\n callee.startsWith('AiResponse.')\n ) return 'ai';\n if (\n callee.startsWith('NodeSdk.') ||\n callee.startsWith('WebSdk.') ||\n callee.startsWith('OtelMetrics.')\n ) return 'opentelemetry';\n if (\n callee.startsWith('Entity.') ||\n callee.startsWith('ClusterSchema.') ||\n callee.startsWith('MessageState.') ||\n callee.startsWith('Sharding.')\n ) return 'cluster';\n if (\n callee.startsWith('RpcGroup.') ||\n callee.startsWith('RpcApi.') ||\n callee.startsWith('RpcClient.') ||\n callee.startsWith('RpcRouter.')\n ) return 'rpc';\n if (\n callee.startsWith('SqlResolver.') ||\n callee.startsWith('SqlMigrator.')\n ) return 'sql';\n if (callee.startsWith('DevTools.') || callee.startsWith('Server.')) return 'devtools';\n if (callee.startsWith('BigDecimal.')) return 'big-decimal';\n if (callee.startsWith('Graph.')) return 'graph';\n if (callee.startsWith('HashRing.')) return 'hash-ring';\n if (callee.startsWith('Chunk.')) return 'chunk';\n if (callee.startsWith('HashMap.') || callee.startsWith('HashSet.')) return 'immutable-collection';\n if (\n callee.startsWith('List.') ||\n callee.startsWith('SortedMap.') ||\n callee.startsWith('SortedSet.') ||\n callee.startsWith('RedBlackTree.') ||\n callee.startsWith('Trie.')\n ) return 'immutable-collection';\n if (\n callee.includes('.map') ||\n callee.includes('.flatMap') ||\n callee.includes('.andThen') ||\n callee.includes('.tap') ||\n callee.includes('.tapBoth') ||\n callee.includes('.tapError') ||\n callee.includes('.tapErrorTag') ||\n callee.includes('.tapErrorCause') ||\n callee.includes('.tapDefect') ||\n callee.includes('.zip') ||\n callee.includes('.zipLeft') ||\n callee.includes('.zipRight') ||\n callee.includes('.zipWith') ||\n callee.includes('.as') ||\n callee.includes('.asVoid') ||\n callee.includes('.flatten') ||\n callee.includes('.merge') ||\n callee.includes('.ap') ||\n callee.includes('.validate') ||\n callee.includes('.negate')\n ) return 'transformation';\n if (\n callee.startsWith('Printer.') ||\n callee.startsWith('Doc.') ||\n callee.startsWith('DocTree.') ||\n callee.startsWith('PageWidth.') ||\n callee.startsWith('Optimize.')\n ) return 'printer';\n if (\n callee.startsWith('Http') ||\n callee.startsWith('FileSystem.') ||\n callee.startsWith('Command.') ||\n callee.startsWith('Socket.') ||\n callee.startsWith('Worker.')\n ) return 'platform';\n if (callee.includes('channel.') && !callee.includes('Channel')) return 'channel';\n return undefined;\n};\n\nexport const getSemanticDescriptionWithAliases = (\n callee: string,\n effectAliases?: Set<string>,\n): string | undefined => {\n const direct = getSemanticDescription(callee);\n if (direct) return direct;\n\n if (effectAliases) {\n const dotIndex = callee.indexOf('.');\n if (dotIndex > 0) {\n const prefix = callee.substring(0, dotIndex);\n if (effectAliases.has(prefix)) {\n const method = callee.substring(dotIndex + 1);\n return getSemanticDescription(`Effect.${method}`);\n }\n }\n }\n return undefined;\n};\n\nexport const isLikelyDirectEffectInitializer = (\n initializer: Node,\n effectImportNames: Set<string>,\n nonProgramEffectImportNames: Set<string> = new Set(),\n): boolean => {\n const { SyntaxKind } = loadTsMorph();\n const isNonProgramName = (name: string): boolean => nonProgramEffectImportNames.has(name);\n const isRunEntrypointCalleeText = (exprText: string): boolean =>\n /\\.run(?:Promise(?:Exit)?|Sync(?:Exit)?|Fork|Callback|Main)$/.test(exprText) ||\n /^Runtime\\.run(?:Promise|Sync|Fork)$/.test(exprText);\n const isDirectEffectCalleeText = (exprText: string): boolean => {\n if (isRunEntrypointCalleeText(exprText)) {\n return false;\n }\n const isPipeCall = exprText === 'pipe' || exprText.endsWith('.pipe');\n const dotIndex = exprText.indexOf('.');\n if (dotIndex > 0 && isNonProgramName(exprText.slice(0, dotIndex))) {\n return false;\n }\n return (\n isPipeCall ||\n [...effectImportNames].some((alias) => exprText.startsWith(`${alias}.`))\n );\n };\n\n const isLikelyEffectCall = (call: CallExpression): boolean => {\n const callee = call.getExpression();\n const exprText = callee.getText();\n if (isRunEntrypointCalleeText(exprText)) {\n return false;\n }\n const isPipeCall = exprText === 'pipe';\n const isMethodPipeCall =\n callee.getKind() === SyntaxKind.PropertyAccessExpression &&\n (callee as PropertyAccessExpression).getName() === 'pipe';\n if (isPipeCall || isMethodPipeCall) {\n const argsContainEffect = call.getArguments().some((arg) =>\n isLikelyDirectEffectInitializer(arg, effectImportNames, nonProgramEffectImportNames)\n );\n if (argsContainEffect) {\n return true;\n }\n if (isMethodPipeCall) {\n const base = (callee as PropertyAccessExpression).getExpression();\n return isLikelyDirectEffectInitializer(\n base,\n effectImportNames,\n nonProgramEffectImportNames,\n );\n }\n return false;\n }\n if (\n callee.getKind() === SyntaxKind.Identifier &&\n effectImportNames.has(exprText) &&\n !isNonProgramName(exprText)\n ) {\n return true;\n }\n if (isDirectEffectCalleeText(exprText)) {\n return true;\n }\n\n // Builder / wrapper chains: inspect call receiver and arguments for effectful callbacks,\n // e.g. make(() => Effect.never).identified(\"Never\")\n if (\n callee.getKind() === SyntaxKind.PropertyAccessExpression &&\n isLikelyDirectEffectInitializer(\n (callee as PropertyAccessExpression).getExpression(),\n effectImportNames,\n nonProgramEffectImportNames,\n )\n ) {\n return true;\n }\n\n return call.getArguments().some((arg) =>\n isLikelyDirectEffectInitializer(arg, effectImportNames, nonProgramEffectImportNames)\n );\n };\n\n /** True when `node` is NOT inside a nested function/arrow/method relative to `scope`. */\n const isInSameScope = (node: Node, scope: Node): boolean => {\n let current = node.getParent();\n while (current && current !== scope) {\n const k = current.getKind();\n if (\n k === SyntaxKind.FunctionDeclaration ||\n k === SyntaxKind.FunctionExpression ||\n k === SyntaxKind.ArrowFunction ||\n k === SyntaxKind.MethodDeclaration ||\n k === SyntaxKind.GetAccessor ||\n k === SyntaxKind.SetAccessor ||\n k === SyntaxKind.ClassDeclaration ||\n k === SyntaxKind.ClassExpression ||\n k === SyntaxKind.Constructor ||\n k === SyntaxKind.ClassStaticBlockDeclaration\n ) {\n return false;\n }\n current = current.getParent();\n }\n return true;\n };\n\n const blockContainsEffectLikeUsage = (block: import('ts-morph').Block): boolean => {\n const callExprs = block.getDescendantsOfKind(SyntaxKind.CallExpression);\n if (callExprs.some((call) => isInSameScope(call, block) && isLikelyEffectCall(call))) {\n return true;\n }\n\n const awaitedExprs = block.getDescendantsOfKind(SyntaxKind.AwaitExpression);\n if (\n awaitedExprs.some((awaitExpr) =>\n isInSameScope(awaitExpr, block) &&\n isLikelyDirectEffectInitializer(awaitExpr, effectImportNames, nonProgramEffectImportNames)\n )\n ) {\n return true;\n }\n\n const propertyAccessExprs = block.getDescendantsOfKind(\n SyntaxKind.PropertyAccessExpression,\n );\n return propertyAccessExprs.some((expr) =>\n isInSameScope(expr, block) &&\n isLikelyDirectEffectInitializer(expr, effectImportNames, nonProgramEffectImportNames)\n );\n };\n\n const blockContainsRunEntrypointUsage = (block: import('ts-morph').Block): boolean =>\n block\n .getDescendantsOfKind(SyntaxKind.CallExpression)\n .some((call) => isInSameScope(call, block) && isRunEntrypointCalleeText((call).getExpression().getText()));\n\n if (initializer.getKind() === SyntaxKind.ObjectLiteralExpression) {\n const obj = initializer as ObjectLiteralExpression;\n return obj.getProperties().some((prop) => {\n if (\n prop.getKind() === SyntaxKind.PropertyAssignment ||\n prop.getKind() === SyntaxKind.ShorthandPropertyAssignment\n ) {\n const init =\n prop.getKind() === SyntaxKind.PropertyAssignment\n ? (prop as PropertyAssignment).getInitializer()\n : undefined;\n return init\n ? isLikelyDirectEffectInitializer(init, effectImportNames, nonProgramEffectImportNames)\n : false;\n }\n if (\n prop.getKind() === SyntaxKind.MethodDeclaration ||\n prop.getKind() === SyntaxKind.GetAccessor ||\n prop.getKind() === SyntaxKind.SetAccessor\n ) {\n const body = (\n prop as\n | import('ts-morph').MethodDeclaration\n | import('ts-morph').GetAccessorDeclaration\n | import('ts-morph').SetAccessorDeclaration\n ).getBody();\n return body\n ? blockContainsEffectLikeUsage(body as Block)\n : false;\n }\n return false;\n });\n }\n\n if (\n initializer.getKind() === SyntaxKind.ArrowFunction ||\n initializer.getKind() === SyntaxKind.FunctionExpression\n ) {\n const fn = initializer as ArrowFunction | FunctionExpression;\n const body = fn.getBody();\n\n if (body.getKind() === SyntaxKind.Block) {\n const bodyBlock = body as Block;\n // Check return statements in the current function scope (if/else/switch branches)\n // but NOT those inside nested functions/callbacks.\n const returnStmts = bodyBlock.getDescendantsOfKind(SyntaxKind.ReturnStatement);\n const hasEffectReturn = returnStmts.some((ret) => {\n if (!isInSameScope(ret, bodyBlock)) return false;\n const expr = ret.getExpression();\n return expr !== undefined && isLikelyDirectEffectInitializer(\n expr,\n effectImportNames,\n nonProgramEffectImportNames,\n );\n });\n if (hasEffectReturn) {\n return true;\n }\n // Only fall back to body heuristic if no run* entrypoint is present —\n // a function that merely executes an Effect (runSync/runPromise/…)\n // without returning one is not itself an Effect program.\n if (blockContainsRunEntrypointUsage(bodyBlock)) {\n return false;\n }\n return blockContainsEffectLikeUsage(bodyBlock);\n }\n\n return isLikelyDirectEffectInitializer(body, effectImportNames, nonProgramEffectImportNames);\n }\n\n if (initializer.getKind() === SyntaxKind.CallExpression) {\n return isLikelyEffectCall(initializer as CallExpression);\n }\n\n if (initializer.getKind() === SyntaxKind.AwaitExpression) {\n const awaited = (\n initializer as AwaitExpression\n ).getExpression();\n if (awaited.getKind() !== SyntaxKind.CallExpression) {\n return false;\n }\n return isLikelyEffectCall(awaited as CallExpression);\n }\n\n if (initializer.getKind() === SyntaxKind.ConditionalExpression) {\n const conditional = initializer as ConditionalExpression;\n return (\n isLikelyDirectEffectInitializer(\n conditional.getWhenTrue(),\n effectImportNames,\n nonProgramEffectImportNames,\n ) ||\n isLikelyDirectEffectInitializer(\n conditional.getWhenFalse(),\n effectImportNames,\n nonProgramEffectImportNames,\n )\n );\n }\n\n if (initializer.getKind() === SyntaxKind.PropertyAccessExpression) {\n const text = initializer.getText();\n const dotIndex = text.indexOf('.');\n if (dotIndex > 0 && isNonProgramName(text.slice(0, dotIndex))) {\n return false;\n }\n return [...effectImportNames].some((alias) => text.startsWith(`${alias}.`));\n }\n\n return false;\n};\n\nexport function isEffectPackageSpecifier(specifier: string): boolean {\n return (\n specifier === 'effect' ||\n specifier.startsWith('effect/') ||\n specifier.startsWith('@effect/')\n );\n}\n\nexport const EFFECT_NAMESPACE_NAMES = new Set([\n 'Effect', 'Layer', 'Schedule', 'Stream', 'Queue', 'PubSub', 'Deferred',\n 'Semaphore', 'Mailbox', 'SubscriptionRef', 'Scope', 'Fiber', 'Runtime', 'ManagedRuntime',\n 'Cause', 'Exit', 'Data', 'Option', 'Either', 'Chunk', 'HashMap', 'HashSet',\n 'Match', 'Config', 'Schema', 'Cache', 'ScopedCache', 'Metric', 'Logger',\n 'Tracer', 'Context', 'Brand', 'Encoding', 'Predicate', 'DateTime', 'Cron',\n 'BigDecimal', 'Graph', 'HashRing', 'Redacted', 'GlobalValue',\n 'NodeRuntime', 'BunRuntime', 'DenoRuntime', 'Channel', 'Sink',\n]);\n\nexport const KNOWN_INTERNAL_MODULES = new Set([\n 'core', 'core-effect', 'core-stream', 'fiberRuntime', 'effectable', 'channel', 'sink', 'layer', 'schedule', 'mailbox', 'pubsub',\n]);\n\n// =============================================================================\n// Numeric literal and Context type parsing\n// =============================================================================\n\nexport function parseServiceIdsFromContextType(requiredType: string): string[] {\n const skip = new Set(['never', 'unknown', 'any', '{}', 'object']);\n const normalized = requiredType.trim();\n if (!normalized || skip.has(normalized)) return [];\n const parts = normalized.split(/[\\s|&]+/).map((s) => s.trim().split('<')[0]?.trim() ?? '');\n return parts.filter((s) => s.length > 0 && !skip.has(s));\n}\n\nexport function getNumericLiteralFromNode(node: Node): number | undefined {\n const { SyntaxKind } = loadTsMorph();\n const kind = node.getKind();\n if (kind === SyntaxKind.NumericLiteral) {\n const text = node.getText();\n const n = Number(text);\n return Number.isFinite(n) ? n : undefined;\n }\n if (kind === SyntaxKind.PrefixUnaryExpression) {\n const unary = node as PrefixUnaryExpression;\n if (unary.getOperatorToken() === SyntaxKind.MinusToken) {\n const operand = unary.getOperand();\n const v = getNumericLiteralFromNode(operand);\n return v !== undefined ? -v : undefined;\n }\n }\n return undefined;\n}\n","/**\n * Alias and module resolution for Effect: file-level alias caches,\n * barrel resolution, and Effect-like call detection.\n */\n\nimport { existsSync } from 'fs';\nimport { dirname, resolve, join, sep } from 'path';\nimport type { SourceFile, CallExpression, PropertyAccessExpression } from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport {\n API_PREFIXES,\n isEffectPackageSpecifier,\n EFFECT_NAMESPACE_NAMES,\n KNOWN_INTERNAL_MODULES,\n} from './analysis-patterns';\n\n// =============================================================================\n// Caches\n// =============================================================================\n\n/** Per-SourceFile alias cache — avoids global mutable state and races. */\nconst effectAliasCache = new WeakMap<SourceFile, Set<string>>();\n\n/** Per-SourceFile symbol-resolution cache — avoids repeated TypeChecker lookups. */\nconst symbolResolutionCache = new WeakMap<SourceFile, Map<string, boolean>>();\n\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 = dirname(currentFilePath);\n const resolved = resolve(baseDir, specifier);\n const candidates: string[] = [\n resolved,\n `${resolved}.ts`,\n `${resolved}.tsx`,\n `${resolved}.js`,\n `${resolved}.jsx`,\n join(resolved, 'index.ts'),\n join(resolved, 'index.tsx'),\n join(resolved, 'index.js'),\n join(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 baseDir = dirname(currentFilePath);\n const resolved = resolve(baseDir, specifier);\n const candidates: string[] = [\n resolved,\n `${resolved}.ts`,\n `${resolved}.tsx`,\n `${resolved}.js`,\n `${resolved}.jsx`,\n join(resolved, 'index.ts'),\n join(resolved, 'index.tsx'),\n join(resolved, 'index.js'),\n join(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 resolvedPath = resolve(dirname(currentFilePath), specifier);\n const normalizedResolved = resolve(resolvedPath);\n const normalizedRoot = resolve(knownEffectInternalsRoot);\n if (\n normalizedResolved === normalizedRoot ||\n normalizedResolved.startsWith(normalizedRoot + sep)\n ) {\n return true;\n }\n\n // `analyze.source(...)` uses an in-memory synthetic file path (e.g. `temp.ts`),\n // so path resolution cannot be related to the caller-provided internals root.\n // Preserve regression coverage in source-mode while keeping path resolution primary\n // for real files.\n const isSyntheticSourcePath =\n currentFilePath === 'temp.ts' || currentFilePath.endsWith(`${sep}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 if (reExported.size === 0) continue;\n const def = decl.getDefaultImport();\n if (def) {\n const text = def.getText();\n if (reExported.has(text)) names.add(text);\n }\n const ns = decl.getNamespaceImport();\n if (ns) {\n const text = ns.getText();\n if (reExported.has(text)) names.add(text);\n }\n for (const named of decl.getNamedImports()) {\n if (reExported.has(named.getName())) {\n names.add(named.getAliasNode()?.getText() ?? named.getName());\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 const nsImport = decl.getNamespaceImport();\n if (!nsImport) continue;\n const aliasName = nsImport.getText();\n const canonical = canonicalNamespaceFromSpecifier(specifier);\n map.set(aliasName, canonical);\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 * Resolve whether a callee expression originates from an Effect package\n * by tracing its import declaration. Fallback when API_PREFIXES and alias checks don't match.\n */\nfunction resolveCalleeModuleOrigin(calleeText: string, sourceFile: SourceFile): boolean {\n let cache = symbolResolutionCache.get(sourceFile);\n if (!cache) {\n cache = new Map();\n symbolResolutionCache.set(sourceFile, cache);\n }\n\n const dotIdx = calleeText.indexOf('.');\n const nsText = dotIdx > 0 ? calleeText.slice(0, dotIdx) : calleeText;\n const cached = cache.get(nsText);\n if (cached !== undefined) return cached;\n\n let result = false;\n try {\n for (const importDecl of sourceFile.getImportDeclarations()) {\n const specifier = importDecl.getModuleSpecifierValue();\n\n const nsImport = importDecl.getNamespaceImport();\n if (nsImport?.getText() === nsText) {\n result = isEffectPackageSpecifier(specifier);\n break;\n }\n\n const defImport = importDecl.getDefaultImport();\n if (defImport?.getText() === nsText) {\n result = isEffectPackageSpecifier(specifier);\n break;\n }\n\n for (const named of importDecl.getNamedImports()) {\n const alias = named.getAliasNode()?.getText();\n const localName = alias ?? named.getName();\n if (localName === nsText) {\n if (isEffectPackageSpecifier(specifier)) {\n result = true;\n } else if (specifier.startsWith('.')) {\n const barrelFile = resolveBarrelSourceFile(\n sourceFile.getProject(), sourceFile.getFilePath(), specifier\n );\n if (barrelFile) {\n const reExported = getNamesReExportedFromEffect(barrelFile);\n result = reExported.has(named.getName());\n }\n }\n break;\n }\n }\n if (result) break;\n }\n } catch {\n result = false;\n }\n\n cache.set(nsText, result);\n return result;\n}\n\n/**\n * Resolve the module specifier for the namespace part of a property access (e.g. E in E.succeed).\n * Returns the import's module specifier string, or undefined if not found.\n */\nfunction resolveNamespaceImportModuleSpecifier(\n expr: import('ts-morph').PropertyAccessExpression,\n sourceFile: SourceFile,\n): string | undefined {\n const nsExpr = expr.getExpression();\n const nsText = nsExpr.getText();\n for (const importDecl of sourceFile.getImportDeclarations()) {\n const specifier = importDecl.getModuleSpecifierValue();\n const nsImport = importDecl.getNamespaceImport();\n if (nsImport?.getText() === nsText) return specifier;\n const defImport = importDecl.getDefaultImport();\n if (defImport?.getText() === nsText) return specifier;\n for (const named of importDecl.getNamedImports()) {\n const alias = named.getAliasNode()?.getText();\n const localName = alias ?? named.getName();\n if (localName === nsText) return specifier;\n }\n }\n return undefined;\n}\n\n// =============================================================================\n// Effect-like call detection\n// =============================================================================\n\n/**\n * Symbol/typechecker-backed check for Effect-like call. Fast path: API_PREFIXES + file alias set;\n * fallback: resolve callee namespace to module specifier and classify by origin.\n * Optional knownEffectInternalsRoot: local paths under that root are treated as Effect-like (improve.md §1).\n */\nexport function isEffectLikeCallExpression(\n call: CallExpression,\n sourceFile: SourceFile,\n effectAliases: Set<string>,\n knownEffectInternalsRoot?: string,\n): boolean {\n const expr = call.getExpression();\n const text = expr.getText();\n if (API_PREFIXES.some((p) => text.startsWith(p)) || text.startsWith('pipe(')) return true;\n for (const alias of effectAliases) {\n if (text.startsWith(`${alias}.`)) return true;\n }\n const { SyntaxKind } = loadTsMorph();\n if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) return false;\n const propAccess = expr as PropertyAccessExpression;\n const specifier = resolveNamespaceImportModuleSpecifier(propAccess, sourceFile);\n if (!specifier) return false;\n if (isEffectPackageSpecifier(specifier)) return true;\n if (specifier.startsWith('.')) {\n const barrelFile = resolveBarrelSourceFile(\n sourceFile.getProject(),\n sourceFile.getFilePath(),\n specifier,\n );\n if (barrelFile) {\n const reExported = getNamesReExportedFromEffect(barrelFile);\n const nsText = propAccess.getExpression().getText();\n for (const importDecl of sourceFile.getImportDeclarations()) {\n if (importDecl.getModuleSpecifierValue() !== specifier) continue;\n for (const named of importDecl.getNamedImports()) {\n const localName = named.getAliasNode()?.getText() ?? named.getName();\n if (localName === nsText && reExported.has(named.getName())) return true;\n }\n }\n }\n if (\n isSpecifierUnderKnownEffectInternalsRoot(\n sourceFile.getFilePath(),\n specifier,\n knownEffectInternalsRoot,\n )\n ) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if callee text is an Effect API call (prefix, alias, or symbol-resolved).\n */\nexport function isEffectCallee(\n text: string,\n effectAliases?: Set<string>,\n sourceFile?: SourceFile,\n): boolean {\n if (API_PREFIXES.some((prefix) => text.startsWith(prefix)) || text.startsWith('pipe(')) {\n return true;\n }\n if (effectAliases) {\n for (const alias of effectAliases) {\n if (text.startsWith(`${alias}.`)) return true;\n }\n }\n if (sourceFile && text.includes('.')) {\n return resolveCalleeModuleOrigin(text, sourceFile);\n }\n return false;\n}\n","/**\n * Effect program discovery: find Effect.gen, pipe, run, class, and class-member programs.\n */\n\nimport type {\n SourceFile,\n Node,\n CallExpression,\n VariableDeclaration,\n PropertyAccessExpression,\n Identifier,\n AwaitExpression,\n Block,\n ArrowFunction,\n FunctionExpression,\n PropertyDeclaration,\n MethodDeclaration,\n GetAccessorDeclaration,\n FunctionDeclaration,\n ClassDeclaration,\n ReturnStatement,\n ExpressionStatement,\n TypeNode,\n ObjectLiteralExpression,\n PropertyAssignment,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type { AnalyzerOptions, ServiceDefinition } from './types';\nimport { extractProgramName, extractEnclosingEffectFnName } from './analysis-utils';\nimport type { EffectProgram } from './analysis-utils';\n\nexport type { EffectProgram } from './analysis-utils';\nimport { isLikelyDirectEffectInitializer } from './analysis-patterns';\nimport {\n getEffectLikeNamespaceAliases,\n getNonProgramEffectImportNames,\n isSpecifierUnderKnownEffectInternalsRoot,\n isEffectLikeCallExpression,\n} from './alias-resolution';\n\n// =============================================================================\n// Workflow (effect-workflow) helpers\n// =============================================================================\n\nconst WORKFLOW_FACTORY_NAMES = new Set([\n 'createWorkflow',\n 'createSagaWorkflow',\n 'runSaga',\n]);\n\nconst isWorkflowFactoryCall = (calleeText: string): boolean =>\n Array.from(WORKFLOW_FACTORY_NAMES).some(\n (name) => calleeText === name || calleeText.endsWith(`.${name}`),\n );\n\n/** Returns true if call is X.make(name, deps?, fn, options?) with at least 3 args and 3rd is a function. */\nconst isWorkflowMakeCall = (call: CallExpression): boolean => {\n const expr = call.getExpression();\n if (expr.getKind() !== loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n return false;\n }\n const prop = expr as PropertyAccessExpression;\n const args = call.getArguments();\n if (prop.getName() !== 'make' || args.length < 3 || !args[2]) {\n return false;\n }\n const third = args[2].getKind();\n const { SyntaxKind } = loadTsMorph();\n return (\n third === SyntaxKind.ArrowFunction || third === SyntaxKind.FunctionExpression\n );\n};\n\n// =============================================================================\n// Effect package workflow\n// =============================================================================\n\n/** True if the module specifier refers to the workflow package. */\nfunction isWorkflowPackageSpecifier(specifier: string, _currentFilePath?: string): boolean {\n const n = specifier.replace(/\\\\/g, '/');\n if (n === '@effect/workflow' || n === 'effect/workflow') return true;\n if (n.endsWith('/workflow') || n.includes('/workflow/')) return true;\n if (n.endsWith('/Workflow.js') || n.endsWith('/Workflow.ts')) return true;\n if (n.endsWith('/Activity.js') || n.endsWith('/Activity.ts')) return true;\n if (n.startsWith('.') && (n.endsWith('Workflow.js') || n.endsWith('Workflow.ts') || n.endsWith('Activity.js') || n.endsWith('Activity.ts'))) return true;\n return false;\n}\n\nfunction isWorkflowNamespaceFromPackage(\n localName: string,\n specifier: string,\n _currentFilePath?: string,\n): boolean {\n if (localName !== 'Workflow') return false;\n return isWorkflowPackageSpecifier(specifier, _currentFilePath);\n}\n\nfunction isActivityNamespaceFromPackage(\n localName: string,\n specifier: string,\n _currentFilePath?: string,\n): boolean {\n if (localName !== 'Activity') return false;\n return isWorkflowPackageSpecifier(specifier, _currentFilePath);\n}\n\nfunction objectArgHasAnyProperty(\n call: CallExpression,\n propertyNames: readonly string[],\n): boolean {\n const { SyntaxKind } = loadTsMorph();\n const args = call.getArguments();\n if (args.length !== 1 || !args[0]) return false;\n const arg = args[0];\n if (arg.getKind() !== SyntaxKind.ObjectLiteralExpression) return false;\n const obj = arg as ObjectLiteralExpression;\n const props = obj.getProperties();\n const names = new Set(propertyNames);\n for (const p of props) {\n if (p.getKind() === SyntaxKind.PropertyAssignment) {\n const name = (p as PropertyAssignment).getName();\n if (names.has(name)) return true;\n }\n }\n return false;\n}\n\nfunction isWorkflowMakeOptionsCall(\n call: CallExpression,\n importSpecifierByLocalName: Map<string, string>,\n currentFilePath: string,\n): boolean {\n const { SyntaxKind } = loadTsMorph();\n const expr = call.getExpression();\n if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) return false;\n const prop = expr as PropertyAccessExpression;\n if (prop.getName() !== 'make') return false;\n const baseText = prop.getExpression().getText();\n const specifier = importSpecifierByLocalName.get(baseText);\n if (!specifier || !isWorkflowNamespaceFromPackage(baseText, specifier, currentFilePath)) return false;\n return objectArgHasAnyProperty(call, ['name', 'payload', 'idempotencyKey']);\n}\n\nfunction isActivityMakeOptionsCall(\n call: CallExpression,\n importSpecifierByLocalName: Map<string, string>,\n currentFilePath: string,\n): boolean {\n const { SyntaxKind } = loadTsMorph();\n const expr = call.getExpression();\n if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) return false;\n const prop = expr as PropertyAccessExpression;\n if (prop.getName() !== 'make') return false;\n const baseText = prop.getExpression().getText();\n const specifier = importSpecifierByLocalName.get(baseText);\n if (!specifier || !isActivityNamespaceFromPackage(baseText, specifier, currentFilePath)) return false;\n return objectArgHasAnyProperty(call, ['name', 'execute']);\n}\n\n/**\n * For X.run(singleArg) (e.g. effect-workflow Workflow.run(workflow)), resolve the single\n * argument to the workflow body (the callback passed to Workflow.make). Returns the AST\n * node for that callback or null.\n */\nexport const getWorkflowBodyNodeForRunCall = (\n runCall: CallExpression,\n sourceFile: SourceFile,\n): Node | null => {\n const expr = runCall.getExpression();\n if (expr.getKind() !== loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n return null;\n }\n const prop = expr as PropertyAccessExpression;\n if (prop.getName() !== 'run') {\n return null;\n }\n const args = runCall.getArguments();\n if (args.length < 1 || !args[0]) {\n return null;\n }\n const arg = args[0];\n const { SyntaxKind } = loadTsMorph();\n\n if (arg.getKind() === SyntaxKind.CallExpression) {\n const innerCall = arg as CallExpression;\n if (isWorkflowMakeCall(innerCall)) {\n const makeArgs = innerCall.getArguments();\n return makeArgs[2] ?? null;\n }\n return null;\n }\n\n if (arg.getKind() !== SyntaxKind.Identifier) {\n return null;\n }\n const id = arg as Identifier;\n const name = id.getText();\n const varDecls = sourceFile.getDescendantsOfKind(\n SyntaxKind.VariableDeclaration,\n );\n for (const decl of varDecls) {\n if ((decl).getName() !== name) {\n continue;\n }\n const initializer = (decl).getInitializer();\n if (\n initializer?.getKind() === SyntaxKind.CallExpression &&\n isWorkflowMakeCall(initializer as CallExpression)\n ) {\n const makeArgs = (initializer as CallExpression).getArguments();\n return makeArgs[2] ?? null;\n }\n }\n return null;\n};\n\n// =============================================================================\n// Scope and run detection\n// =============================================================================\n\nconst isInsideEffectGen = (node: Node): boolean => {\n const { SyntaxKind } = loadTsMorph();\n let current = node.getParent();\n while (current) {\n if (current.getKind() === SyntaxKind.CallExpression) {\n const expr = (current as CallExpression).getExpression();\n const text = expr.getText();\n if (text.includes('.gen') || text === 'gen') {\n return true;\n }\n }\n current = current.getParent();\n }\n return false;\n};\n\nconst isTopLevelVariableDeclaration = (decl: VariableDeclaration): boolean => {\n const { SyntaxKind } = loadTsMorph();\n const statement = decl.getFirstAncestorByKind(SyntaxKind.VariableStatement);\n return statement?.getParent()?.getKind() === SyntaxKind.SourceFile;\n};\n\nconst isYieldBoundDeclaration = (decl: VariableDeclaration): boolean => {\n const { SyntaxKind } = loadTsMorph();\n const initializer = decl.getInitializer();\n if (!initializer) return false;\n if (initializer.getKind() === SyntaxKind.YieldExpression) return true;\n if (\n initializer.getKind() === SyntaxKind.AwaitExpression &&\n (\n initializer as AwaitExpression\n ).getExpression().getKind() === SyntaxKind.YieldExpression\n ) {\n return true;\n }\n return false;\n};\n\nconst getCallExpressionFromInitializer = (\n initializer: Node,\n): CallExpression | undefined => {\n const { SyntaxKind } = loadTsMorph();\n if (initializer.getKind() === SyntaxKind.CallExpression) {\n return initializer as CallExpression;\n }\n if (initializer.getKind() === SyntaxKind.AwaitExpression) {\n const awaited = (\n initializer as AwaitExpression\n ).getExpression();\n if (awaited.getKind() === SyntaxKind.CallExpression) {\n return awaited as CallExpression;\n }\n }\n return undefined;\n};\n\ntype DiscoveryConfidence = NonNullable<EffectProgram['discoveryConfidence']>;\n\ninterface DiscoveryInfo {\n readonly discoveryConfidence: DiscoveryConfidence;\n readonly discoveryReason: string;\n}\n\nconst buildDiscoveryInfo = (\n discoveryConfidence: DiscoveryConfidence,\n discoveryReason: string,\n): DiscoveryInfo => ({ discoveryConfidence, discoveryReason });\n\nconst EFFECT_FAMILY_TYPE_HINTS = [\n 'Effect<',\n 'Layer<',\n 'Layer.Layer<',\n 'Stream<',\n 'Stream.Stream<',\n 'Channel<',\n 'Channel.Channel<',\n 'Sink<',\n 'Sink.Sink<',\n 'STM<',\n 'STM.STM<',\n 'Schedule<',\n 'Schedule.Schedule<',\n];\n\nconst hasEffectFamilyTypeHint = (text: string | undefined): boolean =>\n text !== undefined && EFFECT_FAMILY_TYPE_HINTS.some((hint) => text.includes(hint));\n\nconst DISCOVERY_CONFIDENCE_RANK: Record<DiscoveryConfidence, number> = {\n low: 0,\n medium: 1,\n high: 2,\n};\n\nconst isRunCall = (call: CallExpression): boolean => {\n const exprText = call.getExpression().getText();\n return (\n exprText.includes('.runPromise') ||\n exprText.includes('.runPromiseExit') ||\n exprText.includes('.runSync') ||\n exprText.includes('.runSyncExit') ||\n exprText.includes('.runFork') ||\n exprText.includes('.runCallback') ||\n exprText.includes('.runMain') ||\n exprText.includes('Runtime.runPromise') ||\n exprText.includes('Runtime.runSync') ||\n exprText.includes('Runtime.runFork')\n );\n};\n\n/**\n * Check if a function-like node's body contains runMain/runPromise/runSync/runFork.\n * Used for indirect runMain wrapper detection (improve.md §9).\n */\nfunction bodyContainsRunMainOrRunPromise(node: Node): boolean {\n const body = (node as unknown as { getBody?: () => Node }).getBody?.();\n if (!body) return false;\n const text = body.getText();\n return (\n text.includes('.runMain') ||\n text.includes('.runPromise') ||\n text.includes('.runSync') ||\n text.includes('.runFork') ||\n text.includes('Runtime.runPromise') ||\n text.includes('Runtime.runSync') ||\n text.includes('NodeRuntime.runMain') ||\n text.includes('BunRuntime.runMain') ||\n text.includes('DenoRuntime.runMain')\n );\n}\n\n/**\n * Resolve identifier to a function declaration/expression and check if its body contains runMain/runPromise.\n */\nfunction isIndirectRunMainWrapper(call: CallExpression, _sourceFile: SourceFile): boolean {\n const expr = call.getExpression();\n if (expr.getKind() !== loadTsMorph().SyntaxKind.Identifier) return false;\n const id = expr as Identifier;\n const sym = id.getSymbol();\n const decl = sym?.getValueDeclaration();\n if (!decl) return false;\n const kind = decl.getKind();\n const { SyntaxKind } = loadTsMorph();\n if (\n kind === SyntaxKind.FunctionDeclaration ||\n kind === SyntaxKind.ArrowFunction ||\n kind === SyntaxKind.FunctionExpression\n ) {\n return bodyContainsRunMainOrRunPromise(decl);\n }\n if (kind === SyntaxKind.VariableDeclaration) {\n const init = (decl as VariableDeclaration).getInitializer();\n if (init && (init.getKind() === SyntaxKind.ArrowFunction || init.getKind() === SyntaxKind.FunctionExpression)) {\n return bodyContainsRunMainOrRunPromise(init);\n }\n }\n return false;\n}\n\n/**\n * Detect curried runtime form: Runtime.runPromise(runtime)(effect) — improve.md §9.\n * The outer call has one argument (the effect); the callee is itself a call with one argument (the runtime).\n */\nexport function isRuntimeCurriedForm(call: CallExpression): boolean {\n const expr = call.getExpression();\n if (call.getArguments().length !== 1) return false;\n const { SyntaxKind } = loadTsMorph();\n if (expr.getKind() !== SyntaxKind.CallExpression) return false;\n const innerCall = expr as CallExpression;\n if (innerCall.getArguments().length !== 1) return false;\n const innerExprText = innerCall.getExpression().getText();\n return (\n innerExprText.includes('.runPromise') ||\n innerExprText.includes('.runSync') ||\n innerExprText.includes('.runFork') ||\n innerExprText.includes('.runCallback') ||\n innerExprText.includes('Runtime.runPromise') ||\n innerExprText.includes('Runtime.runSync') ||\n innerExprText.includes('Runtime.runFork')\n );\n}\n\n// =============================================================================\n// Program discovery\n// =============================================================================\n\nexport const findEffectPrograms = (\n sourceFile: SourceFile,\n _opts: Required<AnalyzerOptions>,\n): readonly EffectProgram[] => {\n const programs: EffectProgram[] = [];\n const { SyntaxKind } = loadTsMorph();\n const seenCallStarts = new Set<number>();\n const workflowProgramBuilders = new Set<string>();\n const effectImportNames = getEffectLikeNamespaceAliases(\n sourceFile,\n _opts.knownEffectInternalsRoot,\n );\n const nonProgramEffectImportNames = getNonProgramEffectImportNames(sourceFile);\n const importSpecifierByLocalName = new Map<string, string>();\n\n for (const importDecl of sourceFile.getImportDeclarations()) {\n const specifier = importDecl.getModuleSpecifierValue();\n const def = importDecl.getDefaultImport();\n if (def) importSpecifierByLocalName.set(def.getText(), specifier);\n const ns = importDecl.getNamespaceImport();\n if (ns) importSpecifierByLocalName.set(ns.getText(), specifier);\n for (const named of importDecl.getNamedImports()) {\n importSpecifierByLocalName.set(\n named.getAliasNode()?.getText() ?? named.getName(),\n specifier,\n );\n }\n }\n\n const inferAliasBackedDiscovery = (aliasName: string): DiscoveryInfo | undefined => {\n const specifier = importSpecifierByLocalName.get(aliasName);\n if (!specifier) return undefined;\n if (specifier.startsWith('effect') || specifier.startsWith('@effect/')) {\n return buildDiscoveryInfo('high', `imported from ${specifier}`);\n }\n if (\n isSpecifierUnderKnownEffectInternalsRoot(\n sourceFile.getFilePath(),\n specifier,\n _opts.knownEffectInternalsRoot,\n )\n ) {\n return buildDiscoveryInfo(\n 'high',\n 'namespace import resolved under knownEffectInternalsRoot',\n );\n }\n if (specifier.startsWith('.') && /(?:^|\\/)Effect(?:\\.[jt]sx?)?$/.test(specifier)) {\n return buildDiscoveryInfo('high', `relative Effect module namespace import (${specifier})`);\n }\n return undefined;\n };\n\n const inferDirectInitializerDiscovery = (initializer: Node): DiscoveryInfo => {\n const inferFromNestedEffectAliasUsage = (node: Node): DiscoveryInfo | undefined => {\n const propertyAccesses = node.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression);\n for (const expr of propertyAccesses) {\n const base = expr.getExpression().getText();\n if (effectImportNames.has(base) && !nonProgramEffectImportNames.has(base)) {\n const aliasInfo = inferAliasBackedDiscovery(base);\n if (aliasInfo?.discoveryConfidence === 'high') {\n return buildDiscoveryInfo('high', `function body uses ${base}.* from trusted Effect alias`);\n }\n return buildDiscoveryInfo('medium', `function body uses Effect-like alias ${base}.*`);\n }\n }\n\n const calls = node.getDescendantsOfKind(SyntaxKind.CallExpression);\n for (const c of calls) {\n const callee = (c).getExpression();\n if (callee.getKind() === SyntaxKind.Identifier) {\n const local = callee.getText();\n if (effectImportNames.has(local) && !nonProgramEffectImportNames.has(local)) {\n const aliasInfo = inferAliasBackedDiscovery(local);\n if (aliasInfo?.discoveryConfidence === 'high') {\n return buildDiscoveryInfo('high', `function body calls trusted Effect import ${local}(...)`);\n }\n return buildDiscoveryInfo('medium', `function body calls Effect-like import ${local}(...)`);\n }\n }\n }\n\n return undefined;\n };\n\n if (\n initializer.getKind() === SyntaxKind.ArrowFunction ||\n initializer.getKind() === SyntaxKind.FunctionExpression\n ) {\n const fn = initializer as\n | ArrowFunction\n | FunctionExpression;\n const body = fn.getBody();\n if (body.getKind() === SyntaxKind.Block) {\n const nested = inferFromNestedEffectAliasUsage(body as Block);\n if (nested) return nested;\n } else {\n const nested = inferFromNestedEffectAliasUsage(body);\n if (nested) return nested;\n }\n }\n\n const call = getCallExpressionFromInitializer(initializer);\n if (call) {\n const callee = call.getExpression();\n const calleeText = callee.getText();\n if (callee.getKind() === SyntaxKind.Identifier) {\n const local = calleeText;\n if (\n effectImportNames.has(local) &&\n !nonProgramEffectImportNames.has(local)\n ) {\n return (\n inferAliasBackedDiscovery(local) ??\n buildDiscoveryInfo('high', `named import call (${local})`)\n );\n }\n if (local === 'pipe') {\n return buildDiscoveryInfo('medium', 'exact pipe() call detection');\n }\n }\n if (callee.getKind() === SyntaxKind.PropertyAccessExpression) {\n const prop = callee as PropertyAccessExpression;\n const baseText = prop.getExpression().getText();\n if (effectImportNames.has(baseText) && !nonProgramEffectImportNames.has(baseText)) {\n return (\n inferAliasBackedDiscovery(baseText) ??\n buildDiscoveryInfo('medium', `Effect-like namespace prefix (${baseText}.*)`)\n );\n }\n if (prop.getName() === 'pipe') {\n return buildDiscoveryInfo('medium', 'exact .pipe() call detection');\n }\n }\n }\n\n if (initializer.getKind() === SyntaxKind.PropertyAccessExpression) {\n const prop = initializer as PropertyAccessExpression;\n const baseText = prop.getExpression().getText();\n if (effectImportNames.has(baseText) && !nonProgramEffectImportNames.has(baseText)) {\n return (\n inferAliasBackedDiscovery(baseText) ??\n buildDiscoveryInfo('medium', `Effect-like namespace property access (${baseText}.*)`)\n );\n }\n }\n\n if (initializer.getKind() === SyntaxKind.AwaitExpression) {\n const awaited = (initializer as AwaitExpression).getExpression();\n if (awaited.getKind() === SyntaxKind.CallExpression) {\n return inferDirectInitializerDiscovery(awaited);\n }\n }\n\n return buildDiscoveryInfo('low', 'heuristic direct initializer match');\n };\n\n const inferTypeAnnotatedDiscovery = (\n node:\n | VariableDeclaration\n | PropertyDeclaration\n | MethodDeclaration\n | GetAccessorDeclaration,\n ): DiscoveryInfo | undefined => {\n const getTypeNodeText = (\n n: unknown,\n ): string | undefined => {\n const typeNode = (\n n as { getTypeNode?: () => { getText: () => string } | undefined }\n ).getTypeNode?.();\n return typeNode?.getText();\n };\n\n const typeText = getTypeNodeText(node);\n if (hasEffectFamilyTypeHint(typeText)) {\n return buildDiscoveryInfo('high', 'explicit Effect-family type annotation');\n }\n\n const isExportedDecl = (() => {\n if (node.getKind() === SyntaxKind.VariableDeclaration) {\n const stmt = (node as VariableDeclaration).getFirstAncestorByKind(\n SyntaxKind.VariableStatement,\n );\n return stmt?.isExported() ?? false;\n }\n if (node.getKind() === SyntaxKind.PropertyDeclaration) {\n const cls = node.getFirstAncestorByKind(SyntaxKind.ClassDeclaration);\n return cls?.isExported() ?? false;\n }\n if (\n node.getKind() === SyntaxKind.MethodDeclaration ||\n node.getKind() === SyntaxKind.GetAccessor\n ) {\n const cls = node.getFirstAncestorByKind(SyntaxKind.ClassDeclaration);\n return cls?.isExported() ?? false;\n }\n return false;\n })();\n\n if (\n node.getKind() === SyntaxKind.VariableDeclaration ||\n node.getKind() === SyntaxKind.PropertyDeclaration\n ) {\n const initializer = (\n node as VariableDeclaration | PropertyDeclaration\n ).getInitializer();\n if (\n initializer &&\n (initializer.getKind() === SyntaxKind.ArrowFunction ||\n initializer.getKind() === SyntaxKind.FunctionExpression)\n ) {\n const fn = initializer as\n | import('ts-morph').ArrowFunction\n | import('ts-morph').FunctionExpression;\n const fnReturnTypeText = fn.getReturnTypeNode()?.getText();\n if (hasEffectFamilyTypeHint(fnReturnTypeText)) {\n return buildDiscoveryInfo('high', 'function return type annotated as Effect-family');\n }\n if (isExportedDecl && typeText) {\n return buildDiscoveryInfo('medium', 'explicit exported function API type signature');\n }\n }\n if (initializer?.getKind() === SyntaxKind.CallExpression) {\n const call = initializer as CallExpression;\n const typeArgText = call\n .getTypeArguments()\n .map((arg) => arg.getText())\n .join(' ');\n if (hasEffectFamilyTypeHint(typeArgText)) {\n return buildDiscoveryInfo('high', 'call type arguments reference Effect-family types');\n }\n if (isExportedDecl && typeText) {\n return buildDiscoveryInfo('medium', 'explicit exported call-based API type signature');\n }\n }\n }\n\n if (\n node.getKind() === SyntaxKind.MethodDeclaration ||\n node.getKind() === SyntaxKind.GetAccessor\n ) {\n const fnReturnTypeText = (\n node as MethodDeclaration | GetAccessorDeclaration\n ).getReturnTypeNode?.()?.getText();\n if (hasEffectFamilyTypeHint(fnReturnTypeText)) {\n return buildDiscoveryInfo('high', 'method/getter return type annotated as Effect-family');\n }\n if (isExportedDecl && typeText) {\n return buildDiscoveryInfo('medium', 'explicit exported method/getter API type signature');\n }\n }\n\n return undefined;\n };\n\n const isProgramRootExported = (program: EffectProgram): boolean => {\n const node = program.node;\n const kind = node.getKind();\n if (kind === SyntaxKind.CallExpression) {\n // Top-level entrypoint statements / assigned runs don't have a direct export modifier.\n return true;\n }\n if (kind === SyntaxKind.VariableDeclaration) {\n const stmt = (node as VariableDeclaration).getFirstAncestorByKind(\n SyntaxKind.VariableStatement,\n );\n return stmt?.isExported() ?? false;\n }\n if (kind === SyntaxKind.FunctionDeclaration || kind === SyntaxKind.ClassDeclaration) {\n return (\n node as FunctionDeclaration | ClassDeclaration\n ).isExported();\n }\n if (\n kind === SyntaxKind.PropertyDeclaration ||\n kind === SyntaxKind.MethodDeclaration ||\n kind === SyntaxKind.GetAccessor\n ) {\n const cls = node.getFirstAncestorByKind(SyntaxKind.ClassDeclaration);\n return cls?.isExported() ?? false;\n }\n return true;\n };\n\n const inferMethodReturnDiscovery = (\n returnStatements: readonly ReturnStatement[],\n ): DiscoveryInfo => {\n for (const ret of returnStatements) {\n const expr = ret.getExpression();\n if (!expr) continue;\n if (\n isLikelyDirectEffectInitializer(\n expr,\n effectImportNames,\n nonProgramEffectImportNames,\n )\n ) {\n return inferDirectInitializerDiscovery(expr);\n }\n }\n return buildDiscoveryInfo('low', 'heuristic method return match');\n };\n\n const filePath = sourceFile.getFilePath();\n const varDeclarations = sourceFile.getDescendantsOfKind(\n SyntaxKind.VariableDeclaration,\n );\n for (const decl of varDeclarations) {\n const initializer = decl.getInitializer();\n if (\n initializer?.getKind() === SyntaxKind.CallExpression &&\n isWorkflowFactoryCall(\n (initializer as CallExpression).getExpression().getText(),\n )\n ) {\n workflowProgramBuilders.add(decl.getName());\n }\n if (\n _opts.enableEffectWorkflow &&\n initializer?.getKind() === SyntaxKind.CallExpression\n ) {\n const initCall = initializer as CallExpression;\n if (\n isWorkflowMakeOptionsCall(initCall, importSpecifierByLocalName, filePath) ||\n isActivityMakeOptionsCall(initCall, importSpecifierByLocalName, filePath)\n ) {\n workflowProgramBuilders.add(decl.getName());\n }\n }\n }\n\n const genCalls = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);\n\n for (const call of genCalls) {\n const expression = call.getExpression();\n const exprText = expression.getText();\n const callStart = call.getStart();\n\n let isWorkflowInvocation = false;\n if (expression.getKind() === SyntaxKind.Identifier) {\n isWorkflowInvocation = workflowProgramBuilders.has(exprText);\n } else if (expression.getKind() === SyntaxKind.PropertyAccessExpression) {\n const propertyAccess =\n expression as PropertyAccessExpression;\n const objectText = propertyAccess.getExpression().getText();\n const methodName = propertyAccess.getName();\n isWorkflowInvocation =\n workflowProgramBuilders.has(objectText) && methodName === 'run';\n if (\n _opts.enableEffectWorkflow &&\n !isWorkflowInvocation &&\n methodName === 'run' &&\n call.getArguments().length === 1 &&\n !exprText.includes('runPromise') &&\n !exprText.includes('runSync') &&\n !exprText.includes('runFork') &&\n !exprText.includes('runCallback') &&\n !seenCallStarts.has(callStart)\n ) {\n const name =\n extractProgramName(call) ?? `workflow-${programs.length + 1}`;\n programs.push({\n name,\n node: call,\n type: 'run',\n ...buildDiscoveryInfo('low', 'workflow-like .run(...) shape heuristic'),\n });\n seenCallStarts.add(callStart);\n continue;\n }\n }\n if (isWorkflowInvocation && !seenCallStarts.has(callStart)) {\n const name = extractProgramName(call) ?? `workflow-${programs.length + 1}`;\n programs.push({\n name,\n node: call,\n type: 'run',\n ...buildDiscoveryInfo('medium', 'workflow builder invocation'),\n });\n seenCallStarts.add(callStart);\n continue;\n }\n\n if (\n _opts.enableEffectWorkflow &&\n expression.getKind() === SyntaxKind.PropertyAccessExpression\n ) {\n const propertyAccess = expression as PropertyAccessExpression;\n const objectText = propertyAccess.getExpression().getText();\n const methodName = propertyAccess.getName();\n const isExecuteEntrypoint =\n (methodName === 'execute' || methodName === 'executeEncoded') &&\n workflowProgramBuilders.has(objectText) &&\n !seenCallStarts.has(callStart);\n if (isExecuteEntrypoint) {\n const name =\n extractProgramName(call) ?? `${objectText}.${methodName}`;\n programs.push({\n name,\n node: call,\n type: 'workflow-execute',\n ...buildDiscoveryInfo('medium', 'workflow/activity .execute entrypoint'),\n });\n seenCallStarts.add(callStart);\n continue;\n }\n }\n\n if ((exprText === 'gen' || (exprText.includes('.gen') && isEffectLikeCallExpression(call, sourceFile, effectImportNames, _opts.knownEffectInternalsRoot))) && !seenCallStarts.has(callStart)) {\n const name = extractProgramName(call) ?? extractEnclosingEffectFnName(call) ?? `program-${programs.length + 1}`;\n programs.push({\n name,\n node: call,\n type: 'generator',\n ...(exprText === 'gen'\n ? buildDiscoveryInfo('medium', 'unqualified gen(...) call')\n : buildDiscoveryInfo('high', 'Effect-like .gen(...) call')),\n });\n seenCallStarts.add(callStart);\n }\n\n const pipeName = extractProgramName(call);\n if (\n exprText.includes('pipe') &&\n hasEffectInArgs(call, effectImportNames) &&\n !seenCallStarts.has(callStart) &&\n expression.getKind() !== SyntaxKind.PropertyAccessExpression &&\n pipeName !== undefined &&\n !isInsideEffectGen(call)\n ) {\n programs.push({\n name: pipeName,\n node: call,\n type: 'pipe',\n ...buildDiscoveryInfo('medium', 'exact pipe(...) call with Effect-like args'),\n });\n seenCallStarts.add(callStart);\n }\n\n if ((isRunCall(call) || isRuntimeCurriedForm(call)) && !seenCallStarts.has(callStart)) {\n const name = extractProgramName(call) ?? `run-${programs.length + 1}`;\n programs.push({\n name,\n node: call,\n type: 'run',\n ...buildDiscoveryInfo('high', 'recognized Runtime/Effect run* entrypoint'),\n });\n seenCallStarts.add(callStart);\n }\n }\n\n for (const decl of varDeclarations) {\n if (!isTopLevelVariableDeclaration(decl)) continue;\n if (isYieldBoundDeclaration(decl)) continue;\n const initializer = decl.getInitializer();\n if (initializer) {\n const name = decl.getName();\n const callInitializer = getCallExpressionFromInitializer(initializer);\n if (callInitializer && isRunCall(callInitializer)) {\n continue;\n }\n if (initializer.getKind() === SyntaxKind.ObjectLiteralExpression) {\n continue;\n }\n const looksLikeEffect = isLikelyDirectEffectInitializer(\n initializer,\n effectImportNames,\n nonProgramEffectImportNames,\n );\n if (looksLikeEffect && !programs.some((p) => p.name === name)) {\n programs.push({\n name,\n node: decl,\n type: 'direct',\n ...(inferTypeAnnotatedDiscovery(decl) ?? inferDirectInitializerDiscovery(initializer)),\n });\n }\n }\n }\n\n const topLevelStatements = sourceFile.getStatements();\n for (const stmt of topLevelStatements) {\n if (stmt.getKind() !== SyntaxKind.ExpressionStatement) continue;\n const expr = (stmt as ExpressionStatement).getExpression();\n if (expr.getKind() !== SyntaxKind.CallExpression) continue;\n\n const call = expr as CallExpression;\n const callStart = call.getStart();\n if (seenCallStarts.has(callStart)) continue;\n\n const calleeExpr = call.getExpression();\n const calleeText = calleeExpr.getText();\n\n if (isRunCall(call)) {\n const name = `run-${programs.length + 1}`;\n programs.push({\n name,\n node: call,\n type: 'run',\n ...buildDiscoveryInfo('high', 'recognized top-level run* entrypoint'),\n });\n seenCallStarts.add(callStart);\n continue;\n }\n\n if (calleeText.endsWith('.pipe') || calleeText === 'pipe') {\n const args = call.getArguments();\n const lastArg = args[args.length - 1];\n if (!lastArg) continue;\n\n const lastArgText = lastArg.getText();\n const isRunTerminated =\n lastArgText.includes('.runMain') ||\n lastArgText.includes('.runPromise') ||\n lastArgText.includes('.runSync') ||\n lastArgText.includes('.runFork');\n\n if (isRunTerminated) {\n let baseName: string | undefined;\n if (calleeExpr.getKind() === SyntaxKind.PropertyAccessExpression) {\n const propAccess = calleeExpr as PropertyAccessExpression;\n const baseExpr = propAccess.getExpression();\n baseName = baseExpr.getText().split('.').pop();\n }\n const name = baseName && !programs.some(p => p.name === baseName)\n ? baseName\n : `entrypoint-${programs.length + 1}`;\n programs.push({\n name,\n node: call,\n type: 'run',\n ...buildDiscoveryInfo('medium', 'top-level pipe(...).run* terminator pattern'),\n });\n seenCallStarts.add(callStart);\n }\n }\n\n if (calleeExpr.getKind() === SyntaxKind.Identifier && call.getArguments().length >= 1) {\n const name = (calleeExpr as Identifier).getText();\n const isIndirectWrapper = isIndirectRunMainWrapper(call, sourceFile);\n if (isIndirectWrapper && !programs.some(p => p.name === name)) {\n programs.push({\n name,\n node: call,\n type: 'run',\n ...buildDiscoveryInfo('low', 'indirect run wrapper body heuristic'),\n });\n seenCallStarts.add(callStart);\n }\n }\n }\n\n const DATA_SCHEMA_CLASS_PATTERNS = [\n 'Data.TaggedError',\n 'Data.TaggedClass',\n 'Data.Class',\n 'Data.Error',\n 'Schema.Class',\n 'Schema.TaggedClass',\n 'Schema.TaggedError',\n 'Schema.TaggedRequest',\n 'Context.Tag',\n 'Context.Reference',\n 'Effect.Service',\n ];\n const classDeclarations = sourceFile.getDescendantsOfKind(SyntaxKind.ClassDeclaration);\n for (const classDecl of classDeclarations) {\n const name = classDecl.getName();\n if (!name) continue;\n if (programs.some((p) => p.name === name)) continue;\n const heritageClauses = classDecl.getHeritageClauses();\n const matchesPattern = heritageClauses.some((clause) => {\n const clauseText = clause.getText();\n return DATA_SCHEMA_CLASS_PATTERNS.some((p) => clauseText.includes(p));\n });\n if (matchesPattern) {\n programs.push({\n name,\n node: classDecl,\n type: 'class',\n ...buildDiscoveryInfo('medium', 'known Data/Schema/Context class pattern'),\n });\n }\n }\n\n const topLevelClasses = classDeclarations.filter((c) => {\n const parent = c.getParent();\n return parent === sourceFile || parent?.getParent() === sourceFile;\n });\n for (const classDecl of topLevelClasses) {\n const className = classDecl.getName() ?? 'Anonymous';\n\n const members = classDecl.getMembers();\n const properties = members.filter(\n m => m.getKind() === SyntaxKind.PropertyDeclaration\n ) as PropertyDeclaration[];\n\n for (const prop of properties) {\n const initializer = prop.getInitializer();\n if (!initializer) continue;\n const memberName = prop.getName();\n const fullName = `${className}.${memberName}`;\n if (programs.some(p => p.name === fullName)) continue;\n\n if (\n isLikelyDirectEffectInitializer(\n initializer,\n effectImportNames,\n nonProgramEffectImportNames,\n )\n ) {\n programs.push({\n name: fullName,\n node: prop,\n type: 'classProperty',\n ...(inferTypeAnnotatedDiscovery(prop) ?? inferDirectInitializerDiscovery(initializer)),\n });\n }\n }\n\n const methods = members.filter(\n m => m.getKind() === SyntaxKind.MethodDeclaration\n ) as MethodDeclaration[];\n\n for (const method of methods) {\n const memberName = method.getName();\n const fullName = `${className}.${memberName}`;\n if (programs.some(p => p.name === fullName)) continue;\n\n const body = method.getBody();\n if (!body) continue;\n\n const returnStatements = body.getDescendantsOfKind(SyntaxKind.ReturnStatement);\n const hasEffectReturn = returnStatements.some(ret => {\n const expr = (ret).getExpression();\n return expr\n ? isLikelyDirectEffectInitializer(\n expr,\n effectImportNames,\n nonProgramEffectImportNames,\n )\n : false;\n });\n\n if (hasEffectReturn) {\n programs.push({\n name: fullName,\n node: method,\n type: 'classMethod',\n ...(inferTypeAnnotatedDiscovery(method) ?? inferMethodReturnDiscovery(returnStatements)),\n });\n }\n }\n\n const getters = members.filter(\n m => m.getKind() === SyntaxKind.GetAccessor\n ) as GetAccessorDeclaration[];\n\n for (const getter of getters) {\n const memberName = getter.getName();\n const fullName = `${className}.${memberName}`;\n if (programs.some(p => p.name === fullName)) continue;\n\n const body = getter.getBody();\n if (!body) continue;\n\n const returnStatements = body.getDescendantsOfKind(SyntaxKind.ReturnStatement);\n const hasEffectReturn = returnStatements.some(ret => {\n const expr = (ret).getExpression();\n return expr\n ? isLikelyDirectEffectInitializer(\n expr,\n effectImportNames,\n nonProgramEffectImportNames,\n )\n : false;\n });\n\n if (hasEffectReturn) {\n programs.push({\n name: fullName,\n node: getter,\n type: 'classMethod',\n ...(inferTypeAnnotatedDiscovery(getter) ?? inferMethodReturnDiscovery(returnStatements)),\n });\n }\n }\n }\n\n return programs.filter((program) => {\n const threshold = _opts.minDiscoveryConfidence ?? 'low';\n const confidence = program.discoveryConfidence ?? 'low';\n if (DISCOVERY_CONFIDENCE_RANK[confidence] < DISCOVERY_CONFIDENCE_RANK[threshold]) {\n return false;\n }\n if (_opts.onlyExportedPrograms && !isProgramRootExported(program)) {\n return false;\n }\n return true;\n });\n};\n\nconst hasEffectInArgs = (\n call: CallExpression,\n effectImportNames: Set<string>,\n): boolean => {\n const args = call.getArguments();\n const argTexts = args.map((arg) => arg.getText());\n return argTexts.some((text) =>\n [...effectImportNames].some((alias) => text.includes(`${alias}.`)),\n );\n};\n\n// =============================================================================\n// Service definitions\n// =============================================================================\n\nexport function extractServiceDefinitionsFromFile(sourceFile: SourceFile): ServiceDefinition[] {\n const { SyntaxKind } = loadTsMorph();\n const results: ServiceDefinition[] = [];\n const typeChecker = sourceFile.getProject().getTypeChecker();\n const classDeclarations = sourceFile.getDescendantsOfKind(SyntaxKind.ClassDeclaration);\n for (const classDecl of classDeclarations) {\n const name = classDecl.getName();\n if (!name) continue;\n const extExpr = classDecl.getExtends();\n if (!extExpr) continue;\n const extText = extExpr.getText();\n if (!extText.includes('Context.Tag') && !extText.includes('Effect.Service')) continue;\n let typeArgs: readonly TypeNode[] = extExpr.getTypeArguments();\n if (typeArgs.length < 2) {\n const inner = extExpr.getExpression();\n if (inner && 'getTypeArguments' in inner && typeof (inner as { getTypeArguments: () => unknown[] }).getTypeArguments === 'function') {\n typeArgs = (inner as { getTypeArguments: () => readonly TypeNode[] }).getTypeArguments();\n }\n }\n if (typeArgs.length < 2) continue;\n const interfaceTypeNode = typeArgs[1];\n if (!interfaceTypeNode) continue;\n try {\n const type = typeChecker.getTypeAtLocation(interfaceTypeNode);\n const methods: string[] = [];\n const properties: string[] = [];\n for (const sym of type.getProperties()) {\n const propName = sym.getName();\n if (propName.startsWith('_') || propName === 'constructor') continue;\n const propType = typeChecker.getTypeOfSymbolAtLocation(sym, interfaceTypeNode);\n const callSigs = propType.getCallSignatures();\n if (callSigs.length > 0) methods.push(propName);\n else properties.push(propName);\n }\n const classText = classDecl.getText();\n const hasCustomEquality = classText.includes('Equal.symbol') || classText.includes('[Equal') || classText.includes('equal(');\n const hasCustomHash = classText.includes('Hash.symbol') || classText.includes('[Hash') || classText.includes('hash(');\n results.push({\n tagId: name, methods, properties,\n ...(hasCustomEquality ? { hasCustomEquality } : {}),\n ...(hasCustomHash ? { hasCustomHash } : {}),\n });\n } catch {\n // skip\n }\n }\n\n for (const classDecl of classDeclarations) {\n const name = classDecl.getName();\n if (!name) continue;\n const extExpr = classDecl.getExtends();\n if (!extExpr) continue;\n const extText = extExpr.getText();\n if (!extText.includes('Data.Class') && !extText.includes('Data.TaggedClass')) continue;\n if (results.some(r => r.tagId === name)) continue;\n const classText = classDecl.getText();\n const hasCustomEquality = classText.includes('Equal.symbol') || classText.includes('[Equal') || classText.includes('equal(');\n const hasCustomHash = classText.includes('Hash.symbol') || classText.includes('[Hash') || classText.includes('hash(');\n if (hasCustomEquality || hasCustomHash) {\n results.push({ tagId: name, methods: [], properties: [], hasCustomEquality, hasCustomHash });\n }\n }\n\n return results;\n}\n","/**\n * Core program analysis: analyzeProgram, analyzeProgramNode,\n * analyzeGeneratorFunction, analyzeRunEntrypointExpression.\n */\n\nimport { Effect, Option } from 'effect';\nimport type {\n SourceFile,\n Node,\n CallExpression,\n FunctionDeclaration,\n VariableDeclaration,\n ClassDeclaration,\n PropertyDeclaration,\n MethodDeclaration,\n GetAccessorDeclaration,\n StringLiteral,\n NumericLiteral,\n ParenthesizedExpression,\n ObjectLiteralExpression,\n PropertyAssignment,\n ArrayLiteralExpression,\n YieldExpression,\n ExpressionStatement,\n VariableStatement,\n IfStatement,\n SwitchStatement,\n CaseClause,\n ForStatement,\n ForOfStatement,\n ForInStatement,\n WhileStatement,\n DoStatement,\n TryStatement,\n ReturnStatement,\n ThrowStatement,\n LabeledStatement,\n Block,\n ConditionalExpression,\n BinaryExpression,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type {\n StaticEffectIR,\n StaticEffectProgram,\n StaticFlowNode,\n StaticEffectNode,\n StaticGeneratorNode,\n StaticDecisionNode,\n StaticSwitchNode,\n StaticSwitchCase,\n StaticTryCatchNode,\n StaticTerminalNode,\n StaticOpaqueNode,\n StaticLoopNode,\n StaticParallelNode,\n StaticRaceNode,\n StaticRetryNode,\n AnalysisError,\n AnalyzerOptions,\n AnalysisWarning,\n AnalysisStats,\n} from './types';\nimport {\n extractEffectTypeSignature,\n extractServiceRequirements,\n} from './type-extractor';\nimport type { EffectProgram } from './analysis-utils';\nimport {\n createEmptyStats,\n generateId,\n extractLocation,\n collectDependencies,\n collectErrorTypes,\n getJSDocFromParentVariable,\n extractJSDocDescription,\n extractJSDocTags,\n extractYieldVariableName,\n computeDisplayName,\n computeSemanticRole,\n} from './analysis-utils';\nimport { isServiceTagCallee } from './analysis-patterns';\nimport { getAliasesForFile, isEffectLikeCallExpression } from './alias-resolution';\nimport {\n extractServiceDefinitionsFromFile,\n getWorkflowBodyNodeForRunCall,\n} from './program-discovery';\nimport {\n analyzePipeChain,\n analyzeEffectExpression,\n analyzeEffectCall,\n} from './effect-analysis';\n\n// =============================================================================\n// Program Analysis\n// =============================================================================\n\nexport const analyzeProgram = (\n program: EffectProgram,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n tsVersion: string,\n): Effect.Effect<StaticEffectIR, AnalysisError> =>\n Effect.gen(function* () {\n const warnings: AnalysisWarning[] = [];\n const stats = createEmptyStats();\n\n const children = yield* analyzeProgramNode(\n program.node,\n program.type,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n\n const programJSDoc = getJSDocFromParentVariable(program.node);\n\n const typeChecker = sourceFile.getProject().getTypeChecker();\n const typeSignature = extractEffectTypeSignature(program.node, typeChecker);\n const requiredServices = extractServiceRequirements(program.node, typeChecker);\n\n const root: StaticEffectProgram = {\n id: generateId(),\n type: 'program',\n programName: program.name,\n source: program.type,\n ...(program.discoveryConfidence\n ? { discoveryConfidence: program.discoveryConfidence }\n : {}),\n ...(program.discoveryReason ? { discoveryReason: program.discoveryReason } : {}),\n children,\n dependencies: collectDependencies(children),\n errorTypes: collectErrorTypes(children),\n typeSignature,\n requiredServices,\n location: extractLocation(\n program.node,\n filePath,\n opts.includeLocations ?? false,\n ),\n jsdocDescription: programJSDoc,\n jsdocTags: extractJSDocTags(program.node),\n };\n\n const serviceDefinitions = extractServiceDefinitionsFromFile(sourceFile);\n return {\n root,\n metadata: {\n analyzedAt: Date.now(),\n filePath,\n tsVersion,\n warnings,\n stats,\n ...(serviceDefinitions.length > 0 ? { serviceDefinitions } : {}),\n },\n references: new Map(),\n };\n });\n\n// =============================================================================\n// Node Analysis\n// =============================================================================\n\nexport const analyzeProgramNode = (\n node: Node,\n programType: EffectProgram['type'],\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<readonly StaticFlowNode[], AnalysisError> =>\n Effect.gen(function* () {\n switch (programType) {\n case 'generator': {\n const args = (node as CallExpression).getArguments();\n if (args.length > 0 && args[0]) {\n const genFn = args[0];\n return yield* analyzeGeneratorFunction(\n genFn,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n return [];\n }\n\n case 'pipe': {\n return yield* analyzePipeChain(\n node as CallExpression,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n case 'run': {\n const call = node as CallExpression;\n const { SyntaxKind } = loadTsMorph();\n const pipeResult = yield* analyzeRunEntrypointExpression(\n call,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n if (Option.isSome(pipeResult)) {\n return pipeResult.value;\n }\n\n const args = call.getArguments();\n const callbackInArgs = args.find(\n (arg) =>\n arg.getKind() === SyntaxKind.ArrowFunction ||\n arg.getKind() === SyntaxKind.FunctionExpression,\n );\n const workflowBody =\n opts.enableEffectWorkflow &&\n callbackInArgs === undefined &&\n args.length === 1\n ? getWorkflowBodyNodeForRunCall(call, sourceFile)\n : null;\n const effect = callbackInArgs ?? workflowBody ?? args[0];\n if (effect) {\n const analyzed = yield* analyzeEffectExpression(\n effect,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n return [analyzed];\n }\n return [];\n }\n\n case 'workflow-execute': {\n const call = node as CallExpression;\n const exprText = call.getExpression().getText();\n const syntheticNode: StaticEffectNode = {\n id: generateId(),\n type: 'effect',\n callee: exprText,\n name: exprText,\n semanticRole: 'side-effect',\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return [syntheticNode];\n }\n\n case 'direct': {\n const initializer = (node as VariableDeclaration).getInitializer();\n if (initializer) {\n const analyzed = yield* analyzeEffectExpression(\n initializer,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n return [analyzed];\n }\n return [];\n }\n\n case 'class': {\n const classDecl = node as ClassDeclaration;\n let callee = 'Data.Class';\n for (const clause of classDecl.getHeritageClauses()) {\n const clauseText = clause.getText();\n if (clauseText.includes('Data.TaggedError')) { callee = 'Data.TaggedError'; break; }\n if (clauseText.includes('Data.TaggedClass')) { callee = 'Data.TaggedClass'; break; }\n if (clauseText.includes('Data.Error')) { callee = 'Data.Error'; break; }\n if (clauseText.includes('Schema.TaggedRequest')) { callee = 'Schema.TaggedRequest'; break; }\n if (clauseText.includes('Schema.TaggedError')) { callee = 'Schema.TaggedError'; break; }\n if (clauseText.includes('Schema.TaggedClass')) { callee = 'Schema.TaggedClass'; break; }\n if (clauseText.includes('Schema.Class')) { callee = 'Schema.Class'; break; }\n if (clauseText.includes('Context.Tag')) { callee = 'Context.Tag'; break; }\n if (clauseText.includes('Context.Reference')) { callee = 'Context.Reference'; break; }\n if (clauseText.includes('Effect.Service')) { callee = 'Effect.Service'; break; }\n }\n const description =\n callee.includes('Error') ? 'error-type' :\n callee.includes('Schema') ? 'schema' :\n callee === 'Context.Tag' || callee === 'Context.Reference' || callee === 'Effect.Service' ? 'service-tag' :\n 'data';\n const classEffectNode: StaticEffectNode = {\n id: generateId(),\n type: 'effect',\n callee,\n description,\n location: extractLocation(node, filePath, opts.includeLocations ?? false),\n jsdocDescription: extractJSDocDescription(classDecl),\n jsdocTags: extractJSDocTags(classDecl),\n };\n stats.totalEffects++;\n return [classEffectNode];\n }\n\n case 'classProperty': {\n const prop = node as PropertyDeclaration;\n const initializer = prop.getInitializer();\n if (initializer) {\n const result = yield* analyzeEffectExpression(\n initializer, sourceFile, filePath, opts, warnings, stats,\n );\n return [result];\n }\n return [];\n }\n\n case 'classMethod': {\n const method = node as MethodDeclaration | GetAccessorDeclaration;\n const body = method.getBody();\n if (!body) return [];\n\n const { SyntaxKind: SK } = loadTsMorph();\n const returnStatements = body.getDescendantsOfKind(SK.ReturnStatement);\n const children: StaticFlowNode[] = [];\n for (const ret of returnStatements) {\n const expr = (ret).getExpression();\n if (expr) {\n const result = yield* analyzeEffectExpression(\n expr, sourceFile, filePath, opts, warnings, stats,\n );\n children.push(result);\n }\n }\n return children;\n }\n\n default:\n return [];\n }\n });\n\n// =============================================================================\n// Statement-Level Walker Helpers\n// =============================================================================\n\n/**\n * Check if a node is a function boundary that should NOT be descended into\n * when searching for generator yields.\n */\nfunction isFunctionBoundary(node: Node): boolean {\n const { SyntaxKind } = loadTsMorph();\n const kind = node.getKind();\n return (\n kind === SyntaxKind.FunctionDeclaration ||\n kind === SyntaxKind.FunctionExpression ||\n kind === SyntaxKind.ArrowFunction ||\n kind === SyntaxKind.MethodDeclaration ||\n kind === SyntaxKind.ClassDeclaration ||\n kind === SyntaxKind.ClassExpression ||\n kind === SyntaxKind.Constructor\n );\n}\n\n/**\n * Boundary-aware check: does `node` contain (or is itself) a YieldExpression\n * without crossing into nested function/class bodies?\n */\nfunction containsGeneratorYield(node: Node): boolean {\n const { SyntaxKind } = loadTsMorph();\n // Check the node itself first\n if (node.getKind() === SyntaxKind.YieldExpression) return true;\n let found = false;\n node.forEachChild((child) => {\n if (found) return;\n if (isFunctionBoundary(child)) return; // SKIP nested functions\n if (child.getKind() === SyntaxKind.YieldExpression) {\n found = true;\n return;\n }\n if (containsGeneratorYield(child)) {\n found = true;\n return;\n }\n });\n return found;\n}\n\n/**\n * Extract a literal value from an expression node if it's a simple literal.\n * Returns the string representation or undefined if not a literal.\n */\nfunction extractLiteralValue(expr: Node): string | undefined {\n const { SyntaxKind } = loadTsMorph();\n const kind = expr.getKind();\n switch (kind) {\n case SyntaxKind.StringLiteral:\n return (expr as StringLiteral).getLiteralValue();\n case SyntaxKind.NumericLiteral:\n return (expr as NumericLiteral).getLiteralValue().toString();\n case SyntaxKind.TrueKeyword:\n return 'true';\n case SyntaxKind.FalseKeyword:\n return 'false';\n case SyntaxKind.NullKeyword:\n return 'null';\n case SyntaxKind.NoSubstitutionTemplateLiteral:\n return expr.getText().replace(/^`|`$/g, '');\n default:\n return undefined;\n }\n}\n\n/**\n * Resolve const values in a condition string by substituting known const identifiers.\n */\nfunction resolveConditionConsts(condition: string, constValues: Map<string, string>): string {\n if (constValues.size === 0) return condition;\n let resolved = condition;\n for (const [name, value] of constValues) {\n // Replace standalone identifier references (word boundary) with the resolved value\n const pattern = new RegExp(`\\\\b${name}\\\\b`, 'g');\n const replacement = /^\\d/.test(value) || value === 'true' || value === 'false' || value === 'null'\n ? value\n : `'${value}'`;\n resolved = resolved.replace(pattern, replacement);\n }\n return resolved;\n}\n\n/**\n * Simplify boolean expressions: true && X → X, false || X → X, etc.\n */\nfunction simplifyBooleanExpression(expr: string): string {\n let result = expr;\n // true && X → X\n result = result.replace(/\\btrue\\b\\s*&&\\s*/g, '');\n result = result.replace(/\\s*&&\\s*\\btrue\\b/g, '');\n // false || X → X\n result = result.replace(/\\bfalse\\b\\s*\\|\\|\\s*/g, '');\n result = result.replace(/\\s*\\|\\|\\s*\\bfalse\\b/g, '');\n // false && X → false\n result = result.replace(/\\bfalse\\b\\s*&&\\s*[^|&]+/g, 'false');\n // true || X → true\n result = result.replace(/\\btrue\\b\\s*\\|\\|\\s*[^|&]+/g, 'true');\n return result.trim();\n}\n\n/**\n * Unwrap TypeScript expression wrappers: parenthesized, as, non-null, satisfies, type assertion.\n */\nfunction unwrapExpression(expr: Node): Node {\n const { SyntaxKind } = loadTsMorph();\n const kind = expr.getKind();\n switch (kind) {\n case SyntaxKind.ParenthesizedExpression:\n case SyntaxKind.AsExpression:\n case SyntaxKind.TypeAssertionExpression:\n case SyntaxKind.NonNullExpression:\n case SyntaxKind.SatisfiesExpression: {\n const inner = (expr as ParenthesizedExpression).getExpression();\n return unwrapExpression(inner);\n }\n default:\n return expr;\n }\n}\n\n/**\n * Check if a statement has a terminator (break/return/throw/continue) at the end.\n */\nfunction hasTerminatorStatement(stmts: readonly Node[]): boolean {\n const { SyntaxKind } = loadTsMorph();\n if (stmts.length === 0) return false;\n const last = stmts[stmts.length - 1];\n if (!last) return false;\n const kind = last.getKind();\n return (\n kind === SyntaxKind.ReturnStatement ||\n kind === SyntaxKind.ThrowStatement ||\n kind === SyntaxKind.BreakStatement ||\n kind === SyntaxKind.ContinueStatement\n );\n}\n\n/**\n * Collect all yield* expressions from a node in depth-first left-to-right order,\n * respecting function boundaries.\n */\nfunction collectYieldExpressionsDF(node: Node): Node[] {\n const { SyntaxKind } = loadTsMorph();\n const results: Node[] = [];\n node.forEachChild((child) => {\n if (isFunctionBoundary(child)) return;\n if (child.getKind() === SyntaxKind.YieldExpression) {\n results.push(child);\n } else {\n results.push(...collectYieldExpressionsDF(child));\n }\n });\n return results;\n}\n\n// =============================================================================\n// effect-flow Step.* Detection Helpers\n// =============================================================================\n\n/** Known Step.* function names from the effect-flow library. */\nconst STEP_FUNCTIONS = new Set([\n 'Step.run', 'Step.decide', 'Step.branch', 'Step.all',\n 'Step.forEach', 'Step.retry', 'Step.race', 'Step.sleep',\n]);\n\n/**\n * Check if a node is a CallExpression whose callee matches `Step.*` patterns.\n */\nfunction isStepCall(node: Node): boolean {\n const { SyntaxKind } = loadTsMorph();\n if (node.getKind() !== SyntaxKind.CallExpression) return false;\n const callee = (node as CallExpression).getExpression().getText();\n return STEP_FUNCTIONS.has(callee);\n}\n\n/**\n * Extract the string literal text from a node, or undefined if not a string literal.\n */\nfunction extractStringLiteral(node: Node | undefined): string | undefined {\n if (!node) return undefined;\n const { SyntaxKind } = loadTsMorph();\n if (node.getKind() === SyntaxKind.StringLiteral) {\n return (node as StringLiteral).getLiteralText();\n }\n return undefined;\n}\n\n/**\n * Parse an ObjectLiteralExpression into StaticSwitchCase[] for Step.branch cases.\n */\nfunction parseBranchCases(casesObj: Node | undefined): StaticSwitchCase[] {\n if (!casesObj) return [];\n const { SyntaxKind } = loadTsMorph();\n if (casesObj.getKind() !== SyntaxKind.ObjectLiteralExpression) return [];\n const cases: StaticSwitchCase[] = [];\n const objLit = casesObj as ObjectLiteralExpression;\n for (const prop of objLit.getProperties()) {\n if (prop.getKind() === SyntaxKind.PropertyAssignment) {\n const name = (prop as PropertyAssignment).getName();\n cases.push({\n labels: [name],\n isDefault: name === 'default',\n body: [], // The effect in the property value would need deep analysis\n });\n }\n }\n return cases;\n}\n\n/**\n * Analyze a Step.* call expression and produce enriched IR nodes.\n * Only called when `ctx.opts.enableEffectFlow` is true.\n */\nfunction analyzeStepCall(\n callExpr: CallExpression,\n ctx: WalkerContext,\n): Effect.Effect<StaticFlowNode, AnalysisError> {\n return Effect.gen(function* () {\n const { SyntaxKind } = loadTsMorph();\n const callee = callExpr.getExpression().getText();\n const args = callExpr.getArguments();\n\n switch (callee) {\n case 'Step.run': {\n // Step.run(id, effect) -> analyze the inner effect, enrich with step ID\n const stepId = extractStringLiteral(args[0]);\n const innerEffect = args[1];\n if (!innerEffect) {\n const node: StaticEffectNode = {\n id: generateId(),\n type: 'effect',\n callee: 'Step.run',\n name: stepId,\n displayName: stepId,\n };\n ctx.stats.totalEffects++;\n return node;\n }\n const analyzed = yield* analyzeEffectExpression(\n innerEffect,\n ctx.sourceFile,\n ctx.filePath,\n ctx.opts,\n ctx.warnings,\n ctx.stats,\n ctx.serviceScope,\n );\n return {\n ...analyzed,\n displayName: stepId ?? analyzed.displayName,\n name: stepId ?? analyzed.name,\n };\n }\n\n case 'Step.decide': {\n // Step.decide(id, label, conditionEffect) -> StaticDecisionNode\n const stepId = extractStringLiteral(args[0]);\n const label = extractStringLiteral(args[1]);\n ctx.stats.decisionCount++;\n const decisionNode: StaticDecisionNode = {\n id: generateId(),\n type: 'decision',\n decisionId: stepId ?? generateId(),\n label: label ?? stepId ?? 'decision',\n condition: args[2]?.getText() ?? 'unknown',\n source: 'effect-flow',\n onTrue: [], // The if/else around it captures branches\n onFalse: undefined,\n };\n return decisionNode;\n }\n\n case 'Step.branch': {\n // Step.branch(id, expression, cases) -> StaticSwitchNode\n const stepId = extractStringLiteral(args[0]);\n const expression = args[1]?.getText() ?? 'unknown';\n const casesObj = args[2];\n const cases = parseBranchCases(casesObj);\n ctx.stats.switchCount++;\n const switchNode: StaticSwitchNode = {\n id: generateId(),\n type: 'switch',\n switchId: stepId,\n expression,\n cases,\n source: 'effect-flow',\n hasDefault: cases.some((c) => c.isDefault),\n hasFallthrough: false,\n };\n return switchNode;\n }\n\n case 'Step.all': {\n // Step.all(id, effects) -> StaticParallelNode with enriched name\n const stepId = extractStringLiteral(args[0]);\n const effectsArg = args[1];\n const children: StaticFlowNode[] = [];\n if (effectsArg?.getKind() === SyntaxKind.ArrayLiteralExpression) {\n const arrayLit = effectsArg as ArrayLiteralExpression;\n for (const element of arrayLit.getElements()) {\n const analyzed = yield* analyzeEffectExpression(\n element,\n ctx.sourceFile,\n ctx.filePath,\n ctx.opts,\n ctx.warnings,\n ctx.stats,\n ctx.serviceScope,\n );\n children.push(analyzed);\n }\n }\n ctx.stats.parallelCount++;\n const parallelNode: StaticParallelNode = {\n id: generateId(),\n type: 'parallel',\n name: stepId,\n displayName: stepId,\n children,\n mode: 'parallel',\n callee: 'Step.all',\n };\n return parallelNode;\n }\n\n case 'Step.forEach': {\n // Step.forEach(id, items, fn) -> StaticLoopNode with enriched name\n const stepId = extractStringLiteral(args[0]);\n const iterSource = args[1]?.getText();\n const fn = args[2];\n let body: StaticFlowNode = { id: generateId(), type: 'effect', callee: 'unknown' } as StaticEffectNode;\n if (fn) {\n const analyzed = yield* analyzeEffectExpression(\n fn,\n ctx.sourceFile,\n ctx.filePath,\n ctx.opts,\n ctx.warnings,\n ctx.stats,\n ctx.serviceScope,\n );\n body = analyzed;\n }\n ctx.stats.loopCount++;\n const loopNode: StaticLoopNode = {\n id: generateId(),\n type: 'loop',\n name: stepId,\n displayName: stepId,\n loopType: 'forEach',\n iterSource,\n body,\n };\n return loopNode;\n }\n\n case 'Step.retry': {\n // Step.retry(id, effect, options) -> StaticRetryNode\n const stepId = extractStringLiteral(args[0]);\n const innerEffect = args[1];\n if (!innerEffect) {\n const node: StaticEffectNode = {\n id: generateId(),\n type: 'effect',\n callee: 'Step.retry',\n name: stepId,\n displayName: stepId,\n };\n ctx.stats.totalEffects++;\n return node;\n }\n const analyzed = yield* analyzeEffectExpression(\n innerEffect,\n ctx.sourceFile,\n ctx.filePath,\n ctx.opts,\n ctx.warnings,\n ctx.stats,\n ctx.serviceScope,\n );\n ctx.stats.retryCount++;\n const retryNode: StaticRetryNode = {\n id: generateId(),\n type: 'retry',\n name: stepId,\n displayName: stepId,\n source: analyzed,\n hasFallback: false,\n };\n return retryNode;\n }\n\n case 'Step.race': {\n // Step.race(id, effects) -> StaticRaceNode\n const stepId = extractStringLiteral(args[0]);\n const effectsArg = args[1];\n const children: StaticFlowNode[] = [];\n if (effectsArg?.getKind() === SyntaxKind.ArrayLiteralExpression) {\n const arrayLit = effectsArg as ArrayLiteralExpression;\n for (const element of arrayLit.getElements()) {\n const analyzed = yield* analyzeEffectExpression(\n element,\n ctx.sourceFile,\n ctx.filePath,\n ctx.opts,\n ctx.warnings,\n ctx.stats,\n ctx.serviceScope,\n );\n children.push(analyzed);\n }\n }\n ctx.stats.raceCount++;\n const raceNode: StaticRaceNode = {\n id: generateId(),\n type: 'race',\n name: stepId,\n displayName: stepId,\n children,\n callee: 'Step.race',\n };\n return raceNode;\n }\n\n case 'Step.sleep': {\n // Step.sleep(id, duration) -> StaticEffectNode with scheduling role\n const stepId = extractStringLiteral(args[0]);\n const effectNode: StaticEffectNode = {\n id: generateId(),\n type: 'effect',\n callee: 'Step.sleep',\n name: stepId,\n displayName: stepId,\n semanticRole: 'scheduling',\n };\n ctx.stats.totalEffects++;\n return effectNode;\n }\n\n default: {\n // Unknown Step.* call — fallback to generic effect analysis\n const node: StaticEffectNode = {\n id: generateId(),\n type: 'effect',\n callee,\n name: callee,\n displayName: callee,\n };\n ctx.stats.totalEffects++;\n return node;\n }\n }\n });\n}\n\n/** Walker context threaded through statement analysis. */\ninterface WalkerContext {\n readonly sourceFile: SourceFile;\n readonly filePath: string;\n readonly opts: Required<AnalyzerOptions>;\n readonly warnings: AnalysisWarning[];\n readonly stats: AnalysisStats;\n readonly serviceScope: Map<string, string>;\n /** 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 yieldExpr = yieldNode as YieldExpression;\n const isDelegated = yieldExpr.getText().startsWith('yield*');\n const expr = yieldExpr.getExpression();\n\n // Plain yield (not yield*)\n if (!isDelegated) {\n const opaqueNode: StaticOpaqueNode = {\n id: generateId(),\n type: 'opaque',\n reason: 'plain-yield',\n sourceText: yieldNode.getText().slice(0, 80),\n };\n ctx.stats.opaqueCount++;\n ctx.warnings.push({\n code: 'PLAIN_YIELD',\n message: `Plain yield (not yield*) detected; this is unusual in Effect generators: ${yieldNode.getText().slice(0, 60)}`,\n location: extractLocation(yieldNode, ctx.filePath, ctx.opts.includeLocations ?? false),\n });\n return { variableName: extractYieldVariableName(yieldNode), effect: opaqueNode };\n }\n\n if (!expr) {\n const opaqueNode: StaticOpaqueNode = {\n id: generateId(),\n type: 'opaque',\n reason: 'yield-no-expression',\n sourceText: yieldNode.getText().slice(0, 80),\n };\n ctx.stats.opaqueCount++;\n return { variableName: undefined, effect: opaqueNode };\n }\n\n // effect-flow: intercept Step.* calls when enableEffectFlow is active\n const unwrappedExpr = unwrapExpression(expr);\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 expr,\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 displayName: computeDisplayName(analyzed, variableName),\n semanticRole: analyzed.semanticRole ?? computeSemanticRole(analyzed),\n };\n return { variableName, effect: enrichedEffect };\n });\n}\n\n/**\n * Walk a block (or block-like body) statement-by-statement and produce structured IR.\n */\nfunction analyzeGeneratorBody(\n block: import('ts-morph').Block,\n ctx: WalkerContext,\n): Effect.Effect<StaticGeneratorNode['yields'], AnalysisError> {\n return Effect.gen(function* () {\n const stmts = block.getStatements();\n const result: StaticGeneratorNode['yields'][number][] = [];\n for (const stmt of stmts) {\n const nodes = yield* analyzeStatement(stmt, ctx);\n result.push(...nodes);\n }\n return result;\n });\n}\n\n/**\n * Main statement dispatcher: analyze a single statement and return yield entries.\n */\nfunction analyzeStatement(\n stmt: Node,\n ctx: WalkerContext,\n): Effect.Effect<StaticGeneratorNode['yields'], AnalysisError> {\n return Effect.gen(function* () {\n const { SyntaxKind } = loadTsMorph();\n const kind = stmt.getKind();\n\n switch (kind) {\n // -------------------------------------------------------------------\n // ExpressionStatement\n // -------------------------------------------------------------------\n case SyntaxKind.ExpressionStatement: {\n const exprStmt = stmt as ExpressionStatement;\n const expr = exprStmt.getExpression();\n return yield* analyzeExpressionForYields(expr, ctx);\n }\n\n // -------------------------------------------------------------------\n // VariableStatement\n // -------------------------------------------------------------------\n case SyntaxKind.VariableStatement: {\n const varStmt = stmt as VariableStatement;\n const result: StaticGeneratorNode['yields'][number][] = [];\n const { VariableDeclarationKind } = loadTsMorph();\n const isConst = varStmt.getDeclarationKind() === VariableDeclarationKind.Const;\n for (const decl of varStmt.getDeclarations()) {\n const init = decl.getInitializer();\n\n // Track const declarations with literal initializers for condition resolution\n if (isConst && init) {\n const literalValue = extractLiteralValue(init);\n if (literalValue !== undefined) {\n ctx.constValues.set(decl.getName(), literalValue);\n }\n }\n\n // Preserve Context.pick/Context.omit steps even when not yield*'d.\n // These are pure but context-shaping and are part of intended IR coverage.\n if (init && !containsGeneratorYield(init) && init.getKind() === SyntaxKind.CallExpression) {\n const callExpr = init as CallExpression;\n const calleeText = callExpr.getExpression().getText();\n if (calleeText === 'Context.pick' || calleeText === 'Context.omit') {\n const analyzed = yield* analyzeEffectExpression(\n callExpr,\n ctx.sourceFile,\n ctx.filePath,\n ctx.opts,\n ctx.warnings,\n ctx.stats,\n ctx.serviceScope,\n );\n if (analyzed.type === 'effect' && analyzed.description === 'context') {\n result.push({ variableName: decl.getName(), effect: analyzed });\n }\n continue;\n }\n }\n\n if (init && containsGeneratorYield(init)) {\n const yieldEntries = yield* analyzeExpressionForYields(init, ctx);\n // Try to get variable name from the declaration for the last yield\n if (yieldEntries.length > 0) {\n const declName = decl.getName();\n const lastEntry = yieldEntries[yieldEntries.length - 1];\n if (lastEntry) {\n yieldEntries[yieldEntries.length - 1] = {\n ...lastEntry,\n variableName: lastEntry.variableName ?? declName,\n };\n }\n }\n result.push(...yieldEntries);\n }\n }\n return result;\n }\n\n // -------------------------------------------------------------------\n // IfStatement\n // -------------------------------------------------------------------\n case SyntaxKind.IfStatement: {\n if (!containsGeneratorYield(stmt)) return [];\n const ifStmt = stmt as IfStatement;\n const condition = ifStmt.getExpression().getText();\n\n // Check if condition itself has yields\n const condYields = yield* analyzeExpressionForYields(\n ifStmt.getExpression(),\n ctx,\n );\n\n const thenStmt = ifStmt.getThenStatement();\n const elseStmt = ifStmt.getElseStatement();\n\n const onTrue = yield* analyzeStatementBlock(thenStmt, ctx);\n const onFalse = elseStmt\n ? yield* analyzeStatementBlock(elseStmt, ctx)\n : undefined;\n\n const resolvedCondition = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n const decisionLabel = resolvedCondition.length > 40 ? resolvedCondition.slice(0, 40) + '...' : resolvedCondition;\n const decisionNode: StaticDecisionNode = {\n id: generateId(),\n type: 'decision',\n decisionId: generateId(),\n label: decisionLabel,\n condition,\n source: 'raw-if',\n onTrue: onTrue.map((y) => y.effect),\n onFalse: onFalse && onFalse.length > 0 ? onFalse.map((y) => y.effect) : undefined,\n };\n ctx.stats.decisionCount++;\n\n return [\n ...condYields,\n { effect: decisionNode },\n ];\n }\n\n // -------------------------------------------------------------------\n // SwitchStatement\n // -------------------------------------------------------------------\n case SyntaxKind.SwitchStatement: {\n if (!containsGeneratorYield(stmt)) return [];\n const switchStmt = stmt as SwitchStatement;\n const expression = switchStmt.getExpression().getText();\n\n const clauses = switchStmt.getClauses();\n const cases: StaticSwitchCase[] = [];\n let hasFallthrough = false;\n let hasDefault = false;\n\n // Build fallthrough groups\n let currentLabels: string[] = [];\n let currentBodyYields: StaticGeneratorNode['yields'] = [];\n let currentIsDefault = false;\n\n for (const clause of clauses) {\n const isDefault = clause.getKind() === SyntaxKind.DefaultClause;\n if (isDefault) {\n hasDefault = true;\n currentIsDefault = true;\n currentLabels.push('default');\n } else {\n const caseClause = clause as CaseClause;\n currentLabels.push(caseClause.getExpression().getText());\n }\n\n const clauseStmts = clause.getStatements();\n if (clauseStmts.length === 0) {\n // Empty clause body = fallthrough\n hasFallthrough = true;\n continue;\n }\n\n // Analyze clause body\n for (const clauseStmt of clauseStmts) {\n const yieldEntries = yield* analyzeStatement(clauseStmt, ctx);\n currentBodyYields.push(...yieldEntries);\n }\n\n const hasTerminator = hasTerminatorStatement(clauseStmts);\n if (!hasTerminator) {\n hasFallthrough = true;\n }\n\n cases.push({\n labels: currentLabels,\n isDefault: currentIsDefault,\n body: currentBodyYields.map((y) => y.effect),\n });\n currentLabels = [];\n currentBodyYields = [];\n currentIsDefault = false;\n }\n\n // Flush remaining group\n if (currentLabels.length > 0) {\n cases.push({\n labels: currentLabels,\n isDefault: currentIsDefault,\n body: currentBodyYields.map((y) => y.effect),\n });\n }\n\n const resolvedExpression = resolveConditionConsts(expression, ctx.constValues);\n const switchNode: StaticSwitchNode = {\n id: generateId(),\n type: 'switch',\n switchId: generateId(),\n expression: resolvedExpression,\n cases,\n source: 'raw-js',\n hasDefault,\n hasFallthrough,\n };\n ctx.stats.switchCount++;\n\n return [{ effect: switchNode }];\n }\n\n // -------------------------------------------------------------------\n // ForStatement\n // -------------------------------------------------------------------\n case SyntaxKind.ForStatement: {\n if (!containsGeneratorYield(stmt)) return [];\n const forStmt = stmt as ForStatement;\n\n // Check for yields in header (initializer / incrementor)\n const headerYields: StaticFlowNode[] = [];\n const initializer = forStmt.getInitializer();\n if (initializer && containsGeneratorYield(initializer)) {\n const entries = yield* analyzeExpressionForYields(initializer, ctx);\n headerYields.push(...entries.map((e) => e.effect));\n }\n const incrementor = forStmt.getIncrementor();\n if (incrementor && containsGeneratorYield(incrementor)) {\n const entries = yield* analyzeExpressionForYields(incrementor, ctx);\n headerYields.push(...entries.map((e) => e.effect));\n }\n\n const bodyStmt = forStmt.getStatement();\n const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n const condition = forStmt.getCondition();\n const iterSource = condition ? condition.getText() : undefined;\n\n const loopBody: StaticFlowNode =\n bodyYields.length === 1 && bodyYields[0]\n ? bodyYields[0].effect\n : {\n id: generateId(),\n type: 'generator' as const,\n yields: bodyYields,\n };\n\n const loopNode: StaticLoopNode = {\n id: generateId(),\n type: 'loop',\n loopType: 'for',\n iterSource,\n body: loopBody,\n ...(hasEarlyExit ? { hasEarlyExit } : {}),\n ...(headerYields.length > 0 ? { headerYields } : {}),\n };\n ctx.stats.loopCount++;\n\n return [{ effect: loopNode }];\n }\n\n // -------------------------------------------------------------------\n // ForOfStatement\n // -------------------------------------------------------------------\n case SyntaxKind.ForOfStatement: {\n if (!containsGeneratorYield(stmt)) return [];\n const forOfStmt = stmt as ForOfStatement;\n\n const iterExpr = forOfStmt.getExpression();\n const iterSource = iterExpr.getText();\n\n // Check for yield* in the iterable expression: `for (const x of yield* items)`\n const headerYields: StaticFlowNode[] = [];\n if (containsGeneratorYield(iterExpr)) {\n const entries = yield* analyzeExpressionForYields(iterExpr, ctx);\n headerYields.push(...entries.map((e) => e.effect));\n }\n\n const iterVariable = forOfStmt.getInitializer().getText();\n\n const bodyStmt = forOfStmt.getStatement();\n const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n const loopBody: StaticFlowNode =\n bodyYields.length === 1 && bodyYields[0]\n ? bodyYields[0].effect\n : {\n id: generateId(),\n type: 'generator' as const,\n yields: bodyYields,\n };\n\n const loopNode: StaticLoopNode = {\n id: generateId(),\n type: 'loop',\n loopType: 'forOf',\n iterSource,\n body: loopBody,\n ...(hasEarlyExit ? { hasEarlyExit } : {}),\n ...(headerYields.length > 0 ? { headerYields } : {}),\n iterVariable,\n };\n ctx.stats.loopCount++;\n\n return [{ effect: loopNode }];\n }\n\n // -------------------------------------------------------------------\n // ForInStatement\n // -------------------------------------------------------------------\n case SyntaxKind.ForInStatement: {\n if (!containsGeneratorYield(stmt)) return [];\n const forInStmt = stmt as ForInStatement;\n\n const iterSource = forInStmt.getExpression().getText();\n const iterVariable = forInStmt.getInitializer().getText();\n\n const bodyStmt = forInStmt.getStatement();\n const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n const loopBody: StaticFlowNode =\n bodyYields.length === 1 && bodyYields[0]\n ? bodyYields[0].effect\n : {\n id: generateId(),\n type: 'generator' as const,\n yields: bodyYields,\n };\n\n const loopNode: StaticLoopNode = {\n id: generateId(),\n type: 'loop',\n loopType: 'forIn',\n iterSource,\n body: loopBody,\n ...(hasEarlyExit ? { hasEarlyExit } : {}),\n iterVariable,\n };\n ctx.stats.loopCount++;\n\n return [{ effect: loopNode }];\n }\n\n // -------------------------------------------------------------------\n // WhileStatement\n // -------------------------------------------------------------------\n case SyntaxKind.WhileStatement: {\n if (!containsGeneratorYield(stmt)) return [];\n const whileStmt = stmt as WhileStatement;\n\n const condition = whileStmt.getExpression().getText();\n\n const bodyStmt = whileStmt.getStatement();\n const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n const loopBody: StaticFlowNode =\n bodyYields.length === 1 && bodyYields[0]\n ? bodyYields[0].effect\n : {\n id: generateId(),\n type: 'generator' as const,\n yields: bodyYields,\n };\n\n const loopNode: StaticLoopNode = {\n id: generateId(),\n type: 'loop',\n loopType: 'while',\n iterSource: condition,\n body: loopBody,\n ...(hasEarlyExit ? { hasEarlyExit } : {}),\n };\n ctx.stats.loopCount++;\n\n return [{ effect: loopNode }];\n }\n\n // -------------------------------------------------------------------\n // DoStatement (do-while)\n // -------------------------------------------------------------------\n case SyntaxKind.DoStatement: {\n if (!containsGeneratorYield(stmt)) return [];\n const doStmt = stmt as DoStatement;\n\n const condition = doStmt.getExpression().getText();\n\n const bodyStmt = doStmt.getStatement();\n const bodyYields = yield* analyzeStatementBlock(bodyStmt, ctx);\n const hasEarlyExit = checkEarlyExit(bodyStmt);\n\n const loopBody: StaticFlowNode =\n bodyYields.length === 1 && bodyYields[0]\n ? bodyYields[0].effect\n : {\n id: generateId(),\n type: 'generator' as const,\n yields: bodyYields,\n };\n\n const loopNode: StaticLoopNode = {\n id: generateId(),\n type: 'loop',\n loopType: 'doWhile',\n iterSource: condition,\n body: loopBody,\n ...(hasEarlyExit ? { hasEarlyExit } : {}),\n };\n ctx.stats.loopCount++;\n\n return [{ effect: loopNode }];\n }\n\n // -------------------------------------------------------------------\n // TryStatement\n // -------------------------------------------------------------------\n case SyntaxKind.TryStatement: {\n if (!containsGeneratorYield(stmt)) return [];\n const tryStmt = stmt as TryStatement;\n\n const tryBlock = tryStmt.getTryBlock();\n const tryYields = yield* analyzeGeneratorBody(tryBlock, ctx);\n\n const catchClause = tryStmt.getCatchClause();\n let catchVariable: string | undefined;\n let catchYields: StaticGeneratorNode['yields'] | undefined;\n if (catchClause) {\n const variableDecl = catchClause.getVariableDeclaration();\n catchVariable = variableDecl?.getName();\n const catchBlock = catchClause.getBlock();\n catchYields = yield* analyzeGeneratorBody(catchBlock, ctx);\n }\n\n const finallyBlock = tryStmt.getFinallyBlock();\n let finallyYields: StaticGeneratorNode['yields'] | undefined;\n if (finallyBlock) {\n finallyYields = yield* analyzeGeneratorBody(finallyBlock, ctx);\n }\n\n const hasTerminalInTry = hasTerminatorStatement(tryBlock.getStatements());\n\n const tryCatchNode: StaticTryCatchNode = {\n id: generateId(),\n type: 'try-catch',\n tryBody: tryYields.map((y) => y.effect),\n ...(catchVariable ? { catchVariable } : {}),\n ...(catchYields && catchYields.length > 0\n ? { catchBody: catchYields.map((y) => y.effect) }\n : {}),\n ...(finallyYields && finallyYields.length > 0\n ? { finallyBody: finallyYields.map((y) => y.effect) }\n : {}),\n hasTerminalInTry,\n };\n ctx.stats.tryCatchCount++;\n\n return [{ effect: tryCatchNode }];\n }\n\n // -------------------------------------------------------------------\n // ReturnStatement\n // -------------------------------------------------------------------\n case SyntaxKind.ReturnStatement: {\n const retStmt = stmt as ReturnStatement;\n const expr = retStmt.getExpression();\n\n if (!expr || !containsGeneratorYield(expr)) {\n // return with no yield — skip (not interesting for the IR)\n return [];\n }\n\n // return yield* X or return (yield* X) — analyze the yield expression\n const yieldEntries = yield* analyzeExpressionForYields(expr, ctx);\n const termNode: StaticTerminalNode = {\n id: generateId(),\n type: 'terminal',\n terminalKind: 'return',\n value: yieldEntries.map((y) => y.effect),\n };\n ctx.stats.terminalCount++;\n return [{ effect: termNode }];\n }\n\n // -------------------------------------------------------------------\n // ThrowStatement\n // -------------------------------------------------------------------\n case SyntaxKind.ThrowStatement: {\n const throwStmt = stmt as ThrowStatement;\n const expr = throwStmt.getExpression();\n if (!containsGeneratorYield(expr)) {\n // throw without yields — skip (not interesting for the IR at top level)\n return [];\n }\n\n const valueYields = yield* analyzeExpressionForYields(expr, ctx);\n\n const termNode: StaticTerminalNode = {\n id: generateId(),\n type: 'terminal',\n terminalKind: 'throw',\n ...(valueYields.length > 0 ? { value: valueYields.map((y) => y.effect) } : {}),\n };\n ctx.stats.terminalCount++;\n return [{ effect: termNode }];\n }\n\n // -------------------------------------------------------------------\n // BreakStatement\n // -------------------------------------------------------------------\n case SyntaxKind.BreakStatement: {\n // Only emit break as a terminal when inside a yield-containing control flow.\n // We always skip at the top level since it can't appear there anyway,\n // but it may appear inside switch/loop bodies that we recurse into.\n return [];\n }\n\n // -------------------------------------------------------------------\n // ContinueStatement\n // -------------------------------------------------------------------\n case SyntaxKind.ContinueStatement: {\n // Same as break — skip as a yield entry.\n return [];\n }\n\n // -------------------------------------------------------------------\n // LabeledStatement — unwrap inner statement\n // -------------------------------------------------------------------\n case SyntaxKind.LabeledStatement: {\n const labeledStmt = stmt as LabeledStatement;\n return yield* analyzeStatement(labeledStmt.getStatement(), ctx);\n }\n\n // -------------------------------------------------------------------\n // Block — recurse\n // -------------------------------------------------------------------\n case SyntaxKind.Block: {\n return yield* analyzeGeneratorBody(stmt as Block, ctx);\n }\n\n // -------------------------------------------------------------------\n // Default — skip non-yield-containing statements\n // -------------------------------------------------------------------\n default:\n return [];\n }\n });\n}\n\n/**\n * Analyze a statement or block-like node into yield entries.\n * If the node is a Block, delegate to analyzeGeneratorBody.\n * Otherwise, treat it as a single statement (e.g., an if-then body without braces).\n */\nfunction analyzeStatementBlock(\n stmt: Node,\n ctx: WalkerContext,\n): Effect.Effect<StaticGeneratorNode['yields'], AnalysisError> {\n const { SyntaxKind } = loadTsMorph();\n if (stmt.getKind() === SyntaxKind.Block) {\n return analyzeGeneratorBody(stmt as Block, ctx);\n }\n return analyzeStatement(stmt, ctx);\n}\n\n/**\n * Check if a statement body contains an early exit (break/return) at any depth,\n * respecting function boundaries.\n */\nfunction checkEarlyExit(stmt: Node): boolean {\n const { SyntaxKind } = loadTsMorph();\n let found = false;\n stmt.forEachChild((child) => {\n if (found) return;\n if (isFunctionBoundary(child)) return;\n const k = child.getKind();\n if (k === SyntaxKind.BreakStatement || k === SyntaxKind.ReturnStatement) {\n found = true;\n return;\n }\n if (checkEarlyExit(child)) {\n found = true;\n return;\n }\n });\n return found;\n}\n\n/**\n * Analyze an expression node for yield expressions. Handles:\n * - Direct yield/yield* expressions\n * - Ternary expressions: cond ? yield* A : yield* B\n * - Short-circuit: cond && yield* A, cond || yield* B, x ?? yield* A\n * - Fallback: collect all yield* in evaluation order\n */\nfunction analyzeExpressionForYields(\n expr: Node,\n ctx: WalkerContext,\n): Effect.Effect<StaticGeneratorNode['yields'], AnalysisError> {\n return Effect.gen(function* () {\n const { SyntaxKind } = loadTsMorph();\n\n if (!containsGeneratorYield(expr)) return [];\n\n const unwrapped = unwrapExpression(expr);\n const exprKind = unwrapped.getKind();\n\n // Direct yield expression\n if (exprKind === SyntaxKind.YieldExpression) {\n const entry = yield* analyzeYieldNode(unwrapped, ctx);\n return [entry];\n }\n\n // Ternary: cond ? (yield* A) : (yield* B)\n if (exprKind === SyntaxKind.ConditionalExpression) {\n const ternary = unwrapped as ConditionalExpression;\n const condition = ternary.getCondition().getText();\n const whenTrue = ternary.getWhenTrue();\n const whenFalse = ternary.getWhenFalse();\n\n const trueYields = yield* analyzeExpressionForYields(whenTrue, ctx);\n const falseYields = yield* analyzeExpressionForYields(whenFalse, ctx);\n\n if (trueYields.length > 0 || falseYields.length > 0) {\n const resolvedCond = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n const decisionNode: StaticDecisionNode = {\n id: generateId(),\n type: 'decision',\n decisionId: generateId(),\n label: resolvedCond.length > 40 ? resolvedCond.slice(0, 40) + '...' : resolvedCond,\n condition,\n source: 'raw-ternary',\n onTrue: trueYields.map((y) => y.effect),\n onFalse: falseYields.length > 0 ? falseYields.map((y) => y.effect) : undefined,\n };\n ctx.stats.decisionCount++;\n return [{ effect: decisionNode }];\n }\n }\n\n // Binary expression: short-circuit (&&, ||, ??)\n if (exprKind === SyntaxKind.BinaryExpression) {\n const binary = unwrapped as BinaryExpression;\n const operatorToken = binary.getOperatorToken().getKind();\n const left = binary.getLeft();\n const right = binary.getRight();\n\n // && short-circuit: cond && (yield* A)\n if (operatorToken === SyntaxKind.AmpersandAmpersandToken) {\n const rightYields = yield* analyzeExpressionForYields(right, ctx);\n if (rightYields.length > 0) {\n const condition = left.getText();\n const resolvedCond = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n const decisionNode: StaticDecisionNode = {\n id: generateId(),\n type: 'decision',\n decisionId: generateId(),\n label: resolvedCond.length > 40 ? resolvedCond.slice(0, 40) + '...' : resolvedCond,\n condition,\n source: 'raw-short-circuit',\n onTrue: rightYields.map((y) => y.effect),\n onFalse: [],\n };\n ctx.stats.decisionCount++;\n return [{ effect: decisionNode }];\n }\n }\n\n // || short-circuit: cond || (yield* B)\n if (operatorToken === SyntaxKind.BarBarToken) {\n const rightYields = yield* analyzeExpressionForYields(right, ctx);\n if (rightYields.length > 0) {\n const condition = left.getText();\n const resolvedCond = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n const decisionNode: StaticDecisionNode = {\n id: generateId(),\n type: 'decision',\n decisionId: generateId(),\n label: resolvedCond.length > 40 ? resolvedCond.slice(0, 40) + '...' : resolvedCond,\n condition,\n source: 'raw-short-circuit',\n onTrue: [],\n onFalse: rightYields.map((y) => y.effect),\n };\n ctx.stats.decisionCount++;\n return [{ effect: decisionNode }];\n }\n }\n\n // ?? nullish coalescing: x ?? (yield* A)\n if (operatorToken === SyntaxKind.QuestionQuestionToken) {\n const rightYields = yield* analyzeExpressionForYields(right, ctx);\n if (rightYields.length > 0) {\n const condition = `${left.getText()} != null`;\n const resolvedCond = simplifyBooleanExpression(resolveConditionConsts(condition, ctx.constValues));\n const decisionNode: StaticDecisionNode = {\n id: generateId(),\n type: 'decision',\n decisionId: generateId(),\n label: resolvedCond.length > 40 ? resolvedCond.slice(0, 40) + '...' : resolvedCond,\n condition,\n source: 'raw-short-circuit',\n onTrue: [],\n onFalse: rightYields.map((y) => y.effect),\n };\n ctx.stats.decisionCount++;\n return [{ effect: decisionNode }];\n }\n }\n }\n\n // Fallback: collect all yield expressions in depth-first order\n const yieldExprs = collectYieldExpressionsDF(expr);\n const result: StaticGeneratorNode['yields'] = [];\n for (const yieldExpr of yieldExprs) {\n const entry = yield* analyzeYieldNode(yieldExpr, ctx);\n result.push(entry);\n }\n return result;\n });\n}\n\n// =============================================================================\n// Generator Function Analysis (rewritten with statement-level walker)\n// =============================================================================\n\nexport const analyzeGeneratorFunction = (\n node: Node,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<readonly StaticFlowNode[], AnalysisError> =>\n Effect.gen(function* () {\n const { SyntaxKind } = loadTsMorph();\n\n let body: Node | undefined;\n\n if (\n node.getKind() === SyntaxKind.ArrowFunction ||\n node.getKind() === SyntaxKind.FunctionExpression\n ) {\n body = (\n node as\n | import('ts-morph').ArrowFunction\n | import('ts-morph').FunctionExpression\n ).getBody();\n } else if (node.getKind() === SyntaxKind.FunctionDeclaration) {\n body = (node as FunctionDeclaration).getBody();\n }\n\n if (!body) {\n return [];\n }\n\n const serviceScope = new Map<string, string>();\n const constValues = new Map<string, string>();\n const ctx: WalkerContext = {\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n serviceScope,\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 // This intentionally includes calls nested inside yield* arguments — the existing\n // behavior produces additional entries for sub-expressions like Effect.provide()\n // inside pipe chains, which tests and downstream consumers rely on.\n const calls = body.getDescendantsOfKind(SyntaxKind.CallExpression);\n for (const call of calls) {\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 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\nexport function analyzeRunEntrypointExpression(\n call: CallExpression,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<Option.Option<readonly StaticFlowNode[]>, AnalysisError> {\n const calleeExpr = call.getExpression();\n const calleeText = calleeExpr.getText();\n const isPipeCall = calleeText.endsWith('.pipe') || calleeText === 'pipe';\n if (!isPipeCall) return Effect.succeed(Option.none());\n const args = call.getArguments();\n const lastArg = args[args.length - 1];\n if (!lastArg) return Effect.succeed(Option.none());\n const lastArgText = lastArg.getText();\n const isRunTerminated =\n lastArgText.includes('.runMain') ||\n lastArgText.includes('.runPromise') ||\n lastArgText.includes('.runSync') ||\n lastArgText.includes('.runFork');\n if (!isRunTerminated) return Effect.succeed(Option.none());\n return Effect.map(\n analyzePipeChain(call, sourceFile, filePath, opts, warnings, stats),\n (nodes) => Option.some(nodes),\n );\n}\n","/**\n * Effect expression analysis: pipe chains, effect calls, and domain-specific analyzers.\n */\n\nimport { Effect, Option } from 'effect';\nimport type {\n SourceFile,\n Node,\n CallExpression,\n ArrowFunction,\n FunctionExpression,\n Block,\n ReturnStatement,\n ObjectLiteralExpression,\n PropertyAssignment,\n PropertyAccessExpression,\n ExpressionStatement,\n Identifier,\n VariableDeclaration,\n ArrayLiteralExpression,\n NumericLiteral,\n StringLiteral,\n MethodDeclaration,\n ImportSpecifier,\n VariableStatement,\n} from 'ts-morph';\nimport { loadTsMorph } from './ts-morph-loader';\nimport type { AnalysisError, AnalyzerOptions, AnalysisWarning, AnalysisStats } from './types';\nimport type {\n StaticFlowNode,\n StaticEffectNode,\n StaticPipeNode,\n StaticParallelNode,\n StaticRaceNode,\n StaticErrorHandlerNode,\n StaticRetryNode,\n StaticTimeoutNode,\n StaticResourceNode,\n StaticConditionalNode,\n StaticLoopNode,\n StaticMatchNode,\n StaticCauseNode,\n StaticExitNode,\n StaticScheduleNode,\n StaticTransformNode,\n StaticLayerNode,\n StaticStreamNode,\n StaticChannelNode,\n StaticSinkNode,\n StaticConcurrencyPrimitiveNode,\n StaticFiberNode,\n StaticInterruptionNode,\n StaticUnknownNode,\n ConcurrencyMode,\n LayerLifecycle,\n StreamOperatorInfo,\n ChannelOperatorInfo,\n SinkOperatorInfo,\n ScheduleInfo,\n EffectTypeSignature,\n} from './types';\nimport { getStaticChildren } from './types';\nimport {\n extractEffectTypeSignature,\n extractServiceRequirements,\n extractLayerTypeSignature,\n} from './type-extractor';\nimport {\n generateId,\n extractLocation,\n extractJSDocDescription,\n extractJSDocTags,\n getNodeText,\n computeDisplayName,\n computeSemanticRole,\n} from './analysis-utils';\nimport {\n ERROR_HANDLER_PATTERNS,\n CONDITIONAL_PATTERNS,\n COLLECTION_PATTERNS,\n FIBER_PATTERNS,\n INTERRUPTION_PATTERNS,\n TRANSFORM_OPS,\n EFFECTFUL_TRANSFORMS,\n isTransformCall,\n MATCH_OP_MAP,\n EXHAUSTIVE_OPS,\n isMatchCall,\n CAUSE_OP_MAP,\n CAUSE_CONSTRUCTORS,\n isCauseCall,\n EXIT_OP_MAP,\n EXIT_CONSTRUCTORS,\n isExitCall,\n SCHEDULE_OP_MAP,\n isScheduleCall,\n getSemanticDescriptionWithAliases,\n parseServiceIdsFromContextType,\n getNumericLiteralFromNode,\n BUILT_IN_TYPE_NAMES,\n KNOWN_EFFECT_NAMESPACES,\n} from './analysis-patterns';\nimport {\n getAliasesForFile,\n isEffectCallee,\n isEffectLikeCallExpression,\n normalizeEffectCallee,\n resolveBarrelSourceFile,\n resolveModulePath,\n} from './alias-resolution';\nexport const analyzePipeChain = (\n node: CallExpression,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<readonly StaticFlowNode[], AnalysisError> =>\n Effect.gen(function* () {\n const { SyntaxKind } = loadTsMorph();\n const args = node.getArguments();\n const expr = node.getExpression();\n const isMethodPipe =\n expr.getKind() === SyntaxKind.PropertyAccessExpression &&\n (expr as PropertyAccessExpression).getName() === 'pipe';\n const baseExpr = isMethodPipe\n ? (expr as PropertyAccessExpression).getExpression()\n : args[0];\n const transformArgs = isMethodPipe ? args : args.slice(1);\n if (!baseExpr) return [];\n\n // GAP: pipe-chain when base is a variable — resolve to Layer initializer (same- or cross-file)\n const baseNode = resolveIdentifierToLayerInitializer(baseExpr);\n let baseSourceFile = baseNode.getSourceFile();\n const basePath = baseSourceFile.getFilePath();\n const project = sourceFile.getProject();\n // Ensure the resolved file is in the project so alias resolution (e.g. L→Layer) works\n if (!project.getSourceFile(basePath)) {\n const added = project.addSourceFileAtPath(basePath);\n if (added) baseSourceFile = added;\n } else {\n const inProject = project.getSourceFile(basePath);\n if (inProject) baseSourceFile = inProject;\n }\n const initial = yield* analyzeEffectExpression(\n baseNode,\n baseSourceFile,\n baseSourceFile.getFilePath(),\n opts,\n warnings,\n stats,\n );\n\n const transformations: StaticFlowNode[] = [];\n for (const arg of transformArgs) {\n if (arg) {\n const analyzed = yield* analyzeEffectExpression(\n arg,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n transformations.push(analyzed);\n }\n }\n\n // Extract type flow through pipe chain\n let typeFlow: EffectTypeSignature[] | undefined;\n try {\n const typeChecker = sourceFile.getProject().getTypeChecker();\n const flow: EffectTypeSignature[] = [];\n // Extract initial type\n const initialSig = extractEffectTypeSignature(baseExpr, typeChecker);\n if (initialSig) flow.push(initialSig);\n // Extract type at each transform step\n for (const argNode of transformArgs) {\n if (argNode) {\n const sig = extractEffectTypeSignature(argNode, typeChecker);\n if (sig) flow.push(sig);\n }\n }\n if (flow.length > 0) typeFlow = flow;\n } catch {\n // Type extraction can fail; skip type flow\n }\n\n const pipeNode: StaticPipeNode = {\n id: generateId(),\n type: 'pipe',\n initial,\n transformations,\n ...(typeFlow ? { typeFlow } : {}),\n };\n const enrichedPipeNode: StaticPipeNode = {\n ...pipeNode,\n displayName: computeDisplayName(pipeNode),\n semanticRole: computeSemanticRole(pipeNode),\n };\n\n return [enrichedPipeNode];\n });\n\n// =============================================================================\n// Effect Expression Analysis\n// =============================================================================\n\nexport const analyzeEffectExpression = (\n node: Node,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n serviceScope?: Map<string, string>,\n): Effect.Effect<StaticFlowNode, AnalysisError> =>\n Effect.gen(function* () {\n const { SyntaxKind } = loadTsMorph();\n\n // 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 unknownNode: StaticUnknownNode = {\n id: generateId(),\n type: 'unknown',\n reason: 'Function does not return an Effect expression',\n sourceCode: node.getText().slice(0, 100),\n location: extractLocation(node, filePath, opts.includeLocations ?? false),\n };\n stats.unknownCount++;\n return unknownNode;\n }\n\n // Handle call expressions\n if (node.getKind() === SyntaxKind.CallExpression) {\n return yield* analyzeEffectCall(\n node as CallExpression,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n serviceScope,\n );\n }\n\n // Handle property access chains (Effect.succeed(...))\n if (node.getKind() === SyntaxKind.PropertyAccessExpression) {\n const text = node.getText();\n // Fiber.roots / Fiber.getCurrentFiber — property access that yields an Effect (GAP 5)\n if (text === 'Fiber.roots' || text === 'Fiber.getCurrentFiber') {\n const operation: StaticFiberNode['operation'] =\n text === 'Fiber.roots' ? 'roots' : 'getCurrentFiber';\n return {\n id: generateId(),\n type: 'fiber',\n operation,\n isScoped: false,\n isDaemon: false,\n location: extractLocation(\n node,\n filePath,\n opts.includeLocations ?? false,\n ),\n };\n }\n if (isEffectCallee(text, getAliasesForFile(sourceFile), sourceFile)) {\n const effectNode: StaticEffectNode = {\n id: generateId(),\n type: 'effect',\n callee: text,\n location: extractLocation(\n node,\n filePath,\n opts.includeLocations ?? false,\n ),\n };\n stats.totalEffects++;\n return effectNode;\n }\n }\n\n // Handle identifier references\n if (node.getKind() === SyntaxKind.Identifier) {\n const effectNode: StaticEffectNode = {\n id: generateId(),\n type: 'effect',\n callee: node.getText(),\n location: extractLocation(\n node,\n filePath,\n opts.includeLocations ?? false,\n ),\n };\n stats.totalEffects++;\n return effectNode;\n }\n\n // Handle object literal with known Effect handler properties (match-style APIs)\n if (node.getKind() === SyntaxKind.ObjectLiteralExpression) {\n const objLit = node as ObjectLiteralExpression;\n const HANDLER_PROPS = new Set(['onNone', 'onSome', 'onFailure', 'onSuccess', 'onLeft', 'onRight']);\n const props = objLit.getProperties();\n const handlerEntries: StaticFlowNode[] = [];\n let hasKnownHandler = false;\n\n for (const prop of props) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const assignment = prop as PropertyAssignment;\n const propName = assignment.getName();\n if (!HANDLER_PROPS.has(propName)) continue;\n hasKnownHandler = true;\n const initializer = assignment.getInitializer();\n if (initializer) {\n const analyzed = yield* analyzeEffectExpression(\n initializer,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n serviceScope,\n );\n handlerEntries.push(analyzed);\n }\n }\n\n if (hasKnownHandler && handlerEntries.length > 0) {\n return handlerEntries.length === 1 ? handlerEntries[0]! : {\n id: generateId(),\n type: 'parallel',\n callee: 'match-handlers',\n mode: 'sequential' as const,\n children: handlerEntries,\n location: extractLocation(node, filePath, opts.includeLocations ?? false),\n };\n }\n }\n\n\n // Default: unknown\n const unknownNode: StaticUnknownNode = {\n id: generateId(),\n type: 'unknown',\n reason: 'Could not determine effect type',\n sourceCode: node.getText().slice(0, 100),\n location: extractLocation(node, filePath, opts.includeLocations ?? false),\n };\n stats.unknownCount++;\n return unknownNode;\n });\n\nexport const analyzeEffectCall = (\n call: CallExpression,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n serviceScope?: Map<string, string>,\n): Effect.Effect<StaticFlowNode, AnalysisError> =>\n Effect.gen(function* () {\n const { SyntaxKind } = loadTsMorph();\n const callee = call.getExpression().getText();\n const normalizedCallee = normalizeEffectCallee(callee, sourceFile);\n const calleeOperation =\n (/([A-Za-z_$][\\w$]*)$/.exec(normalizedCallee))?.[1] ?? normalizedCallee;\n const location = extractLocation(\n call,\n filePath,\n opts.includeLocations ?? false,\n );\n\n // pipe(base, ...fns) inside generator → analyze as pipe chain so transformations (e.g. RcRef.update) are classified\n if (callee === 'pipe' && call.getArguments().length >= 1) {\n const nodes = yield* analyzePipeChain(\n call,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n if (nodes.length > 0 && nodes[0]) return nodes[0];\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 if (normalizedCallee.startsWith('Stream.')) {\n return yield* analyzeStreamCall(\n call,\n normalizedCallee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (normalizedCallee.startsWith('Channel.')) {\n return yield* analyzeChannelCall(\n call,\n normalizedCallee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (callee.startsWith('Sink.')) {\n return yield* analyzeSinkCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n const isConcurrencyPrimitiveCallee =\n callee.startsWith('Queue.') ||\n callee.startsWith('PubSub.') ||\n callee.startsWith('Deferred.') ||\n callee.startsWith('Semaphore.') ||\n callee.startsWith('Mailbox.') ||\n callee.startsWith('SubscriptionRef.') ||\n callee.startsWith('RateLimiter.') ||\n callee.startsWith('PartitionedSemaphore.') ||\n callee.startsWith('FiberHandle.') ||\n callee.startsWith('FiberSet.') ||\n callee.startsWith('FiberMap.') ||\n callee.startsWith('Cache.') ||\n callee.startsWith('ScopedCache.') ||\n callee.startsWith('RcRef.') ||\n callee.includes('.RcRef.') ||\n callee.startsWith('RcMap.') ||\n callee.includes('.RcMap.') ||\n callee.startsWith('Reloadable.') ||\n callee.includes('.Reloadable.') ||\n callee.includes('makeLatch') ||\n callee.includes('Latch.');\n if (isConcurrencyPrimitiveCallee) {\n return yield* analyzeConcurrencyPrimitiveCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (FIBER_PATTERNS.some((p) => callee.includes(p) || callee.startsWith(p))) {\n return yield* analyzeFiberCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (INTERRUPTION_PATTERNS.some((p) => callee.includes(p))) {\n return yield* analyzeInterruptionCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n // Handle different Effect patterns\n if (callee.includes('.all') || callee === 'all') {\n return yield* analyzeParallelCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (callee.includes('.race') || callee === 'race') {\n return yield* analyzeRaceCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (ERROR_HANDLER_PATTERNS.some((pattern) => callee.includes(pattern))) {\n return yield* analyzeErrorHandlerCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (callee.includes('.retry')) {\n return yield* analyzeRetryCall(\n call,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (callee.includes('.timeout')) {\n return yield* analyzeTimeoutCall(\n call,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n const resourceOps = new Set([\n 'acquireRelease',\n 'acquireUseRelease',\n 'ensuring',\n 'addFinalizer',\n 'onExit',\n 'onError',\n 'parallelFinalizers',\n 'sequentialFinalizers',\n 'finalizersMask',\n 'using',\n 'withEarlyRelease',\n ]);\n const resourceOpPrefixes = ['acquireRelease', 'acquireUseRelease'] as const;\n const isResourceOp = (op: string) =>\n resourceOps.has(op) || resourceOpPrefixes.some((p) => op.startsWith(p));\n if (calleeOperation === 'pipe' && call.getExpression().getKind() === SyntaxKind.PropertyAccessExpression) {\n const propAccess = call.getExpression() as PropertyAccessExpression;\n const baseExpr = propAccess.getExpression();\n if (baseExpr.getKind() === SyntaxKind.CallExpression) {\n const baseCall = baseExpr as CallExpression;\n const baseCallee = baseCall.getExpression().getText();\n const baseOperation = (/([A-Za-z_$][\\w$]*)$/.exec(baseCallee))?.[1] ?? baseCallee;\n if (isResourceOp(baseOperation)) {\n return yield* analyzeResourceCall(\n baseCall,\n baseOperation,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n }\n }\n if (isResourceOp(calleeOperation)) {\n return yield* analyzeResourceCall(\n call,\n calleeOperation,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (CONDITIONAL_PATTERNS.some((pattern) => callee.includes(pattern))) {\n return yield* analyzeConditionalCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (COLLECTION_PATTERNS.some((pattern) => callee.includes(pattern))) {\n return yield* analyzeLoopCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (isTransformCall(callee)) {\n return yield* analyzeTransformCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (isMatchCall(callee)) {\n return analyzeMatchCall(call, callee, filePath, opts);\n }\n\n if (isCauseCall(callee)) {\n return yield* analyzeCauseCall(\n call,\n callee,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n if (isExitCall(callee)) {\n return analyzeExitCall(call, callee, filePath, opts);\n }\n\n if (isScheduleCall(callee)) {\n return yield* analyzeScheduleCall(call, callee, filePath, opts);\n }\n\n // Default effect node\n stats.totalEffects++;\n\n // Effect.sync/promise/async callback body (one level only)\n let callbackBody: readonly StaticFlowNode[] | undefined;\n const CONSTRUCTOR_CALLBACK_CALLEES = [\n 'Effect.sync',\n 'Effect.promise',\n 'Effect.async',\n 'Effect.asyncEffect',\n 'Effect.tryPromise',\n 'Effect.suspend',\n ];\n const isConstructorWithCallback =\n CONSTRUCTOR_CALLBACK_CALLEES.some((c) => callee.includes(c)) &&\n call.getArguments().length > 0 &&\n call.getArguments()[0];\n let asyncCallback: StaticEffectNode['asyncCallback'];\n if (isConstructorWithCallback) {\n const firstArg = call.getArguments()[0]!;\n const { SyntaxKind } = loadTsMorph();\n const isFn =\n firstArg.getKind() === SyntaxKind.ArrowFunction ||\n firstArg.getKind() === SyntaxKind.FunctionExpression;\n if (isFn) {\n const fn = firstArg as\n | ArrowFunction\n | FunctionExpression;\n const body = fn.getBody();\n const innerNodes: StaticFlowNode[] = [];\n if (body) {\n if (body.getKind() === SyntaxKind.Block) {\n const block = body as Block;\n for (const stmt of block.getStatements()) {\n if (stmt.getKind() === SyntaxKind.ReturnStatement) {\n const retExpr = (stmt as ReturnStatement).getExpression();\n if (retExpr && isEffectCallee(retExpr.getText(), getAliasesForFile(sourceFile), sourceFile)) {\n const analyzed = yield* analyzeEffectExpression(\n retExpr,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n undefined,\n );\n innerNodes.push(analyzed);\n }\n } else if (stmt.getKind() === SyntaxKind.ExpressionStatement) {\n const expr = (stmt as ExpressionStatement).getExpression();\n if (\n expr.getKind() === SyntaxKind.CallExpression &&\n isEffectLikeCallExpression(expr as CallExpression, sourceFile, getAliasesForFile(sourceFile), opts.knownEffectInternalsRoot)\n ) {\n const analyzed = yield* analyzeEffectExpression(\n expr,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n undefined,\n );\n innerNodes.push(analyzed);\n }\n }\n }\n } else {\n if (isEffectCallee(body.getText(), getAliasesForFile(sourceFile), sourceFile)) {\n const analyzed = yield* analyzeEffectExpression(\n body,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n undefined,\n );\n innerNodes.push(analyzed);\n }\n }\n }\n if (innerNodes.length > 0) callbackBody = innerNodes;\n\n // Effect.async/asyncEffect: resume/canceller patterns (GAP async callback interop)\n if (callee.includes('Effect.async') || callee.includes('Effect.asyncEffect')) {\n const resumeParamName =\n fn.getParameters()[0]?.getName?.() ?? 'resume';\n let resumeCallCount = 0;\n const visit = (node: Node) => {\n if (node.getKind() === SyntaxKind.CallExpression) {\n const callNode = node as CallExpression;\n const expr = callNode.getExpression();\n if (\n expr.getKind() === SyntaxKind.Identifier &&\n (expr as Identifier).getText() === resumeParamName\n ) {\n resumeCallCount++;\n }\n }\n node.getChildren().forEach(visit);\n };\n if (body) visit(body);\n let returnsCanceller = false;\n if (body?.getKind() === SyntaxKind.Block) {\n const block = body as Block;\n for (const stmt of block.getStatements()) {\n if (stmt.getKind() === SyntaxKind.ReturnStatement) {\n const retExpr = (stmt as ReturnStatement).getExpression();\n if (retExpr) {\n const k = retExpr.getKind();\n if (\n k === SyntaxKind.ArrowFunction ||\n k === SyntaxKind.FunctionExpression\n ) {\n returnsCanceller = true;\n break;\n }\n }\n }\n }\n } else if (\n body &&\n (body.getKind() === SyntaxKind.ArrowFunction ||\n body.getKind() === SyntaxKind.FunctionExpression)\n ) {\n returnsCanceller = true;\n }\n asyncCallback = {\n resumeParamName,\n resumeCallCount,\n returnsCanceller,\n };\n }\n }\n }\n\n // Extract JSDoc from the call statement\n const effectJSDoc = extractJSDocDescription(call);\n\n // Extract type signature and service requirements\n const typeChecker = sourceFile.getProject().getTypeChecker();\n const typeSignature = extractEffectTypeSignature(call, typeChecker);\n const requiredServices = extractServiceRequirements(call, typeChecker);\n\n // Try to identify service method calls\n const serviceCall = tryResolveServiceCall(call, sourceFile);\n\n // Resolve serviceMethod from generator scope or requiredServices fallback\n let serviceMethod: StaticEffectNode['serviceMethod'];\n const expr = call.getExpression();\n if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n const propAccess = expr as PropertyAccessExpression;\n const objectText = propAccess.getExpression().getText();\n const methodName = propAccess.getName();\n if (serviceScope) {\n const serviceId = serviceScope.get(objectText);\n if (serviceId) serviceMethod = { serviceId, methodName };\n }\n if (!serviceMethod && requiredServices?.length === 1 && requiredServices[0]) {\n serviceMethod = { serviceId: requiredServices[0].serviceId, methodName };\n }\n }\n\n // Effect.provide: infer provideKind from context arg (GAP 6: Runtime vs Layer/Context)\n // Two forms: Effect.provide(effect, layer) → 2 args, layer is args[1]; pipe(effect, Effect.provide(layer)) → 1 arg, layer is args[0]\n let provideKind: StaticEffectNode['provideKind'];\n if (\n callee === 'Effect.provide' ||\n (callee.startsWith('Effect.') && callee.includes('.provide') && !callee.includes('provideService'))\n ) {\n const args = call.getArguments();\n const contextArgText = (args.length >= 2 ? args[1] : args[0])?.getText() ?? '';\n if (\n /Runtime\\.|defaultRuntime|\\.runSync|\\.runPromise|\\.runFork|\\.runCallback/.test(contextArgText) ||\n /^\\s*runtime\\s*$|^\\s*rt\\s*$/i.test(contextArgText.trim())\n ) {\n provideKind = 'runtime';\n } else if (contextArgText.includes('Layer.')) {\n provideKind = 'layer';\n } else {\n provideKind = 'context';\n }\n }\n\n // Determine constructorKind\n let constructorKind: StaticEffectNode['constructorKind'];\n if (callee.endsWith('.sync') || callee.endsWith('.succeed') || callee.endsWith('.fail') || callee.endsWith('.try') || callee.endsWith('.suspend')) constructorKind = 'sync';\n else if (callee.endsWith('.promise')) constructorKind = 'promise';\n else if (callee.endsWith('.async') || callee.endsWith('.asyncEffect')) constructorKind = 'async';\n else if (callee.endsWith('.never')) constructorKind = 'never';\n else if (callee.endsWith('.void')) constructorKind = 'void';\n else if (callee.endsWith('.fromNullable')) constructorKind = 'fromNullable';\n else if (callee.endsWith('.fn')) constructorKind = 'fn';\n else if (callee.endsWith('.fnUntraced')) constructorKind = 'fnUntraced';\n\n // Extract FiberRef built-in name\n let fiberRefName: string | undefined;\n const KNOWN_FIBER_REFS = ['currentConcurrency', 'currentLogLevel', 'currentScheduler', 'currentTracerEnabled', 'currentLogSpan', 'currentLogAnnotations', 'currentContext', 'currentRequestBatching', 'currentMaxOpsBeforeYield', 'currentSupervisor', 'currentMetricLabels', 'interruptedCause', 'unhandledLogLevel'] as const;\n for (const refName of KNOWN_FIBER_REFS) {\n if (callee.includes(refName)) { fiberRefName = refName; break; }\n }\n\n // Extract Effect.fn traced name\n let tracedName: string | undefined;\n if (constructorKind === 'fn' || constructorKind === 'fnUntraced') {\n const args = call.getArguments();\n if (args.length > 0) {\n const firstArg = args[0]!.getText();\n const strMatch = /^[\"'`](.+?)[\"'`]$/.exec(firstArg);\n if (strMatch) tracedName = strMatch[1];\n }\n }\n\n const effectNode: StaticEffectNode = {\n id: generateId(),\n type: 'effect',\n callee,\n description: serviceCall ? 'service-call' : getSemanticDescriptionWithAliases(callee, getAliasesForFile(sourceFile)),\n location,\n jsdocDescription: effectJSDoc,\n jsdocTags: extractJSDocTags(call),\n typeSignature,\n requiredServices,\n serviceCall,\n serviceMethod,\n callbackBody,\n ...(asyncCallback ? { asyncCallback } : {}),\n ...(provideKind ? { provideKind } : {}),\n ...(constructorKind ? { constructorKind } : {}),\n ...(fiberRefName ? { fiberRefName } : {}),\n ...(tracedName ? { tracedName } : {}),\n };\n const enrichedEffectNode: StaticEffectNode = {\n ...effectNode,\n displayName: computeDisplayName(effectNode),\n semanticRole: computeSemanticRole(effectNode),\n };\n return enrichedEffectNode;\n });\n\n/**\n * Try to resolve a service method call from a CallExpression.\n * Returns metadata if the callee is `obj.method()` where `obj` has a\n * known, non-built-in type — indicating a yielded service method call.\n */\nconst tryResolveServiceCall = (\n call: CallExpression,\n _sourceFile: SourceFile,\n): StaticEffectNode['serviceCall'] => {\n const { SyntaxKind } = loadTsMorph();\n const expr = call.getExpression();\n\n // Must be a property access (obj.method form)\n if (expr.getKind() !== SyntaxKind.PropertyAccessExpression) return undefined;\n\n const propAccess = expr as PropertyAccessExpression;\n const objExpr = propAccess.getExpression();\n const methodName = propAccess.getName();\n const objectName = objExpr.getText();\n\n // Skip if first segment is a known Effect/JS namespace\n const firstSegment = objectName.split('.')[0] ?? objectName;\n if (KNOWN_EFFECT_NAMESPACES.has(firstSegment)) return undefined;\n\n try {\n const type = objExpr.getType();\n const symbol = type.getSymbol() ?? type.getAliasSymbol();\n if (!symbol) return undefined;\n\n const typeName = symbol.getName();\n // Skip anonymous structural types, built-ins, and error sentinels\n if (\n !typeName ||\n typeName === '__type' ||\n typeName === 'unknown' ||\n typeName === 'any' ||\n BUILT_IN_TYPE_NAMES.has(typeName)\n ) {\n return undefined;\n }\n\n return { serviceType: typeName, methodName, objectName };\n } catch {\n return undefined;\n }\n};\n\n// =============================================================================\n// Specific Pattern Analysis\n// =============================================================================\n\n/** Return true if the call expression text (e.g. \"Layer.succeed\" or \"L.succeed\") is a Layer or Effect initializer. */\nfunction 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.) */\nfunction resolveIdentifierToLayerInitializer(node: Node): Node {\n const { SyntaxKind } = loadTsMorph();\n if (node.getKind() !== SyntaxKind.Identifier) return node;\n const ident = node as Identifier;\n const name = ident.getText();\n let sym = ident.getSymbol();\n let decl = sym?.getValueDeclaration();\n let importSpec: ImportSpecifier | undefined =\n decl?.getKind() === SyntaxKind.ImportSpecifier ? (decl as ImportSpecifier) : undefined;\n if (!importSpec && sym) {\n const fromDecls = sym.getDeclarations().find((d) => d.getKind() === SyntaxKind.ImportSpecifier);\n if (fromDecls) importSpec = fromDecls as ImportSpecifier;\n }\n if (!importSpec) {\n const sf = ident.getSourceFile();\n for (const id of sf.getImportDeclarations()) {\n const defaultImport = id.getDefaultImport()?.getText();\n if (defaultImport === name) {\n const fromDefault = resolveLayerInitializerFromDefaultImport(\n ident,\n id,\n isLayerOrEffectInitializerCallee,\n );\n if (fromDefault) return fromDefault;\n }\n const spec = id\n .getNamedImports()\n .find((n) => n.getName() === name || n.getAliasNode()?.getText() === name);\n if (spec) {\n importSpec = spec;\n break;\n }\n }\n }\n // Cross-file: when the binding is an import, resolve via the target module first so we get\n // a node in the target file (alias resolution for L→Layer needs that file’s SourceFile).\n if (importSpec) {\n const fromImport = resolveLayerInitializerFromImport(\n ident,\n importSpec,\n isLayerOrEffectInitializerCallee,\n );\n if (fromImport) return fromImport;\n sym = sym?.getImmediatelyAliasedSymbol() ?? sym?.getAliasedSymbol();\n decl = sym?.getValueDeclaration();\n }\n // Also follow alias if valueDeclaration is an export specifier (re-export)\n if (decl?.getKind() === SyntaxKind.ExportSpecifier) {\n sym = sym?.getImmediatelyAliasedSymbol() ?? sym?.getAliasedSymbol();\n decl = sym?.getValueDeclaration();\n }\n // Fallback: search all declarations for a VariableDeclaration with Layer initializer (cross-module)\n if (sym && decl?.getKind() !== SyntaxKind.VariableDeclaration) {\n for (const d of sym.getDeclarations()) {\n if (d.getKind() === SyntaxKind.VariableDeclaration) {\n const v = d as VariableDeclaration;\n const init = v.getInitializer();\n if (init?.getKind() === SyntaxKind.CallExpression) {\n if (isLayerOrEffectInitializerCallee(init as CallExpression)) {\n return init;\n }\n }\n }\n }\n }\n if (decl?.getKind() === SyntaxKind.VariableDeclaration) {\n const vd = decl as VariableDeclaration;\n const init = vd.getInitializer();\n if (init?.getKind() === SyntaxKind.CallExpression) {\n if (isLayerOrEffectInitializerCallee(init as CallExpression)) {\n return init;\n }\n }\n }\n return node;\n}\n\nconst analyzeLayerCall = (\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticLayerNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n const operations: StaticFlowNode[] = [];\n const { SyntaxKind } = loadTsMorph();\n\n if (args.length > 0 && args[0]) {\n const firstArg = args[0];\n const isMergeAll =\n callee.includes('mergeAll') &&\n firstArg.getKind() === SyntaxKind.ArrayLiteralExpression;\n\n if (isMergeAll) {\n const elements = (\n firstArg as ArrayLiteralExpression\n ).getElements();\n for (const elem of elements) {\n const analyzed = yield* analyzeEffectExpression(\n elem,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n operations.push(analyzed);\n }\n } else {\n for (const arg of args) {\n if (!arg) continue;\n const toAnalyze = resolveIdentifierToLayerInitializer(arg);\n const argSourceFile = toAnalyze.getSourceFile();\n const analyzed = yield* analyzeEffectExpression(\n toAnalyze,\n argSourceFile,\n argSourceFile.getFilePath(),\n opts,\n warnings,\n stats,\n );\n operations.push(analyzed);\n }\n }\n }\n\n const isMerged =\n callee.includes('merge') || callee.includes('mergeAll');\n\n let lifecycle: LayerLifecycle | undefined;\n if (callee.includes('fresh')) lifecycle = 'fresh';\n else if (callee.includes('memoize')) lifecycle = 'memoized';\n else if (callee.includes('scoped')) lifecycle = 'scoped';\n else lifecycle = 'default';\n\n // Layer error-handling / utility ops — track as semantic description on the node\n // These don't change the primitive provides/requires but are important to detect:\n // catchAll, orDie, orElse, retry, tap, mapError, build, launch, toRuntime,\n // passthrough, project, flatMap, flatten, annotateLogs, annotateSpans,\n // setConfigProvider, setClock, setTracer, locally, withSpan\n\n const provides: string[] = [];\n // Helper: extract a tag name from an arg (Identifier or PropertyAccessExpression)\n const extractTagName = (node: Node): string | undefined => {\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];\n }\n return undefined;\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 const tag = extractTagName(args[0]);\n if (tag) provides.push(tag);\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 const depName = extractTagName(args[0]);\n if (depName) requiresSet.add(depName);\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 const depName = extractTagName(args[1]);\n if (depName) requiresSet.add(depName);\n // The provides of the composed layer come from base (args[0])\n const baseName = extractTagName(args[0]!);\n if (baseName) provides.push(baseName);\n }\n // Layer.provideService(tag, value) — provides a service inline\n if (callee.includes('provideService') && args.length > 0 && args[0]) {\n const tag = extractTagName(args[0]);\n if (tag) provides.push(tag);\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 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 } catch {\n // type extraction can fail\n }\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 'catchAll', 'catchAllCause', 'orDie', 'orElse', 'retry', 'tap',\n 'mapError', 'mapErrorCause', 'build', 'launch', 'toRuntime',\n 'passthrough', 'project', 'flatMap', 'flatten', 'annotateLogs',\n 'annotateSpans', 'setConfigProvider', 'setClock', 'setTracer',\n 'locally', 'withSpan', 'withLogger', 'withTracer', 'withClock',\n 'mock', 'suspend', 'unwrapEffect', 'unwrapScoped',\n ]);\n const layerName = UTILITY_LAYER_OPS.has(layerOpName) ? `Layer.${layerOpName}` : undefined;\n\n // GAP Layer.MemoMap: dedicated memo-map analysis\n const isMemoMap =\n callee.includes('MemoMap') ||\n operations.some(\n (op) => op.type === 'layer' && (op).isMemoMap === true,\n );\n\n const layerNode: StaticLayerNode = {\n id: generateId(),\n type: 'layer',\n name: layerName,\n operations,\n isMerged,\n provides: provides.length > 0 ? provides : undefined,\n requires: requiresSet.size > 0 ? Array.from(requiresSet).sort() : undefined,\n lifecycle,\n ...(isMemoMap ? { isMemoMap: true } : {}),\n location: extractLocation(\n call,\n filePath,\n opts.includeLocations ?? false,\n ),\n };\n return {\n ...layerNode,\n displayName: computeDisplayName(layerNode),\n semanticRole: computeSemanticRole(layerNode),\n };\n });\n\n/** Parse Stream.* call into StaticStreamNode (GAP 5). */\nfunction analyzeStreamCall(\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticStreamNode, AnalysisError> {\n return Effect.gen(function* () {\n const args = call.getArguments();\n let source: StaticFlowNode;\n if (args.length > 0 && args[0]) {\n source = yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n } else {\n source = {\n id: generateId(),\n type: 'unknown',\n reason: 'Stream source not determined',\n };\n }\n const opName = callee.replace(/^Stream\\./, '') || 'unknown';\n\n // Classify constructor type\n let constructorType: StaticStreamNode['constructorType'];\n if (callee.startsWith('Stream.')) {\n if (opName === 'fromIterable' || opName === 'fromChunk' || opName === 'fromChunkQueue') constructorType = 'fromIterable';\n else if (opName === 'fromArray') constructorType = 'fromArray';\n else if (opName === 'fromQueue' || opName === 'fromChunkQueue') constructorType = 'fromQueue';\n else if (opName === 'fromPubSub' || opName === 'fromChunkPubSub') constructorType = 'fromPubSub';\n else if (opName === 'fromEffect' || opName === 'unwrap' || opName === 'unwrapScoped') constructorType = 'fromEffect';\n else if (opName === 'fromAsyncIterable') constructorType = 'fromAsyncIterable';\n else if (opName === 'fromReadableStream' || opName === 'fromReadableStreamByob') constructorType = 'fromReadableStream';\n else if (opName === 'fromEventListener') constructorType = 'fromEventListener';\n else if (opName === 'fromSchedule') constructorType = 'fromSchedule';\n else if (opName === 'range') constructorType = 'range';\n else if (opName === 'tick') constructorType = 'tick';\n else if (opName === 'iterate' || opName === 'iterateEffect') constructorType = 'iterate';\n else if (opName === 'unfold' || opName === 'unfoldEffect' || opName === 'unfoldChunk' || opName === 'unfoldChunkEffect') constructorType = 'unfold';\n else if (opName === 'make') constructorType = 'make';\n else if (opName === 'empty') constructorType = 'empty';\n else if (opName === 'never') constructorType = 'never';\n else if (opName === 'succeed' || opName === 'sync') constructorType = 'succeed';\n else if (opName === 'fail' || opName === 'failSync' || opName === 'failCause' || opName === 'failCauseSync') constructorType = 'fail';\n }\n\n // Classify operator category\n const classifyOperator = (op: string): StreamOperatorInfo['category'] => {\n if (constructorType !== undefined) return 'constructor';\n if (op.startsWith('run')) return 'sink';\n if (op === 'toQueue' || op === 'toPubSub' || op === 'toReadableStream' || op === 'toAsyncIterable' || op === 'toChannel') return 'conversion';\n if (op.includes('pipeThroughChannel') || op.includes('Channel') || op.includes('channel') || op.includes('duplex')) return 'channel';\n if (op.includes('grouped') || op.includes('sliding') || op.includes('groupBy') || op.includes('aggregate') || op.includes('window')) return 'windowing';\n if (op.includes('broadcast') || op === 'share') return 'broadcasting';\n if (op.includes('haltAfter') || op.includes('haltWhen') || op.includes('interruptAfter')) return 'halting';\n if (op.includes('decodeText') || op.includes('encodeText') || op.includes('splitLines')) return 'text';\n if (op.includes('merge') || op === 'concat' || op.includes('interleave') || op.includes('zip')) return 'merge';\n if (op.includes('buffer') || op.includes('debounce') || op.includes('throttle')) return 'backpressure';\n if (op.includes('catchAll') || op.includes('catchTag') || op.includes('orElse') || op.includes('orDie') || op.includes('retry')) return 'error';\n if (op.includes('filter') || op.includes('take') || op.includes('drop') || op.includes('head') || op === 'first' || op === 'last') return 'filter';\n if (op.includes('acquireRelease') || op.includes('scoped') || op.includes('ensuring') || op.includes('onDone') || op.includes('onError')) return 'resource';\n if (op.includes('provide') || op.includes('withSpan') || op.includes('annotate')) return 'context';\n if (op.includes('map') || op.includes('tap') || op.includes('flatMap') || op.includes('mapChunk') || op.includes('scan') || op.includes('transduce')) return 'transform';\n return 'other';\n };\n\n const isEffectful =\n opName.includes('Effect') ||\n opName.startsWith('run') ||\n opName.includes('tap');\n const opCategory = classifyOperator(opName);\n const cardinality: StreamOperatorInfo['estimatedCardinality'] =\n opCategory === 'filter' ? 'fewer' :\n opCategory === 'merge' ? 'more' :\n opCategory === 'broadcasting' ? 'more' :\n opCategory === 'halting' ? 'fewer' :\n opCategory === 'sink' ? 'fewer' :\n opCategory === 'windowing' ? 'fewer' :\n 'unknown';\n\n // Windowing detail (GAP 2): size/stride for grouped, groupedWithin, sliding\n let windowSize: number | undefined;\n let stride: number | undefined;\n const isWindowingOp =\n opName === 'grouped' ||\n opName === 'groupedWithin' ||\n opName.includes('sliding') ||\n opName.includes('Sliding');\n if (isWindowingOp && args.length > 0 && args[0]) {\n windowSize = getNumericLiteralFromNode(args[0]);\n if (\n (opName.includes('sliding') || opName.includes('Sliding')) &&\n args.length > 1 &&\n args[1]\n ) {\n stride = getNumericLiteralFromNode(args[1]);\n }\n }\n\n const thisOp: StreamOperatorInfo = {\n operation: opName,\n isEffectful,\n estimatedCardinality: cardinality,\n category: opCategory,\n ...(windowSize !== undefined ? { windowSize } : {}),\n ...(stride !== undefined ? { stride } : {}),\n };\n\n let sink: string | undefined;\n if (opName.startsWith('run')) sink = opName;\n let backpressureStrategy: StaticStreamNode['backpressureStrategy'];\n if (opName.includes('buffer')) backpressureStrategy = 'buffer';\n else if (opName.includes('drop') || opName.includes('Drop')) backpressureStrategy = 'drop';\n else if (opName.includes('sliding') || opName.includes('Sliding')) backpressureStrategy = 'sliding';\n\n // Flatten nested stream pipeline: if source is itself a StreamNode (data-last\n // call pattern), merge its pipeline into ours and use its base source.\n let effectiveSource = source;\n let pipeline: StreamOperatorInfo[] = [thisOp];\n let effectiveConstructorType = constructorType;\n if (source.type === 'stream') {\n const srcStream = source;\n // Prepend the upstream pipeline so the full chain is visible in one node\n pipeline = [...srcStream.pipeline, thisOp];\n effectiveSource = srcStream.source;\n // Inherit upstream constructorType/sink/strategy if this node doesn't override\n if (!effectiveConstructorType && srcStream.constructorType) effectiveConstructorType = srcStream.constructorType;\n if (!sink && srcStream.sink) sink = srcStream.sink;\n if (!backpressureStrategy && srcStream.backpressureStrategy) backpressureStrategy = srcStream.backpressureStrategy;\n }\n\n const streamNode: StaticStreamNode = {\n id: generateId(),\n type: 'stream',\n source: effectiveSource,\n pipeline,\n sink,\n backpressureStrategy,\n constructorType: effectiveConstructorType,\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...streamNode,\n displayName: computeDisplayName(streamNode),\n semanticRole: computeSemanticRole(streamNode),\n };\n });\n}\n\n/** Classify Channel.* operation (improve.md §8). */\nfunction channelOpCategory(op: string): ChannelOperatorInfo['category'] {\n if (op === 'fromReadableStream' || op === 'fromWritableStream' || op === 'fromDuplexStream' || op === 'make' || op === 'succeed' || op === 'fail' || op === 'empty' || op === 'never') return 'constructor';\n if (op.includes('map') || op.includes('flatMap') || op.includes('filter') || op.includes('concat') || op.includes('zip')) return 'transform';\n if (op.includes('pipe') || op === 'pipeTo' || op === 'pipeThrough') return 'pipe';\n return 'other';\n}\n\n/** Parse Channel.* call into StaticChannelNode (improve.md §8). */\nfunction analyzeChannelCall(\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticChannelNode, AnalysisError> {\n return Effect.gen(function* () {\n const args = call.getArguments();\n let source: StaticFlowNode | undefined;\n if (args.length > 0 && args[0]) {\n source = yield* analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats);\n }\n const opName = callee.replace(/^Channel\\./, '') || 'unknown';\n const pipeline: ChannelOperatorInfo[] = [{ operation: opName, category: channelOpCategory(opName) }];\n if (source?.type === 'channel') {\n const srcChan = source;\n pipeline.unshift(...srcChan.pipeline);\n source = srcChan.source;\n }\n const channelNode: StaticChannelNode = {\n id: generateId(),\n type: 'channel',\n source,\n pipeline,\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...channelNode,\n displayName: computeDisplayName(channelNode),\n semanticRole: computeSemanticRole(channelNode),\n };\n });\n}\n\n/** Classify Sink.* operation (improve.md §8). */\nfunction sinkOpCategory(op: string): SinkOperatorInfo['category'] {\n if (op === 'forEach' || op === 'forEachWhile' || op === 'run' || op === 'runDrain' || op === 'runFor' || op === 'make' || op === 'fromEffect' || op === 'fromQueue') return 'constructor';\n if (op.includes('map') || op.includes('contramap') || op.includes('filter') || op.includes('zip')) return 'transform';\n return 'other';\n}\n\n/** Parse Sink.* call into StaticSinkNode (improve.md §8). */\nfunction analyzeSinkCall(\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticSinkNode, AnalysisError> {\n return Effect.gen(function* () {\n const args = call.getArguments();\n let source: StaticFlowNode | undefined;\n if (args.length > 0 && args[0]) {\n source = yield* analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats);\n }\n const opName = callee.replace(/^Sink\\./, '') || 'unknown';\n const pipeline: SinkOperatorInfo[] = [{ operation: opName, category: sinkOpCategory(opName) }];\n if (source?.type === 'sink') {\n const srcSink = source;\n pipeline.unshift(...srcSink.pipeline);\n source = srcSink.source;\n }\n const sinkNode: StaticSinkNode = {\n id: generateId(),\n type: 'sink',\n source,\n pipeline,\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...sinkNode,\n displayName: computeDisplayName(sinkNode),\n semanticRole: computeSemanticRole(sinkNode),\n };\n });\n}\n\n/** Parse concurrency primitive (Queue, PubSub, Deferred, etc.) - GAP 6 */\nfunction analyzeConcurrencyPrimitiveCall(\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n _warnings: AnalysisWarning[],\n _stats: AnalysisStats,\n): Effect.Effect<StaticConcurrencyPrimitiveNode | StaticStreamNode, AnalysisError> {\n const { SyntaxKind } = loadTsMorph();\n let primitive: StaticConcurrencyPrimitiveNode['primitive'] = 'queue';\n let operation: StaticConcurrencyPrimitiveNode['operation'] = 'create';\n let strategy: 'bounded' | 'unbounded' | 'sliding' | 'dropping' | undefined;\n let capacity: number | undefined;\n let permitCount: number | undefined;\n\n if (callee.startsWith('Queue.')) {\n primitive = 'queue';\n if (callee.includes('bounded')) strategy = 'bounded';\n else if (callee.includes('unbounded')) strategy = 'unbounded';\n else if (callee.includes('sliding')) strategy = 'sliding';\n else if (callee.includes('dropping')) strategy = 'dropping';\n if (callee.includes('offer') || callee.includes('offerAll')) operation = 'offer';\n else if (callee.includes('take') || callee.includes('takeAll') || callee.includes('poll')) operation = 'take';\n else operation = 'create';\n } else if (callee.startsWith('PubSub.')) {\n primitive = 'pubsub';\n if (callee.includes('bounded')) strategy = 'bounded';\n else if (callee.includes('unbounded')) strategy = 'unbounded';\n if (callee.includes('publish')) operation = 'publish';\n else if (callee.includes('subscribe')) operation = 'subscribe';\n else operation = 'create';\n } else if (callee.startsWith('Deferred.')) {\n primitive = 'deferred';\n if (callee.includes('succeed')) operation = 'succeed';\n else if (callee.includes('fail')) operation = 'fail';\n else if (callee.includes('await')) operation = 'await';\n else operation = 'create';\n } else if (callee.startsWith('Semaphore.')) {\n primitive = 'semaphore';\n if (callee.includes('withPermit')) operation = 'withPermit';\n else if (callee.includes('take')) operation = 'take';\n else if (callee.includes('release')) operation = 'release';\n else if (callee.includes('available')) operation = 'available';\n else operation = 'create';\n } else if (callee.startsWith('Mailbox.')) {\n primitive = 'mailbox';\n if (callee.includes('offer')) operation = 'offer';\n else if (callee.includes('takeAll')) operation = 'takeAll';\n else if (callee.includes('take')) operation = 'take';\n else if (callee.includes('end')) operation = 'end';\n else if (callee.includes('toStream')) operation = 'toStream';\n else operation = 'create';\n } else if (callee.startsWith('SubscriptionRef.')) {\n primitive = 'subscriptionRef';\n if (callee.includes('changes')) operation = 'changes';\n else if (callee.includes('get')) operation = 'get';\n else if (callee.includes('set')) operation = 'set';\n else if (callee.includes('update')) operation = 'update';\n else operation = 'create';\n } else if (callee.includes('makeLatch') || callee.includes('Latch.')) {\n primitive = 'latch';\n if (callee.includes('open')) operation = 'open';\n else if (callee.includes('close')) operation = 'close';\n else if (callee.includes('await') || callee.includes('whenOpen')) operation = 'await';\n else operation = 'create';\n } else if (callee.startsWith('FiberHandle.')) {\n primitive = 'fiberHandle';\n if (callee.includes('run')) operation = 'run';\n else if (callee.includes('await')) operation = 'await';\n else operation = 'create';\n } else if (callee.startsWith('FiberSet.')) {\n primitive = 'fiberSet';\n if (callee.includes('run')) operation = 'run';\n else if (callee.includes('join')) operation = 'await';\n else operation = 'create';\n } else if (callee.startsWith('FiberMap.')) {\n primitive = 'fiberMap';\n if (callee.includes('run')) operation = 'run';\n else if (callee.includes('join')) operation = 'await';\n else operation = 'create';\n } else if (callee.startsWith('RateLimiter.')) {\n primitive = 'rateLimiter';\n if (callee.includes('withCost')) operation = 'withPermit';\n else operation = 'create';\n } else if (callee.startsWith('ScopedCache.')) {\n primitive = 'scopedCache';\n if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n else if (callee.includes('get') && !callee.includes('getOrElse')) operation = 'get';\n else if (callee.includes('getOrElse')) operation = 'get';\n else if (callee.includes('set') || callee.includes('Set')) operation = 'set';\n else if (callee.includes('invalidate')) operation = 'invalidate';\n else if (callee.includes('contains')) operation = 'contains';\n else operation = 'create';\n } else if (callee.startsWith('Cache.')) {\n primitive = 'cache';\n if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n else if (callee.includes('get') && !callee.includes('getOrElse')) operation = 'get';\n else if (callee.includes('getOrElse')) operation = 'get';\n else if (callee.includes('set') || callee.includes('Set')) operation = 'set';\n else if (callee.includes('invalidate')) operation = 'invalidate';\n else if (callee.includes('contains')) operation = 'contains';\n else operation = 'create';\n } else if (callee.startsWith('Reloadable.') || callee.includes('.Reloadable.')) {\n primitive = 'reloadable';\n if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n else if (callee.includes('get') && !callee.includes('reload')) operation = 'get';\n else if (callee.includes('reload')) operation = 'reload';\n else operation = 'create';\n } else if (callee.startsWith('RcMap.') || callee.includes('.RcMap.')) {\n primitive = 'rcMap';\n if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n else if (callee.includes('get')) operation = 'get';\n else if (callee.includes('set') || callee.includes('Set')) operation = 'set';\n else if (callee.includes('update')) operation = 'update';\n else operation = 'create';\n } else if (callee.startsWith('RcRef.') || callee.includes('.RcRef.')) {\n primitive = 'rcRef';\n if (callee.includes('make') || callee.includes('Make')) operation = 'create';\n else if (callee.includes('get')) operation = 'get';\n else if (callee.includes('set') || callee.includes('Set')) operation = 'set';\n else if (callee.includes('update')) operation = 'update';\n else operation = 'create';\n }\n\n const args = call.getArguments();\n if (args.length > 0 && strategy === 'bounded') {\n const first = args[0];\n if (first?.getKind() === SyntaxKind.NumericLiteral) {\n capacity = Number.parseInt((first as NumericLiteral).getText(), 10);\n }\n }\n if (primitive === 'semaphore' && (operation === 'take' || operation === 'release') && args.length > 0 && args[0]) {\n permitCount = getNumericLiteralFromNode(args[0]);\n }\n\n // Extract lifecycle options for FiberHandle.run({ onlyIfMissing: true })\n let lifecycleOptions: Record<string, unknown> | undefined;\n if (primitive === 'fiberHandle' && operation === 'run') {\n for (const arg of args) {\n const text = arg.getText();\n if (text.includes('onlyIfMissing')) {\n lifecycleOptions = { onlyIfMissing: text.includes('true') };\n }\n }\n }\n\n // Mailbox.toStream and SubscriptionRef.changes produce stream nodes\n if ((primitive === 'mailbox' && operation === 'toStream') ||\n (primitive === 'subscriptionRef' && operation === 'changes')) {\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 as StaticConcurrencyPrimitiveNode),\n semanticRole: computeSemanticRole(innerPrimNode as StaticConcurrencyPrimitiveNode),\n } as StaticConcurrencyPrimitiveNode,\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 } as StaticStreamNode);\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 */\nfunction analyzeFiberCall(\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticFiberNode, AnalysisError> {\n return Effect.gen(function* () {\n const args = call.getArguments();\n let operation: StaticFiberNode['operation'] = 'fork';\n let isScoped = false;\n let isDaemon = false;\n let fiberSource: StaticFlowNode | undefined;\n\n if (callee.startsWith('Fiber.')) {\n if (callee.includes('awaitAll')) operation = 'awaitAll';\n else if (callee.includes('join')) operation = 'join';\n else if (callee.includes('await')) operation = 'await';\n else if (callee.includes('interruptFork')) operation = 'interruptFork';\n else if (callee.includes('interrupt')) operation = 'interrupt';\n else if (callee.includes('poll')) operation = 'poll';\n else if (callee.includes('status')) operation = 'status';\n else if (callee.includes('all')) operation = 'all';\n else if (callee.includes('children')) operation = 'children';\n else if (callee.includes('dump')) operation = 'dump';\n else if (callee.includes('scoped')) { operation = 'scoped'; isScoped = true; }\n else if (callee.includes('inheritAll')) operation = 'inheritAll';\n else if (callee.includes('mapFiber')) operation = 'mapFiber';\n else if (callee.includes('mapEffect')) operation = 'mapEffect';\n else if (callee.includes('map')) operation = 'map';\n else if (callee.includes('roots')) operation = 'roots';\n else if (callee.includes('getCurrentFiber')) operation = 'getCurrentFiber';\n } else if (callee.includes('forkWithErrorHandler')) {\n operation = 'forkWithErrorHandler';\n } else if (callee.includes('forkAll')) {\n operation = 'forkAll';\n } else if (callee.includes('forkIn')) {\n operation = 'forkIn';\n } else if (callee.includes('fork')) {\n if (callee.includes('forkDaemon')) {\n operation = 'forkDaemon';\n isDaemon = true;\n } else if (callee.includes('forkScoped')) {\n operation = 'forkScoped';\n isScoped = true;\n } else {\n operation = 'fork';\n }\n }\n\n if ((operation === 'fork' || operation === 'forkScoped' || operation === 'forkDaemon' || operation === 'forkAll' || operation === 'forkIn' || operation === 'forkWithErrorHandler') && args.length > 0 && args[0]) {\n fiberSource = yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\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 ...(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.) */\nfunction analyzeInterruptionCall(\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticInterruptionNode, AnalysisError> {\n return Effect.gen(function* () {\n const args = call.getArguments();\n const { SyntaxKind } = loadTsMorph();\n\n let interruptionType: StaticInterruptionNode['interruptionType'];\n if (callee.includes('uninterruptibleMask')) interruptionType = 'uninterruptibleMask';\n else if (callee.includes('interruptibleMask')) interruptionType = 'interruptibleMask';\n else if (callee.includes('uninterruptible')) interruptionType = 'uninterruptible';\n else if (callee.includes('interruptible')) interruptionType = 'interruptible';\n else if (callee.includes('onInterrupt')) interruptionType = 'onInterrupt';\n else if (callee.includes('disconnect')) interruptionType = 'disconnect';\n else if (callee.includes('allowInterrupt')) interruptionType = 'allowInterrupt';\n else if (callee.includes('interruptWith')) interruptionType = 'interruptWith';\n else interruptionType = 'interrupt';\n\n let source: StaticFlowNode | undefined;\n let handler: StaticFlowNode | undefined;\n\n // Method call form: effect.pipe(Effect.interruptible) or effect.interruptible\n const expr = call.getExpression();\n if (expr.getKind() === SyntaxKind.PropertyAccessExpression) {\n const propAccess = expr as PropertyAccessExpression;\n source = yield* analyzeEffectExpression(propAccess.getExpression(), sourceFile, filePath, opts, warnings, stats);\n if (args.length > 0 && args[0]) {\n handler = yield* analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats);\n }\n } else if (args.length > 0 && args[0]) {\n source = yield* analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats);\n if (args.length > 1 && args[1]) {\n handler = yield* 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/** Parse Effect.all options object: concurrency, batching, discard (GAP 18) */\nfunction parseEffectAllOptions(\n optionsNode: ObjectLiteralExpression,\n): {\n concurrency: ConcurrencyMode | undefined;\n batching: boolean | undefined;\n discard: boolean | undefined;\n} {\n const { SyntaxKind } = loadTsMorph();\n let concurrency: ConcurrencyMode | undefined;\n let batching: boolean | undefined;\n let discard: boolean | undefined;\n for (const prop of optionsNode.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const name = (prop as PropertyAssignment)\n .getNameNode()\n .getText();\n const init = (prop as PropertyAssignment).getInitializer();\n if (!init) continue;\n const text = init.getText();\n if (name === 'concurrency') {\n if (text === '\"unbounded\"' || text === \"'unbounded'\") concurrency = 'unbounded';\n else if (text === '\"sequential\"' || text === \"'sequential'\") concurrency = 'sequential';\n else if (text === '\"inherit\"' || text === \"'inherit'\") concurrency = 'sequential';\n else {\n const n = Number.parseInt(text, 10);\n if (!Number.isNaN(n) && n >= 0) concurrency = n;\n }\n } else if (name === 'batching' && (text === 'true' || text === 'false')) {\n batching = text === 'true';\n } else if (name === 'discard' && (text === 'true' || text === 'false')) {\n discard = text === 'true';\n }\n }\n return { concurrency, batching, discard };\n}\n\nconst analyzeParallelCall = (\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticParallelNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n const children: StaticFlowNode[] = [];\n const { SyntaxKind } = loadTsMorph();\n\n // First argument: array of effects or object with effect properties\n if (args.length > 0 && args[0]) {\n const firstArg = args[0];\n\n if (firstArg.getKind() === SyntaxKind.ArrayLiteralExpression) {\n const elements = (\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 children.push(analyzed);\n }\n } else if (firstArg.getKind() === SyntaxKind.ObjectLiteralExpression) {\n const props = (\n firstArg as ObjectLiteralExpression\n ).getProperties();\n for (const prop of props) {\n if (prop.getKind() === SyntaxKind.PropertyAssignment) {\n const initializer = (\n prop as PropertyAssignment\n ).getInitializer();\n if (initializer) {\n const analyzed = yield* analyzeEffectExpression(\n initializer,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\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(\n args[1] as ObjectLiteralExpression,\n );\n concurrency = parsed.concurrency;\n batching = parsed.batching;\n discard = parsed.discard;\n }\n\n const mode = callee.includes('Par') ? 'parallel' : 'sequential';\n if (concurrency === undefined) {\n concurrency = mode === 'parallel' ? 'unbounded' : 'sequential';\n }\n\n stats.parallelCount++;\n\n const branchLabels = children.map((child) => computeDisplayName(child));\n const parallelNode: StaticParallelNode = {\n id: generateId(),\n type: 'parallel',\n callee,\n mode,\n children,\n concurrency,\n batching,\n discard,\n branchLabels,\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...parallelNode,\n displayName: computeDisplayName(parallelNode),\n semanticRole: computeSemanticRole(parallelNode),\n };\n });\n\nconst analyzeRaceCall = (\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticRaceNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n const children: StaticFlowNode[] = [];\n\n for (const arg of args) {\n if (arg) {\n const analyzed = yield* 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\nconst analyzeErrorHandlerCall = (\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticErrorHandlerNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n\n let handlerType: StaticErrorHandlerNode['handlerType'];\n if (callee.includes('catchAllCause')) {\n handlerType = 'catchAllCause';\n } else if (callee.includes('catchSomeCause')) {\n handlerType = 'catchSomeCause';\n } else if (callee.includes('catchSomeDefect')) {\n handlerType = 'catchSomeDefect';\n } else if (callee.includes('catchAllDefect')) {\n handlerType = 'catchAllDefect';\n } else if (callee.includes('catchTags')) {\n handlerType = 'catchTags';\n } else if (callee.includes('catchIf')) {\n handlerType = 'catchIf';\n } else if (callee.includes('catchSome')) {\n handlerType = 'catchSome';\n } else if (callee.includes('catchTag')) {\n handlerType = 'catchTag';\n } else if (callee.includes('catchAll')) {\n handlerType = 'catchAll';\n } else if (callee.includes('orElseFail')) {\n handlerType = 'orElseFail';\n } else if (callee.includes('orElseSucceed')) {\n handlerType = 'orElseSucceed';\n } else if (callee.includes('orElse')) {\n handlerType = 'orElse';\n } else if (callee.includes('orDieWith')) {\n handlerType = 'orDieWith';\n } else if (callee.includes('orDie')) {\n handlerType = 'orDie';\n } else if (callee.includes('flip')) {\n handlerType = 'flip';\n } else if (callee.includes('mapErrorCause')) {\n handlerType = 'mapErrorCause';\n } else if (callee.includes('mapBoth')) {\n handlerType = 'mapBoth';\n } else if (callee.includes('mapError')) {\n handlerType = 'mapError';\n } else if (callee.includes('unsandbox')) {\n handlerType = 'unsandbox';\n } else if (callee.includes('sandbox')) {\n handlerType = 'sandbox';\n } else if (callee.includes('parallelErrors')) {\n handlerType = 'parallelErrors';\n } else if (callee.includes('filterOrDieMessage')) {\n handlerType = 'filterOrDieMessage';\n } else if (callee.includes('filterOrDie')) {\n handlerType = 'filterOrDie';\n } else if (callee.includes('filterOrElse')) {\n handlerType = 'filterOrElse';\n } else if (callee.includes('filterOrFail')) {\n handlerType = 'filterOrFail';\n } else if (callee.includes('matchCauseEffect')) {\n handlerType = 'matchCauseEffect';\n } else if (callee.includes('matchCause')) {\n handlerType = 'matchCause';\n } else if (callee.includes('matchEffect')) {\n handlerType = 'matchEffect';\n } else if (callee.includes('match')) {\n handlerType = 'match';\n } else if (callee.includes('firstSuccessOf')) {\n handlerType = 'firstSuccessOf';\n } else if (callee.includes('ignoreLogged')) {\n handlerType = 'ignoreLogged';\n } else if (callee.includes('ignore')) {\n handlerType = 'ignore';\n } else if (callee.includes('eventually')) {\n handlerType = 'eventually';\n } else {\n handlerType = 'catchAll';\n }\n\n // For methods that are called as effect.pipe(Effect.catchAll(handler))\n // we need to find the source effect differently\n let source: StaticFlowNode;\n let handler: StaticFlowNode | undefined;\n\n // Check if this is a method call on an effect (e.g., effect.catchAll(fn))\n const expr = call.getExpression();\n if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n // This is effect.method() - the source is the object of the property access\n const propAccess = expr as PropertyAccessExpression;\n const exprSource = propAccess.getExpression();\n source = yield* analyzeEffectExpression(\n exprSource,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n\n // Handler is the first argument\n if (args.length > 0 && args[0]) {\n handler = yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n } else {\n // This is Effect.method(effect, handler) - effect is first argument\n if (args.length > 0 && args[0]) {\n source = yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n } else {\n source = {\n id: generateId(),\n type: 'unknown',\n reason: 'Could not determine source effect',\n };\n }\n\n if (args.length > 1 && args[1]) {\n handler = yield* analyzeEffectExpression(\n args[1],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n }\n\n stats.errorHandlerCount++;\n\n // For catchTags (object form), extract the tag keys from the object literal\n let errorTag: string | undefined;\n let errorTags: readonly string[] | undefined;\n if (handlerType === 'catchTag') {\n // catchTag(\"TagName\", handler) — first arg is the tag string\n const tagArg = args[0];\n if (tagArg?.getKind() === loadTsMorph().SyntaxKind.StringLiteral) {\n errorTag = (tagArg as StringLiteral).getLiteralValue();\n }\n } else if (handlerType === 'catchTags') {\n // catchTags({ NotFound: handler, DatabaseError: handler })\n // Find the object literal arg (may be args[0] for Effect.catchTags(eff, obj) or handler arg)\n const objArg = [...args].find(\n (a) => a?.getKind() === loadTsMorph().SyntaxKind.ObjectLiteralExpression,\n );\n if (objArg) {\n const props = (objArg as ObjectLiteralExpression).getProperties();\n errorTags = props\n .filter((p) => p.getKind() === loadTsMorph().SyntaxKind.PropertyAssignment || p.getKind() === loadTsMorph().SyntaxKind.MethodDeclaration)\n .map((p) => {\n if (p.getKind() === loadTsMorph().SyntaxKind.PropertyAssignment) {\n return (p as PropertyAssignment).getName();\n }\n return (p as MethodDeclaration).getName();\n });\n }\n }\n\n const handlerNode: StaticErrorHandlerNode = {\n id: generateId(),\n type: 'error-handler',\n handlerType,\n source,\n handler,\n errorTag,\n errorTags,\n errorEdgeLabel: errorTag ? `on ${errorTag}` : errorTags && errorTags.length > 0 ? `on ${errorTags.join(' | ')}` : '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\nconst analyzeRetryCall = (\n call: CallExpression,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticRetryNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n let source: StaticFlowNode;\n let schedule: string | undefined;\n let scheduleNode: StaticFlowNode | undefined;\n let hasFallback: boolean;\n\n // Similar logic to error handlers for determining source\n const expr = call.getExpression();\n if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n const propAccess = expr as PropertyAccessExpression;\n const exprSource = propAccess.getExpression();\n source = yield* analyzeEffectExpression(\n exprSource,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n\n if (args.length > 0 && args[0]) {\n schedule = args[0].getText();\n scheduleNode = yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n hasFallback = expr.getText().includes('retryOrElse');\n } else {\n if (args.length > 0 && args[0]) {\n source = yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n } else {\n source = {\n id: generateId(),\n type: 'unknown',\n reason: 'Could not determine source effect',\n };\n }\n\n if (args.length > 1 && args[1]) {\n schedule = args[1].getText();\n scheduleNode = yield* analyzeEffectExpression(\n args[1],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n }\n\n hasFallback = args.length > 2;\n }\n\n stats.retryCount++;\n\n const scheduleInfo = schedule ? parseScheduleInfo(schedule) : undefined;\n\n const retryNode: StaticRetryNode = {\n id: generateId(),\n type: 'retry',\n source,\n schedule,\n ...(scheduleNode !== undefined ? { scheduleNode } : {}),\n hasFallback,\n scheduleInfo,\n retryEdgeLabel: schedule ? `retry: ${schedule}` : 'retry',\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...retryNode,\n displayName: computeDisplayName(retryNode),\n semanticRole: computeSemanticRole(retryNode),\n };\n });\n\n/** Parse schedule expression text into ScheduleInfo (GAP 8). */\nfunction parseScheduleInfo(scheduleText: string): ScheduleInfo | undefined {\n const t = scheduleText.replace(/\\s+/g, ' ');\n let baseStrategy: ScheduleInfo['baseStrategy'] = 'custom';\n if (t.includes('Schedule.exponential') || t.includes('exponential(')) baseStrategy = 'exponential';\n else if (t.includes('Schedule.fibonacci') || t.includes('fibonacci(')) baseStrategy = 'fibonacci';\n else if (t.includes('Schedule.spaced') || t.includes('spaced(')) baseStrategy = 'spaced';\n else if (t.includes('Schedule.fixed') || t.includes('fixed(')) baseStrategy = 'fixed';\n else if (t.includes('Schedule.linear') || t.includes('linear(')) baseStrategy = 'linear';\n else if (t.includes('Schedule.cron') || t.includes('cron(')) baseStrategy = 'cron';\n else if (t.includes('Schedule.windowed') || t.includes('windowed(')) baseStrategy = 'windowed';\n else if (t.includes('Schedule.duration') || t.includes('duration(')) baseStrategy = 'duration';\n else if (t.includes('Schedule.elapsed') || t.includes('elapsed(')) baseStrategy = 'elapsed';\n else if (t.includes('Schedule.delays') || t.includes('delays(')) baseStrategy = 'delays';\n else if (t.includes('Schedule.once') || t.includes('once(')) baseStrategy = 'once';\n else if (t.includes('Schedule.stop') || t.includes('stop(')) baseStrategy = 'stop';\n else if (t.includes('Schedule.count') || t.includes('count(')) baseStrategy = 'count';\n\n let maxRetries: number | 'unlimited' | undefined;\n const recursMatch = /recurs\\s*\\(\\s*(\\d+)\\s*\\)/.exec(t);\n if (recursMatch) maxRetries = Number.parseInt(recursMatch[1]!, 10);\n const recurUpToMatch = /recurUpTo\\s*\\(\\s*(\\d+)\\s*\\)/.exec(t);\n if (recurUpToMatch) maxRetries = Number.parseInt(recurUpToMatch[1]!, 10);\n else if (t.includes('forever') || t.includes('Schedule.forever')) maxRetries = 'unlimited';\n\n const jittered = t.includes('jittered') || t.includes('Schedule.jittered');\n const conditions: string[] = [];\n if (t.includes('whileInput')) conditions.push('whileInput');\n if (t.includes('whileOutput')) conditions.push('whileOutput');\n if (t.includes('untilInput')) conditions.push('untilInput');\n if (t.includes('untilOutput')) conditions.push('untilOutput');\n if (t.includes('recurUntil')) conditions.push('recurUntil');\n if (t.includes('recurWhile')) conditions.push('recurWhile');\n if (t.includes('andThen')) conditions.push('andThen');\n if (t.includes('intersect')) conditions.push('intersect');\n if (t.includes('union')) conditions.push('union');\n if (t.includes('compose')) conditions.push('compose');\n if (t.includes('zipWith')) conditions.push('zipWith');\n if (t.includes('addDelay')) conditions.push('addDelay');\n if (t.includes('modifyDelay')) conditions.push('modifyDelay');\n if (t.includes('check')) conditions.push('check');\n if (t.includes('resetAfter')) conditions.push('resetAfter');\n if (t.includes('resetWhen')) conditions.push('resetWhen');\n if (t.includes('ensure')) conditions.push('ensure');\n if (t.includes('driver')) conditions.push('driver');\n if (t.includes('mapInput')) conditions.push('mapInput');\n\n return {\n baseStrategy,\n maxRetries,\n jittered,\n conditions,\n };\n}\n\nconst analyzeTimeoutCall = (\n call: CallExpression,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticTimeoutNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n let source: StaticFlowNode;\n let duration: string | undefined;\n let hasFallback: boolean;\n\n const expr = call.getExpression();\n if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n const propAccess = expr as PropertyAccessExpression;\n const exprSource = propAccess.getExpression();\n source = yield* analyzeEffectExpression(\n exprSource,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n\n if (args.length > 0 && args[0]) {\n duration = getNodeText(args[0]);\n }\n\n const exprText = getNodeText(expr);\n hasFallback =\n exprText.includes('timeoutFail') ||\n exprText.includes('timeoutTo');\n } else {\n if (args.length > 0 && args[0]) {\n source = yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n } else {\n source = {\n id: generateId(),\n type: 'unknown',\n reason: 'Could not determine source effect',\n };\n }\n\n if (args.length > 1 && args[1]) {\n duration = getNodeText(args[1]);\n }\n\n hasFallback = args.length > 2;\n }\n\n stats.timeoutCount++;\n\n const timeoutNode: StaticTimeoutNode = {\n id: generateId(),\n type: 'timeout',\n source,\n duration,\n hasFallback,\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...timeoutNode,\n displayName: computeDisplayName(timeoutNode),\n semanticRole: computeSemanticRole(timeoutNode),\n };\n });\n\nconst analyzeResourceCall = (\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticResourceNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n const resourceOperation = (/([A-Za-z_$][\\w$]*)$/.exec(callee))?.[1] ?? callee;\n let acquire: StaticFlowNode;\n let release: StaticFlowNode;\n let useEffect: StaticFlowNode | undefined;\n\n if (resourceOperation.startsWith('acquireUseRelease')) {\n // acquireUseRelease / acquireUseReleaseInterruptible (acquire, use, release) — 3-arg form\n if (args.length >= 3 && args[0] && args[2]) {\n acquire = yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n release = yield* analyzeEffectExpression(\n args[2],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n if (args[1]) {\n useEffect = yield* 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* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n release = yield* analyzeEffectExpression(\n args[1],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n } else {\n acquire = {\n id: generateId(),\n type: 'unknown',\n reason: 'Missing acquire',\n };\n release = {\n id: generateId(),\n type: 'unknown',\n reason: 'Missing release',\n };\n }\n } else if (\n resourceOperation === 'addFinalizer' ||\n resourceOperation === 'onExit' ||\n resourceOperation === 'onError' ||\n resourceOperation === 'parallelFinalizers' ||\n resourceOperation === 'sequentialFinalizers' ||\n resourceOperation === 'finalizersMask' ||\n resourceOperation === 'using' ||\n resourceOperation === 'withEarlyRelease'\n ) {\n // Finalizer/cleanup patterns — acquire is the surrounding effect (method chain) or unknown\n const expr = call.getExpression();\n if (expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression) {\n const propAccess = expr as PropertyAccessExpression;\n acquire = yield* 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* analyzeEffectExpression(args[0], sourceFile, filePath, opts, warnings, stats)\n : { id: generateId(), type: 'unknown', reason: 'Missing finalizer' };\n } else if (resourceOperation === 'ensuring') {\n // Effect.ensuring(effect, cleanup)\n const expr = call.getExpression();\n if (\n expr.getKind() === loadTsMorph().SyntaxKind.PropertyAccessExpression\n ) {\n const propAccess = expr as PropertyAccessExpression;\n const exprSource = propAccess.getExpression();\n acquire = yield* analyzeEffectExpression(\n exprSource,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n release =\n args.length > 0 && args[0]\n ? yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n )\n : { id: generateId(), type: 'unknown', reason: 'Missing cleanup' };\n } else {\n acquire =\n args.length > 0 && args[0]\n ? yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n )\n : { id: generateId(), type: 'unknown', reason: 'Missing effect' };\n release =\n args.length > 1 && args[1]\n ? yield* analyzeEffectExpression(\n args[1],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n )\n : { id: generateId(), type: 'unknown', reason: 'Missing cleanup' };\n }\n } else {\n acquire = {\n id: generateId(),\n type: 'unknown',\n reason: 'Unknown resource pattern',\n };\n release = {\n id: generateId(),\n type: 'unknown',\n reason: 'Unknown resource pattern',\n };\n }\n\n stats.resourceCount++;\n\n const resourceNode: StaticResourceNode = {\n id: generateId(),\n type: 'resource',\n acquire,\n release,\n use: useEffect,\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...resourceNode,\n displayName: computeDisplayName(resourceNode),\n semanticRole: computeSemanticRole(resourceNode),\n };\n });\n\nconst analyzeConditionalCall = (\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticConditionalNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n\n let conditionalType: StaticConditionalNode['conditionalType'];\n if (callee.includes('.if') || callee === 'if') {\n conditionalType = 'if';\n } else if (callee.includes('whenEffect')) {\n conditionalType = 'whenEffect';\n } else if (callee.includes('whenFiberRef')) {\n conditionalType = 'whenFiberRef';\n } else if (callee.includes('whenRef')) {\n conditionalType = 'whenRef';\n } else if (callee.includes('.when') || callee === 'when') {\n conditionalType = 'when';\n } else if (callee.includes('unlessEffect')) {\n conditionalType = 'unlessEffect';\n } else if (callee.includes('.unless') || callee === 'unless') {\n conditionalType = 'unless';\n } else if (callee.includes('.option') || callee === 'option') {\n conditionalType = 'option';\n } else if (callee.includes('.either') || callee === 'either') {\n conditionalType = 'either';\n } else if (callee.includes('.exit') || callee === 'exit') {\n conditionalType = 'exit';\n } else if (callee.includes('liftPredicate')) {\n conditionalType = 'liftPredicate';\n } else {\n conditionalType = 'unless';\n }\n\n let condition = '<dynamic>';\n let onTrue: StaticFlowNode | undefined;\n let onFalse: StaticFlowNode | undefined;\n\n // Different call patterns for if vs when/unless\n if (conditionalType === 'if') {\n // Effect.if(condition, { onTrue, onFalse })\n if (args.length > 0 && args[0]) {\n condition = args[0].getText();\n }\n\n if (args.length > 1 && args[1]) {\n const secondArg = args[1];\n const { SyntaxKind } = loadTsMorph();\n\n if (secondArg.getKind() === SyntaxKind.ObjectLiteralExpression) {\n const props = (\n secondArg as ObjectLiteralExpression\n ).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* analyzeEffectExpression(\n init,\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n } else if (name === 'onFalse') {\n onFalse = yield* 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* 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\nconst analyzeLoopCall = (\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticLoopNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n\n const loopType: StaticLoopNode['loopType'] =\n callee.includes('forEach') ? 'forEach' :\n callee.includes('filterMap') ? 'filterMap' :\n callee.includes('filter') ? 'filter' :\n callee.includes('partition') ? 'partition' :\n callee.includes('reduce') ? 'reduce' :\n callee.includes('validateAll') || callee.includes('validateFirst') || callee.includes('validateWith') ? 'validate' :\n callee.includes('replicate') ? 'replicate' :\n callee.includes('dropUntil') ? 'dropUntil' :\n callee.includes('dropWhile') ? 'dropWhile' :\n callee.includes('takeUntil') ? 'takeUntil' :\n callee.includes('takeWhile') ? 'takeWhile' :\n callee.includes('every') ? 'every' :\n callee.includes('exists') ? 'exists' :\n callee.includes('findFirst') ? 'findFirst' :\n callee.includes('head') ? 'head' :\n callee.includes('mergeAll') ? 'mergeAll' :\n 'loop';\n\n // reduce/reduceRight/reduceEffect(iterable, initial, reducer) use body at index 2; others (forEach, filter, ...) at index 1\n const bodyArgIndex =\n loopType === 'reduce' ||\n callee.includes('reduceRight') ||\n callee.includes('reduceWhile') ||\n callee.includes('reduceEffect')\n ? 2\n : 1;\n\n let iterSource: string | undefined;\n let body: StaticFlowNode;\n\n if (args.length > 0 && args[0]) {\n iterSource = args[0].getText();\n }\n\n if (args.length > bodyArgIndex && args[bodyArgIndex]) {\n body = yield* analyzeEffectExpression(\n args[bodyArgIndex],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n } else {\n body = {\n id: generateId(),\n type: 'unknown',\n reason: 'Could not determine loop body',\n };\n }\n\n stats.loopCount++;\n\n const loopNode: StaticLoopNode = {\n id: generateId(),\n type: 'loop',\n loopType,\n iterSource,\n body,\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. */\nconst analyzeMatchCall = (\n call: CallExpression,\n callee: string,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n): StaticMatchNode => {\n const matchOp: StaticMatchNode['matchOp'] = MATCH_OP_MAP[callee] ?? 'other';\n const isExhaustive = EXHAUSTIVE_OPS.has(matchOp);\n\n // Extract tag names for Match.tag(tag, fn), Match.tags({ tag1: fn, tag2: fn })\n const args = call.getArguments();\n const matchedTags: string[] = [];\n if ((matchOp === 'when' || matchOp === 'tag') && args[0]) {\n const arg0 = args[0].getText().replace(/[\"'`]/g, '').trim();\n if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(arg0)) matchedTags.push(arg0);\n }\n if (matchOp === 'tags' || matchOp === 'tagsExhaustive') {\n const { SyntaxKind } = loadTsMorph();\n for (const arg of args) {\n if (arg.getKind() === SyntaxKind.ObjectLiteralExpression) {\n const obj = arg as ObjectLiteralExpression;\n for (const prop of obj.getProperties()) {\n const name = prop.getKind() === SyntaxKind.PropertyAssignment\n ? (prop as PropertyAssignment).getName()\n : undefined;\n if (name) matchedTags.push(name.replace(/[\"'`]/g, ''));\n }\n }\n }\n }\n\n const matchNode: StaticMatchNode = {\n id: generateId(),\n type: 'match',\n matchOp,\n isExhaustive,\n ...(matchedTags.length > 0 ? { matchedTags } : {}),\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...matchNode,\n displayName: computeDisplayName(matchNode),\n semanticRole: computeSemanticRole(matchNode),\n };\n};\n\n/** Analyze Cause.fail / die / interrupt / parallel / sequential / failures / etc. */\nconst analyzeCauseCall = (\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticCauseNode, AnalysisError> =>\n Effect.gen(function* () {\n const causeOp: StaticCauseNode['causeOp'] = CAUSE_OP_MAP[callee] ?? 'other';\n const isConstructor = CAUSE_CONSTRUCTORS.has(causeOp);\n let children: readonly StaticFlowNode[] | undefined;\n if (causeOp === 'parallel' || causeOp === 'sequential') {\n const args = call.getArguments();\n const childNodes: StaticFlowNode[] = [];\n for (const arg of args) {\n if (arg) {\n const child = yield* 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. */\nconst 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 Schedule.exponential / spaced / jittered / andThen / etc. (GAP 8 dedicated IR). */\nconst analyzeScheduleCall = (\n call: CallExpression,\n callee: string,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n): Effect.Effect<StaticScheduleNode, AnalysisError> =>\n Effect.sync(() => {\n const scheduleOp: StaticScheduleNode['scheduleOp'] =\n SCHEDULE_OP_MAP[callee] ?? 'other';\n const scheduleText = call.getText();\n const scheduleInfo = parseScheduleInfo(scheduleText);\n const scheduleNode: StaticScheduleNode = {\n id: generateId(),\n type: 'schedule',\n scheduleOp,\n ...(scheduleInfo ? { scheduleInfo } : {}),\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...scheduleNode,\n displayName: computeDisplayName(scheduleNode),\n semanticRole: computeSemanticRole(scheduleNode),\n };\n });\n\n/** Analyze Effect.map / flatMap / andThen / tap / zip / as / flatten etc. */\nconst analyzeTransformCall = (\n call: CallExpression,\n callee: string,\n sourceFile: SourceFile,\n filePath: string,\n opts: Required<AnalyzerOptions>,\n warnings: AnalysisWarning[],\n stats: AnalysisStats,\n): Effect.Effect<StaticTransformNode, AnalysisError> =>\n Effect.gen(function* () {\n const args = call.getArguments();\n const transformType: StaticTransformNode['transformType'] =\n TRANSFORM_OPS[callee] ?? 'other';\n const isEffectful = EFFECTFUL_TRANSFORMS.has(transformType);\n\n // For data-last forms (2 args), first arg is the source\n // For curried forms (1 arg), the source is from the outer pipe\n let source: StaticFlowNode | undefined;\n let fn: string | undefined;\n\n if (args.length >= 2 && args[0]) {\n source = yield* analyzeEffectExpression(\n args[0],\n sourceFile,\n filePath,\n opts,\n warnings,\n stats,\n );\n if (args[1]) {\n const fnText = args[1].getText();\n fn = fnText.length <= 120 ? fnText : fnText.slice(0, 120) + '…';\n }\n } else if (args.length === 1 && args[0]) {\n // Curried — single arg is the function\n const fnText = args[0].getText();\n fn = fnText.length <= 120 ? fnText : fnText.slice(0, 120) + '…';\n }\n\n stats.totalEffects++;\n\n const transformNode: StaticTransformNode = {\n id: generateId(),\n type: 'transform',\n transformType,\n isEffectful,\n ...(source !== undefined ? { source } : {}),\n ...(fn !== undefined ? { fn } : {}),\n location: extractLocation(call, filePath, opts.includeLocations ?? false),\n };\n return {\n ...transformNode,\n displayName: computeDisplayName(transformNode),\n semanticRole: computeSemanticRole(transformNode),\n } satisfies StaticTransformNode;\n });\n","/**\n * Project-wide / Cross-file Analysis (GAP 17)\n *\n * Analyzes a directory of TypeScript files and aggregates results.\n */\n\nimport { Effect, Option } from 'effect';\nimport { readdir, readFile, stat } from 'fs/promises';\nimport { readFileSync } from 'fs';\nimport { join, extname, resolve, basename } from 'path';\nimport type { StaticEffectIR, StaticFlowNode, ProjectServiceMap } from './types';\nimport { getStaticChildren, isStaticUnknownNode } from './types';\nimport { analyze } from './analyze';\nimport { loadTsMorph } from './ts-morph-loader';\nimport { buildProjectServiceMap } from './service-registry';\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, readonly StaticEffectIR[]>;\n /** All programs across the project */\n readonly allPrograms: readonly StaticEffectIR[];\n /** Entry points (files that run Effect.runPromise / runSync / NodeRuntime.runMain) - heuristic + package.json */\n readonly entryPointFiles: string[];\n /** Total file count discovered */\n readonly fileCount: number;\n /** Files that failed to analyze (error message included) - Gap 3 */\n readonly failedFiles: readonly ProjectFileFailure[];\n /** Files that were analyzed but had zero Effect programs */\n readonly zeroProgramFiles: readonly string[];\n /** Project-level deduplicated service map (when --service-map is enabled) */\n readonly serviceMap?: ProjectServiceMap | 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?: readonly 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?: readonly 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}\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\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: readonly FileOutcome[];\n readonly percentage: number;\n /** analyzed / (analyzed + failed) * 100 — excludes zero-program files (correct classification). */\n readonly analyzableCoverage: number;\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 /** Files that import from effect/@effect but produced zero programs. */\n readonly suspiciousZeros: readonly 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: readonly ZeroProgramClassification[];\n /** Top N files by unknown node rate (highest first), for --show-top-unknown. */\n readonly topUnknownFiles?: readonly 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?: readonly { 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};\n\n\n\n// =============================================================================\n// Precision metric helpers\n// =============================================================================\n\nfunction countNodes(nodes: readonly StaticFlowNode[]): { total: number; unknown: number } {\n let total = 0;\n let unknown = 0;\n const visit = (list: readonly StaticFlowNode[]) => {\n for (const node of list) {\n total++;\n if (node.type === 'unknown') unknown++;\n const children = Option.getOrElse(getStaticChildren(node), () => [] as readonly StaticFlowNode[]);\n if (children.length > 0) visit(children);\n }\n };\n visit(nodes);\n return { total, unknown };\n}\n\n/** Aggregate unknown node counts by reason. */\nfunction countUnknownReasons(nodes: readonly StaticFlowNode[]): Map<string, number> {\n const byReason = new Map<string, number>();\n const visit = (list: readonly StaticFlowNode[]) => {\n for (const node of list) {\n if (isStaticUnknownNode(node)) {\n const r = node.reason;\n byReason.set(r, (byReason.get(r) ?? 0) + 1);\n }\n const children = Option.getOrElse(getStaticChildren(node), () => [] as readonly StaticFlowNode[]);\n if (children.length > 0) visit(children);\n }\n };\n visit(nodes);\n return byReason;\n}\n\nfunction fileImportsEffect(filePath: string): boolean {\n try {\n const content = readFileSync(filePath, 'utf-8');\n return /from\\s+[\"'](?:effect|effect\\/|@effect\\/)/.test(content);\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 =\n /\\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 detectExpectedZeroCategory(filePath: string): 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$/.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// Discovery\n// =============================================================================\n\nasync function findTsFiles(\n dir: string,\n extensions: readonly string[],\n maxDepth: number,\n currentDepth: number,\n): Promise<string[]> {\n if (currentDepth >= maxDepth) return [];\n const result: string[] = [];\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n for (const ent of entries) {\n const full = join(dir, ent.name);\n if (ent.isDirectory()) {\n if (ent.name !== 'node_modules' && ent.name !== '.git') {\n result.push(...(await findTsFiles(full, extensions, maxDepth, currentDepth + 1)));\n }\n } else if (ent.isFile() && extensions.includes(extname(ent.name))) {\n result.push(full);\n }\n }\n } catch {\n // ignore permission errors etc.\n }\n return result;\n}\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<string[]> {\n if (currentDepth >= maxDepth) return [];\n const result: 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: readonly string[],\n): 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: readonly string[],\n): Promise<string[]> {\n const pkgDirs = await findPackageJsonDirs(dirPath, 10, 0);\n const entryPaths: 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)) dirs.push(resolveEntry(pkgDir, typeof v === 'string' ? v : undefined, extensions));\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 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 Effect.gen(function* () {\n const files = yield* Effect.promise(() =>\n findTsFiles(dirPath, extensions, maxDepth, 0),\n );\n const byFile = new Map<string, readonly StaticEffectIR[]>();\n const allPrograms: StaticEffectIR[] = [];\n const entryPointFiles: string[] = [];\n const failedFiles: ProjectFileFailure[] = [];\n const zeroProgramFiles: string[] = [];\n\n for (const file of files) {\n const result = yield* analyze(file, {\n tsConfigPath: options.tsconfig,\n knownEffectInternalsRoot: options.knownEffectInternalsRoot,\n })\n .all()\n .pipe(\n Effect.map((programs) => ({ _tag: 'ok' as const, programs })),\n Effect.catchAll((err) =>\n Effect.succeed({\n _tag: 'fail' as const,\n error: err instanceof Error ? err.message : String(err),\n }),\n ),\n );\n if (result._tag === 'fail') {\n failedFiles.push({ file, error: result.error });\n continue;\n }\n const programs = result.programs;\n if (programs.length === 0) {\n zeroProgramFiles.push(file);\n continue;\n }\n byFile.set(file, programs);\n allPrograms.push(...programs);\n for (const ir of programs) {\n const nameLikeEntry =\n 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(() =>\n getEntryPointsFromPackageJson(dirPath, extensions),\n );\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 try {\n const { Project } = loadTsMorph();\n const project = new Project({\n skipAddingFilesFromTsConfig: true,\n compilerOptions: { allowJs: true },\n });\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const sourceFileMap = new Map<string, any>();\n for (const file of byFile.keys()) {\n try {\n const sf = project.addSourceFileAtPath(file);\n sourceFileMap.set(file, sf);\n } catch {\n // skip files that can't be loaded\n }\n }\n serviceMap = buildProjectServiceMap(byFile, sourceFileMap);\n } catch {\n // Fall back to IR-only service map (no AST-level extraction)\n serviceMap = buildProjectServiceMap(byFile);\n }\n }\n\n return {\n byFile,\n allPrograms,\n entryPointFiles,\n fileCount: files.length,\n failedFiles,\n zeroProgramFiles,\n serviceMap,\n };\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 const extensions = (options.extensions ?? DEFAULT_OPTIONS.extensions)!;\n const maxDepth = (options.maxDepth ?? DEFAULT_OPTIONS.maxDepth)!;\n return Effect.gen(function* () {\n const startMs = Date.now();\n const files = yield* Effect.promise(() =>\n findTsFiles(dirPath, extensions, maxDepth, 0),\n );\n const outcomes: FileOutcome[] = [];\n let totalNodes = 0;\n let unknownNodes = 0;\n const fileUnknownRates: { file: string; total: number; unknown: number }[] = [];\n const unknownReasonsCorpus = new Map<string, number>();\n\n const includePerFileTiming = options.includePerFileTiming === true;\n for (const file of files) {\n const fileStartMs = includePerFileTiming ? Date.now() : 0;\n const result = yield* analyze(file, {\n tsConfigPath: options.tsconfig,\n knownEffectInternalsRoot: options.knownEffectInternalsRoot,\n })\n .all()\n .pipe(\n Effect.map((programs) => ({ _tag: 'ok' as const, programs })),\n Effect.catchAll((err) =>\n Effect.succeed({\n _tag: 'fail' as const,\n error: err instanceof Error ? err.message : String(err),\n }),\n ),\n );\n const durationMs = includePerFileTiming ? Date.now() - fileStartMs : undefined;\n if (result._tag === 'ok') {\n const count = result.programs.length;\n let fileTotal = 0;\n let fileUnknown = 0;\n for (const ir of result.programs) {\n const counts = countNodes(ir.root.children);\n totalNodes += counts.total;\n unknownNodes += counts.unknown;\n fileTotal += counts.total;\n fileUnknown += counts.unknown;\n const reasonCounts = countUnknownReasons(ir.root.children);\n for (const [reason, n] of reasonCounts) {\n unknownReasonsCorpus.set(reason, (unknownReasonsCorpus.get(reason) ?? 0) + 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 const msg = result.error ?? '';\n const isZeroPrograms =\n msg.includes('No Effect programs found') || msg.includes('NO_EFFECTS_FOUND');\n outcomes.push(\n isZeroPrograms\n ? { file, status: 'zero', programCount: 0, ...(durationMs !== undefined ? { durationMs } : {}) }\n : { file, status: 'fail', error: result.error, ...(durationMs !== undefined ? { durationMs } : {}) },\n );\n }\n }\n\n const discovered = 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 percentage = discovered > 0 ? (analyzed / discovered) * 100 : 0;\n const analyzableCoverage = (analyzed + failed) > 0\n ? (analyzed / (analyzed + failed)) * 100\n : 100;\n\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: string[] = [];\n const zeroProgramClassifications: 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 =\n importsEffect && !isExcludedFromSuspicious(o.file) && expectedCategory === undefined\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 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 = Date.now() - startMs;\n return {\n discovered,\n analyzed,\n zeroPrograms,\n failed,\n outcomes,\n percentage,\n analyzableCoverage,\n unknownNodeRate,\n totalNodes,\n unknownNodes,\n suspiciousZeros,\n zeroProgramCategoryCounts,\n zeroProgramClassifications,\n topUnknownFiles,\n unknownReasonCounts,\n topUnknownReasons,\n durationMs,\n };\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 type {\n StaticEffectIR,\n ServiceArtifact,\n LayerImplementation,\n ServiceConsumerRef,\n ProjectServiceMap,\n ServiceDefinition,\n SourceLocation,\n StaticFlowNode,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\nimport { loadTsMorph } from './ts-morph-loader';\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(): TsMorphSymbol[];\n getCallSignatures(): 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(): TsMorphNode[];\n getArguments?(): TsMorphNode[];\n getInitializer(): TsMorphNode | undefined;\n}\n\ninterface TsMorphSourceFile {\n getDescendantsOfKind(kind: number): 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): ServiceTagInfo[] {\n const { SyntaxKind } = loadTsMorph();\n const results: 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 (!extText.includes('Context.Tag') && !extText.includes('Effect.Service')) 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 }\n\n // Get type arguments for interface shape\n let typeArgs: readonly TsMorphNode[] = extExpr.getTypeArguments();\n if (typeArgs.length < 2) {\n const inner = extExpr.getExpression();\n if (inner && 'getTypeArguments' in inner && typeof inner.getTypeArguments === 'function') {\n typeArgs = inner.getTypeArguments();\n }\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: string[] = [];\n const properties: string[] = [];\n for (const sym of type.getProperties()) {\n const propName = sym.getName();\n if (propName.startsWith('_') || propName === 'constructor') continue;\n const propType = typeChecker.getTypeOfSymbolAtLocation(sym, interfaceTypeNode);\n const callSigs = propType.getCallSignatures();\n if (callSigs.length > 0) methods.push(propName);\n else properties.push(propName);\n }\n 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): { readonly providesServiceId: string; readonly implementation: LayerImplementation }[] {\n const { SyntaxKind } = loadTsMorph();\n const results: { 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 as number)) {\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: 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, readonly StaticEffectIR[]>,\n): Map<string, ServiceConsumerRef[]> {\n const consumers = new Map<string, 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: readonly StaticFlowNode[],\n programName: string,\n filePath: string,\n consumers: Map<string, 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): string[] {\n const result: 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: readonly LayerImplementation[],\n allLayersByService: ReadonlyMap<string, readonly LayerImplementation[]>,\n visited = new Set<string>(),\n): string[] {\n const deps: 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, readonly 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, 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: 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: readonly StaticFlowNode[],\n filePath: string,\n knownServiceIds: ReadonlySet<string>,\n identifierToServiceId: ReadonlyMap<string, string>,\n layersByService: Map<string, 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 =\n identifierToServiceId.get(providedIdent) ??\n (knownServiceIds.has(providedIdent) ? providedIdent : undefined);\n if (canonical && knownServiceIds.has(canonical)) {\n const list = layersByService.get(canonical) ?? [];\n const requires =\n 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 * Migration Assistant (GAP 29)\n *\n * Detects patterns that could be migrated to Effect (try/catch, Promise.all, etc.).\n */\n\nimport { readdir } from 'node:fs/promises';\nimport { join, extname } from 'path';\nimport { Project, SyntaxKind } from 'ts-morph';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface MigrationOpportunity {\n readonly filePath: string;\n readonly line: number;\n readonly column: number;\n readonly pattern: string;\n readonly suggestion: string;\n readonly codeSnippet?: string | undefined;\n}\n\nexport interface MigrationReport {\n readonly opportunities: readonly MigrationOpportunity[];\n readonly fileCount: number;\n}\n\n// =============================================================================\n// Detection\n// =============================================================================\n\nfunction addOpportunity(\n list: MigrationOpportunity[],\n filePath: string,\n node: { getStart: () => number },\n sourceFile: { getLineAndColumnAtPos: (pos: number) => { line: number; column: number }; getText: () => string },\n pattern: string,\n suggestion: string,\n snippet?: string,\n): void {\n const { line, column } = sourceFile.getLineAndColumnAtPos(node.getStart());\n list.push({\n filePath,\n line: line + 1,\n column,\n pattern,\n suggestion,\n codeSnippet: snippet ?? sourceFile.getText().slice(node.getStart(), node.getStart() + 80).replace(/\\n/g, ' '),\n });\n}\n\n/**\n * Scan a file for migration opportunities.\n */\nexport function findMigrationOpportunities(\n filePath: string,\n source?: string,\n): MigrationOpportunity[] {\n const opportunities: MigrationOpportunity[] = [];\n const project = new Project({ skipAddingFilesFromTsConfig: true });\n const sourceFile = source\n ? project.createSourceFile(filePath, source)\n : project.addSourceFileAtPath(filePath);\n\n // try/catch -> Effect.try / Effect.tryPromise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.TryStatement)) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'try/catch',\n 'Effect.try or Effect.tryPromise with catch handler',\n );\n }\n\n // Promise.all -> Effect.all\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'Promise.all' || (text.endsWith('.all') && text.includes('Promise'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'Promise.all',\n 'Effect.all([...], { concurrency: \"unbounded\" })',\n );\n }\n if (text === 'Promise.race' || (text.endsWith('.race') && text.includes('Promise'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'Promise.race',\n 'Effect.race(first, second)',\n );\n }\n }\n\n // setTimeout / setInterval / setImmediate -> Effect.sleep / Schedule\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'setTimeout' || text === 'setInterval') {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n text,\n text === 'setTimeout' ? 'Effect.sleep(Duration.millis(n))' : 'Schedule.spaced(Duration.millis(n))',\n );\n }\n if (text === 'setImmediate' || text === 'process.setImmediate') {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'setImmediate',\n 'Effect.sync + queueMicrotask or Effect.async',\n );\n }\n }\n\n // XMLHttpRequest -> HttpClient\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'XMLHttpRequest' || text.includes('XMLHttpRequest')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new XMLHttpRequest()',\n 'HttpClient.request or @effect/platform HttpClient',\n );\n }\n }\n\n // Worker / worker_threads -> Effect Worker\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'Worker' || text.includes('Worker')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new Worker()',\n 'Worker.make or @effect/platform Worker',\n );\n }\n }\n\n // fs.exists (callback) -> Effect.promise (only fs module, not Option.exists / Exit.exists)\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isFsExists =\n text === 'fs.exists' ||\n (text.endsWith('.exists') && text.startsWith('fs.'));\n if (isFsExists && node.getArguments().length >= 2) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'fs.exists (callback)',\n 'Effect.promise or fs.promises.access',\n );\n }\n }\n\n // http.request / https.request (callback) -> HttpClient\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n (text.endsWith('.request') && (text.includes('http') || text.includes('https'))) ||\n (text === 'request' && sourceFile.getText().includes('http'))\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'http.request / https.request',\n 'HttpClient.request or @effect/platform HttpClient',\n );\n }\n }\n\n // dns.lookup, dns.resolve (callback) -> Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n (text.startsWith('dns.') || text.includes('dns.')) &&\n (text.includes('lookup') || text.includes('resolve') || text.includes('reverse'))\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'dns (callback)',\n 'Effect.promise or dns.promises',\n );\n }\n }\n\n // fetch( -> HttpClient\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'fetch') {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'fetch()',\n 'HttpClient.request or @effect/platform HttpClient',\n );\n }\n }\n\n // EventEmitter -> PubSub\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'EventEmitter' || text.includes('EventEmitter')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new EventEmitter()',\n 'PubSub.bounded<EventType>() or PubSub.unbounded<EventType>()',\n );\n }\n }\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n (text.endsWith('.on(') || text.endsWith('.addListener(')) &&\n (text.includes('Emitter') || text.includes('emitter'))\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'EventEmitter.on / addListener',\n 'PubSub.subscribe for PubSub',\n );\n }\n if (text.endsWith('.emit(') && (text.includes('Emitter') || text.includes('emitter'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'EventEmitter.emit',\n 'PubSub.publish for PubSub',\n );\n }\n }\n\n // class-based DI -> Context.Tag + Layer\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.ClassDeclaration)) {\n const name = node.getName();\n const text = node.getText();\n if (\n name &&\n (text.includes('new ') || text.includes('constructor')) &&\n (name.endsWith('Service') || name.endsWith('Repository') || name.endsWith('Client'))\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n `class ${name} (manual DI)`,\n `Context.Tag<${name}>() + Layer.effect or Layer.succeed`,\n );\n }\n }\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n (text.endsWith('Service') || text.endsWith('Repository') || text.endsWith('Client')) &&\n !text.includes('Context') &&\n !text.includes('Layer')\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n `new ${text}()`,\n `Context.Tag + Layer.effect for dependency injection`,\n );\n }\n }\n\n // async/await -> Effect\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration)) {\n if (node.getModifiers().some((m) => m.getText() === 'async') || node.getText().startsWith('async')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'async function',\n 'Effect.gen or Effect.pipe with flatMap',\n );\n }\n }\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction)) {\n if (node.getText().startsWith('async')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'async arrow function',\n 'Effect.gen or Effect.pipe with flatMap',\n );\n }\n }\n\n // Promise.then chains -> Effect.flatMap\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text.endsWith('.then') && text.includes('Promise')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'Promise.then',\n 'Effect.flatMap for sequential composition',\n );\n }\n if (text === 'Promise.allSettled' || (text.endsWith('.allSettled') && text.includes('Promise'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'Promise.allSettled',\n 'Effect.all with merge or separate error handling',\n );\n }\n if (text.endsWith('.catch') && (text.includes('Promise') || text.includes('.then'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'Promise.catch',\n 'Effect.catchAll or Effect.catchTag for typed error handling',\n );\n }\n if (text.endsWith('.finally') && (text.includes('Promise') || text.includes('.then'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'Promise.finally',\n 'Effect.ensuring for cleanup',\n );\n }\n }\n\n // addEventListener -> Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'addEventListener' || text.endsWith('.addEventListener')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'addEventListener',\n 'Effect.async or EventTarget + Effect.asyncInterrupt',\n );\n }\n }\n\n // fs.readFile / fs.writeFile (callback) -> Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isFsCallback =\n (text === 'fs.readFile' || text === 'fs.writeFile' || text === 'readFile' || text === 'writeFile') ||\n (text.endsWith('.readFile') && text.startsWith('fs.')) ||\n (text.endsWith('.writeFile') && text.startsWith('fs.'));\n if (isFsCallback && node.getArguments().length >= 2) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n text.includes('write') ? 'fs.writeFile (callback)' : 'fs.readFile (callback)',\n 'Effect.promise or fs.promises + Effect.tryPromise',\n );\n }\n }\n\n // throw new Error -> Effect.fail\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.ThrowStatement)) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'throw',\n 'Effect.fail(error) for typed error channel',\n );\n }\n\n // util.promisify -> Effect.tryPromise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'promisify' || text.endsWith('.promisify')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'util.promisify',\n 'Effect.tryPromise or Effect.async for callback-style APIs',\n );\n }\n }\n\n // new Promise -> Effect.async or Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'Promise') {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new Promise(...)',\n 'Effect.async or Effect.promise for callback-style',\n );\n }\n }\n\n // for await -> Stream.iterate or Effect.asyncIterable\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.ForOfStatement)) {\n if (node.getAwaitKeyword()) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'for await...of',\n 'Stream.iterate or Effect.asyncIterable for async iteration',\n );\n }\n }\n\n // sync fs (readFileSync, writeFileSync) -> Effect.promise + fs/promises\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n text === 'readFileSync' ||\n text === 'writeFileSync' ||\n text === 'existsSync' ||\n text.endsWith('.readFileSync') ||\n text.endsWith('.writeFileSync') ||\n text.endsWith('.existsSync')\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n text,\n 'Effect.promise or fs/promises + Effect.tryPromise',\n );\n }\n }\n\n // process.nextTick -> Effect.sync + queueMicrotask or Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'process.nextTick' || (text.endsWith('.nextTick') && text.includes('process'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'process.nextTick',\n 'Effect.sync + queueMicrotask or Effect.async',\n );\n }\n }\n\n // queueMicrotask -> Effect.sync\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'queueMicrotask' || text.endsWith('.queueMicrotask')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'queueMicrotask',\n 'Effect.sync for deferred execution',\n );\n }\n }\n\n // WebSocket -> Effect.async / @effect/platform\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'WebSocket' || text.includes('WebSocket')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new WebSocket()',\n 'Effect.async or @effect/platform WebSocket',\n );\n }\n }\n\n // MessageChannel -> Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'MessageChannel' || text.includes('MessageChannel')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new MessageChannel()',\n 'Effect.async or Queue for cross-context messaging',\n );\n }\n }\n\n // fs.appendFile (callback) -> Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isFsAppend =\n text === 'fs.appendFile' ||\n (text.endsWith('.appendFile') && text.startsWith('fs.'));\n if (isFsAppend && node.getArguments().length >= 2) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'fs.appendFile (callback)',\n 'Effect.promise or fs.promises.appendFile',\n );\n }\n }\n\n // fs.mkdir / fs.stat / fs.unlink (callback) -> Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isFsCallback =\n (text === 'fs.mkdir' || text === 'fs.stat' || text === 'fs.unlink' ||\n (text.endsWith('.mkdir') && text.startsWith('fs.')) ||\n (text.endsWith('.stat') && text.startsWith('fs.')) ||\n (text.endsWith('.unlink') && text.startsWith('fs.'))) &&\n node.getArguments().length >= 2;\n if (isFsCallback) {\n const name = text.includes('mkdir') ? 'fs.mkdir' : text.includes('stat') ? 'fs.stat' : 'fs.unlink';\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n `${name} (callback)`,\n 'Effect.promise or fs.promises',\n );\n }\n }\n\n // MutationObserver -> Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'MutationObserver' || text.includes('MutationObserver')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new MutationObserver()',\n 'Effect.async or Effect.asyncInterrupt for DOM observation',\n );\n }\n }\n\n // requestIdleCallback -> Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'requestIdleCallback' || text.endsWith('.requestIdleCallback')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'requestIdleCallback',\n 'Effect.async or Effect.sync for idle-time work',\n );\n }\n }\n\n // BroadcastChannel -> PubSub / Effect\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'BroadcastChannel' || text.includes('BroadcastChannel')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new BroadcastChannel()',\n 'PubSub or Effect.async for cross-tab messaging',\n );\n }\n }\n\n // fs.rename / fs.realpath (callback) -> Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isFsCallback =\n (text === 'fs.rename' || text === 'fs.realpath' ||\n (text.endsWith('.rename') && text.startsWith('fs.')) ||\n (text.endsWith('.realpath') && text.startsWith('fs.'))) &&\n node.getArguments().length >= 2;\n if (isFsCallback) {\n const name = text.includes('realpath') ? 'fs.realpath' : 'fs.rename';\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n `${name} (callback)`,\n 'Effect.promise or fs.promises',\n );\n }\n }\n\n // fs.readdir / fs.copyFile (callback) -> Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isFsReaddir =\n (text === 'fs.readdir' || (text.endsWith('.readdir') && text.startsWith('fs.'))) &&\n node.getArguments().length >= 2;\n const isFsCopyFile =\n (text === 'fs.copyFile' || (text.endsWith('.copyFile') && text.startsWith('fs.'))) &&\n node.getArguments().length >= 2;\n if (isFsReaddir) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'fs.readdir (callback)',\n 'Effect.promise or fs.promises.readdir',\n );\n }\n if (isFsCopyFile) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'fs.copyFile (callback)',\n 'Effect.promise or fs.promises.copyFile',\n );\n }\n }\n\n // FileReader (browser) -> Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'FileReader' || text.includes('FileReader')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new FileReader()',\n 'Effect.async or FileReader + Effect.asyncInterrupt',\n );\n }\n }\n\n // fs.mkdtemp / fs.symlink (callback) -> Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isFsMkdtemp =\n (text === 'fs.mkdtemp' || (text.endsWith('.mkdtemp') && text.startsWith('fs.'))) &&\n node.getArguments().length >= 2;\n const isFsSymlink =\n (text === 'fs.symlink' || (text.endsWith('.symlink') && text.startsWith('fs.'))) &&\n node.getArguments().length >= 2;\n if (isFsMkdtemp) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'fs.mkdtemp (callback)',\n 'Effect.promise or fs.promises.mkdtemp',\n );\n }\n if (isFsSymlink) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'fs.symlink (callback)',\n 'Effect.promise or fs.promises.symlink',\n );\n }\n }\n\n // ResizeObserver / IntersectionObserver -> Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n text === 'ResizeObserver' ||\n text === 'IntersectionObserver' ||\n text.includes('ResizeObserver') ||\n text.includes('IntersectionObserver')\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n `new ${text}()`,\n 'Effect.async or Effect.asyncInterrupt for DOM observation',\n );\n }\n }\n\n // child_process.fork -> Worker / Effect\n const hasChildProcessFork = sourceFile.getText().includes('child_process');\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n (text.includes('child_process') && text.endsWith('.fork')) ||\n (hasChildProcessFork && text === 'fork')\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'child_process.fork',\n 'Worker.make or @effect/platform Worker',\n );\n }\n }\n\n // AbortController -> Effect.Scoped\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'AbortController' || text.includes('AbortController')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'new AbortController()',\n 'Effect.Scoped or Effect.interruptible for cancellation',\n );\n }\n }\n\n // child_process.exec/spawn -> CommandExecutor\n const fileText = sourceFile.getText();\n const hasChildProcess = fileText.includes('child_process');\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isChildProcessExec =\n (text.endsWith('.exec') || text.endsWith('.execSync') || text.endsWith('.spawn')) &&\n text.includes('child_process');\n const isNamedImportExec =\n hasChildProcess && (text === 'exec' || text === 'execSync' || text === 'spawn');\n if (isChildProcessExec || isNamedImportExec) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'child_process.exec/spawn',\n '@effect/platform CommandExecutor or Effect.promise',\n );\n }\n }\n\n // process.env -> Config (only direct process.env to avoid duplicates)\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression)) {\n const expr = node.getExpression();\n if (expr.getText() === 'process' && node.getName() === 'env') {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'process.env',\n 'Config.string or Config.forEffect for typed config',\n );\n }\n }\n\n // RxJS Observable -> Stream\n const hasRxjs = fileText.includes('rxjs') || fileText.includes('Observable');\n if (hasRxjs) {\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text.includes('Observable') || (text.includes('of') && text.includes('rxjs'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'RxJS Observable',\n 'Stream from @effect/platform or Effect Stream',\n );\n }\n }\n }\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.NewExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text.includes('Observable') || text.includes('Subject')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'RxJS Observable/Subject',\n 'Stream or PubSub for Effect',\n );\n }\n }\n\n // requestAnimationFrame -> Effect.sync + queueMicrotask (browser)\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'requestAnimationFrame' || text.endsWith('.requestAnimationFrame')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'requestAnimationFrame',\n 'Effect.async or Effect.sync + queueMicrotask for scheduling',\n );\n }\n }\n\n // crypto (callback) -> Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n (text.includes('crypto.') || text.includes('randomBytes') || text.includes('scrypt') || text.includes('pbkdf2')) &&\n node.getArguments().length >= 2\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'crypto (callback)',\n 'Effect.promise or crypto.webcrypto / node:crypto promises',\n );\n }\n }\n\n // createReadStream / createWriteStream -> Stream\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'createReadStream' || text === 'createWriteStream' || text.endsWith('.createReadStream') || text.endsWith('.createWriteStream')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n text,\n 'Stream.fromReadable or @effect/platform FileSystem/Stream',\n );\n }\n }\n\n // cluster.fork -> Worker / Effect\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text.includes('cluster') && text.endsWith('.fork')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'cluster.fork',\n 'Worker.make or @effect/platform Worker pool',\n );\n }\n }\n\n // net.createServer / net.connect (callback) -> Effect\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'createServer' || text === 'connect' || text.endsWith('.createServer') || text.endsWith('.connect')) {\n const full = expr.getText();\n if (full.includes('net') || full.includes('tls')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n full,\n 'Effect.async or @effect/platform Socket/Server',\n );\n }\n }\n }\n\n // zlib (callback) -> Effect.promise\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text.includes('zlib.') && (text.includes('deflate') || text.includes('inflate') || text.includes('gzip') || text.includes('gunzip'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'zlib (callback)',\n 'Effect.promise or zlib.promises',\n );\n }\n }\n\n // readline.createInterface -> Effect.async / Stream\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'createInterface' || text.endsWith('.createInterface')) {\n if (text.includes('readline')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'readline.createInterface',\n 'Effect.async or Stream for line-by-line reading',\n );\n }\n }\n }\n\n // stream.pipeline (callback) -> Effect.promise\n const hasStreamModule = sourceFile.getText().includes('stream');\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isStreamPipeline =\n (text.endsWith('.pipeline') && text.includes('stream')) || (hasStreamModule && text === 'pipeline');\n if (isStreamPipeline) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'stream.pipeline (callback)',\n 'Effect.promise or stream.promises.pipeline',\n );\n }\n }\n\n // events.once -> Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'once' || text.endsWith('.once')) {\n if (text.includes('events') || sourceFile.getText().includes(\"from 'events'\")) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'events.once',\n 'Effect.async for one-shot event',\n );\n }\n }\n }\n\n // fs.watch / fs.watchFile (callback) -> Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'watch' || text === 'watchFile' || text.endsWith('.watch') || text.endsWith('.watchFile')) {\n if (text.includes('fs') || expr.getText().includes('fs.')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'fs.watch / fs.watchFile',\n 'Effect.async or fs.watch with EventEmitter',\n );\n }\n }\n }\n\n // vm.runInNewContext / vm.runInContext -> Effect\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n (text.includes('runInNewContext') || text.includes('runInContext') || text.includes('runInThisContext')) &&\n text.includes('vm')\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'vm.runIn*',\n 'Effect.sync for isolated code execution',\n );\n }\n }\n\n // url.parse (deprecated) -> new URL()\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if ((text === 'parse' || text.endsWith('.parse')) && text.includes('url')) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'url.parse (deprecated)',\n 'new URL() or URL.parse for standard parsing',\n );\n }\n }\n\n // child_process.spawnSync -> Effect.promise / CommandExecutor\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (\n (text.endsWith('.spawnSync') && text.includes('child_process')) ||\n (sourceFile.getText().includes('child_process') && text === 'spawnSync')\n ) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'child_process.spawnSync',\n '@effect/platform CommandExecutor or Effect.promise',\n );\n }\n }\n\n // glob (callback) -> Effect.promise / glob promise API\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text === 'glob' || text.endsWith('.glob')) {\n const fileContent = sourceFile.getText();\n if (fileContent.includes('glob') && node.getArguments().length >= 2) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'glob (callback)',\n 'Effect.promise or glob promise API',\n );\n }\n }\n }\n\n // assert.throws / expect().rejects (test) -> Effect.runPromiseExit\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const isAssertThrows = text.includes('assert') && text.endsWith('.throws');\n const isExpectRejects = text.endsWith('.rejects') && text.includes('expect');\n if (isAssertThrows || isExpectRejects) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n isExpectRejects ? 'expect().rejects' : 'assert.throws',\n 'Effect.runPromiseExit + Exit.match for testing Effect failures',\n );\n }\n }\n\n // tls.connect / tls.createServer -> Effect.async\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (text.includes('tls') && (text.endsWith('.connect') || text.endsWith('.createServer'))) {\n addOpportunity(\n opportunities,\n filePath,\n node,\n sourceFile,\n 'tls.connect / tls.createServer',\n 'Effect.async or @effect/platform Socket/TLS',\n );\n }\n }\n\n return opportunities;\n}\n\n/**\n * Scan a directory for migration opportunities.\n */\nexport async function findMigrationOpportunitiesInProject(\n dirPath: string,\n options?: { extensions?: readonly string[] },\n): Promise<MigrationReport> {\n const extensions = options?.extensions ?? ['.ts', '.tsx'];\n const opportunities: MigrationOpportunity[] = [];\n let fileCount = 0;\n\n async function scan(dir: string): Promise<void> {\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n for (const ent of entries) {\n const full = join(dir, ent.name);\n if (ent.isDirectory()) {\n if (ent.name !== 'node_modules' && ent.name !== '.git' && ent.name !== 'dist') await scan(full);\n } else if (ent.isFile() && extensions.includes(extname(ent.name))) {\n fileCount++;\n try {\n opportunities.push(...findMigrationOpportunities(full));\n } catch {\n // Skip files that fail to parse (syntax errors, missing deps, etc.)\n }\n }\n }\n }\n await scan(dirPath);\n\n return { opportunities, fileCount };\n}\n\n/**\n * Format migration report as text.\n */\nexport function formatMigrationReport(report: MigrationReport): string {\n const lines: string[] = [];\n lines.push('Migration Opportunities Found:');\n lines.push('');\n for (const o of report.opportunities) {\n lines.push(` ${o.filePath}:${o.line}:${o.column} ${o.pattern}`);\n lines.push(` → ${o.suggestion}`);\n if (o.codeSnippet) lines.push(` Snippet: ${o.codeSnippet.slice(0, 60)}...`);\n lines.push('');\n }\n lines.push(`Total: ${report.opportunities.length} opportunities in ${report.fileCount} files`);\n return lines.join('\\n');\n}\n","/**\n * Mermaid diagram generation for Effect IR\n *\n * Aligned with awaitly-analyze: Start/End nodes, explicit edges,\n * optional subgraphs for parallel/race, sequential flow for pipe/generator.\n */\n\nimport { Effect, Option } from 'effect';\nimport type {\n ProjectServiceMap,\n StaticEffectIR,\n StaticFlowNode,\n StaticFiberNode,\n StaticRetryNode,\n StaticEffectNode,\n MermaidOptions,\n MermaidStyles,\n MermaidDetailLevel,\n EffectPath,\n} from '../types';\nimport { getStaticChildren } from '../types';\nimport { buildDataFlowGraph } from '../data-flow';\nimport { analyzeErrorFlow, analyzeErrorPropagation } from '../error-flow';\n\n// =============================================================================\n// Default styles (include start/end for Start/End nodes)\n// =============================================================================\n\nconst DEFAULT_STYLES: MermaidStyles = {\n effect: 'fill:#90EE90,stroke:#333,stroke-width:2px',\n generator: 'fill:#FFB6C1,stroke:#333,stroke-width:2px',\n pipe: 'fill:#ADD8E6,stroke:#333,stroke-width:2px',\n parallel: 'fill:#FFA500,stroke:#333,stroke-width:2px',\n race: 'fill:#FF6347,stroke:#333,stroke-width:2px',\n errorHandler: 'fill:#FFD700,stroke:#333,stroke-width:2px',\n retry: 'fill:#EE82EE,stroke:#333,stroke-width:2px',\n timeout: 'fill:#87CEEB,stroke:#333,stroke-width:2px',\n resource: 'fill:#98FB98,stroke:#333,stroke-width:2px',\n conditional: 'fill:#DDA0DD,stroke:#333,stroke-width:2px',\n loop: 'fill:#F0E68C,stroke:#333,stroke-width:2px',\n layer: 'fill:#E6E6FA,stroke:#333,stroke-width:2px',\n stream: 'fill:#E0F7FA,stroke:#333,stroke-width:2px',\n concurrencyPrimitive: 'fill:#B0E0E6,stroke:#333,stroke-width:2px',\n fiber: 'fill:#DDA0DD,stroke:#333,stroke-width:2px',\n decision: 'fill:#DDA0DD,stroke:#333,stroke-width:2px',\n switch: 'fill:#FFD700,stroke:#333,stroke-width:2px',\n tryCatch: 'fill:#FFE4B5,stroke:#333,stroke-width:2px',\n terminal: 'fill:#FF6B6B,stroke:#333,stroke-width:2px',\n opaque: 'fill:#FF9800,stroke:#333,stroke-width:2px',\n unknown: 'fill:#D3D3D3,stroke:#333,stroke-width:1px',\n start: 'fill:#c8e6c9,stroke:#2e7d32',\n end: 'fill:#ffcdd2,stroke:#c62828',\n cause: 'fill:#FF8A80,stroke:#D32F2F,stroke-width:2px',\n exit: 'fill:#B39DDB,stroke:#512DA8,stroke-width:2px',\n schedule: 'fill:#80DEEA,stroke:#00838F,stroke-width:2px',\n match: 'fill:#FFE082,stroke:#F57F17,stroke-width:2px',\n transform: 'fill:#A5D6A7,stroke:#388E3C,stroke-width:2px',\n channel: 'fill:#90CAF9,stroke:#1565C0,stroke-width:2px',\n sink: 'fill:#CE93D8,stroke:#7B1FA2,stroke-width:2px',\n interruption: 'fill:#FFAB91,stroke:#BF360C,stroke-width:2px',\n};\n\nconst DEFAULT_OPTIONS: Required<\n Omit<MermaidOptions, 'title' | 'includeTypeSignatures' | 'detail' | 'dataFlowOverlay' | 'errorFlowOverlay'>\n> & {\n title?: string;\n includeTypeSignatures?: boolean;\n detail?: MermaidDetailLevel;\n dataFlowOverlay?: boolean;\n errorFlowOverlay?: boolean;\n} = {\n direction: 'TB',\n includeIds: false,\n includeDescriptions: true,\n styles: DEFAULT_STYLES,\n compact: false,\n includeTypeSignatures: true,\n useSubgraphs: true,\n showConditions: true,\n detail: 'verbose',\n};\n\n// =============================================================================\n// Internal types (awaitly-style context and result)\n// =============================================================================\n\ninterface Edge {\n from: string;\n to: string;\n label?: string;\n}\n\ninterface Subgraph {\n id: string;\n label: string;\n content: string[];\n}\n\ninterface RenderContext {\n opts: ResolvedMermaidOptions;\n nodeCounter: number;\n edges: Edge[];\n subgraphs: Subgraph[];\n styleClasses: Map<string, string>;\n /** Map from IR node id to mermaid node ID (for enhanced overlay) */\n nodeIdMap: Map<string, string>;\n /** Optional label annotations per node id (for enhanced renderer) */\n nodeLabelAnnotations?: Map<string, string[]> | undefined;\n}\n\n/** Options with defaults applied (all required fields set). */\ninterface ResolvedMermaidOptions {\n direction: 'TB' | 'LR' | 'BT' | 'RL';\n includeIds: boolean;\n includeDescriptions: boolean;\n styles: MermaidStyles;\n compact: boolean;\n useSubgraphs: boolean;\n showConditions: boolean;\n detail: MermaidDetailLevel;\n title?: string | undefined;\n includeTypeSignatures?: boolean | undefined;\n}\n\ninterface RenderResult {\n firstNodeId: string | null;\n lastNodeIds: string[];\n}\n\n// =============================================================================\n// Utilities\n// =============================================================================\n\nfunction escapeLabel(label: string): string {\n return label\n .replace(/\\r?\\n/g, ' ')\n .replace(/\"/g, \"'\")\n .replace(/\\[/g, '(')\n .replace(/\\]/g, ')')\n .replace(/\\{/g, '(')\n .replace(/\\}/g, ')')\n .replace(/#/g, '&num;')\n .replace(/\\|/g, '&#124;');\n}\n\nfunction truncate(str: string, maxLength: number): string {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength - 3) + '...';\n}\n\nfunction sanitizeId(id: string): string {\n return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n// =============================================================================\n// Internal: render static Mermaid (sync) for reuse by static and enhanced\n// =============================================================================\n\nfunction renderStaticMermaidInternal(\n ir: StaticEffectIR,\n options?: Partial<MermaidOptions>,\n nodeLabelAnnotations?: Map<string, string[]>,\n): { lines: string[]; context: RenderContext } {\n const opts: ResolvedMermaidOptions = {\n ...DEFAULT_OPTIONS,\n ...options,\n useSubgraphs: options?.useSubgraphs ?? true,\n showConditions: options?.showConditions ?? true,\n detail: (options?.detail ?? 'verbose'),\n };\n const context: RenderContext = {\n opts,\n nodeCounter: 0,\n edges: [],\n subgraphs: [],\n styleClasses: new Map(),\n nodeIdMap: new Map(),\n nodeLabelAnnotations,\n };\n\n const lines: string[] = [];\n\n lines.push(`flowchart ${opts.direction}`);\n lines.push('');\n lines.push(` %% Program: ${ir.root.programName}`);\n lines.push('');\n\n const startId = 'start';\n const endId = 'end_node';\n lines.push(` ${startId}((Start))`);\n lines.push(` ${endId}((End))`);\n lines.push('');\n\n const { firstNodeId, lastNodeIds } = renderNodes(\n ir.root.children,\n context,\n lines,\n );\n\n if (firstNodeId) {\n context.edges.push({ from: startId, to: firstNodeId });\n }\n for (const lastId of lastNodeIds) {\n context.edges.push({ from: lastId, to: endId });\n }\n\n for (const subgraph of context.subgraphs) {\n lines.push('');\n lines.push(` subgraph ${subgraph.id}[\"${subgraph.label}\"]`);\n for (const line of subgraph.content) {\n lines.push(` ${line}`);\n }\n lines.push(' end');\n }\n\n lines.push('');\n lines.push(' %% Edges');\n for (const edge of context.edges) {\n if (edge.label && opts.showConditions) {\n lines.push(` ${edge.from} -->|${escapeLabel(edge.label)}| ${edge.to}`);\n } else {\n lines.push(` ${edge.from} --> ${edge.to}`);\n }\n }\n\n const styles = { ...DEFAULT_STYLES, ...opts.styles };\n lines.push('');\n lines.push(' %% Styles');\n 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') {\n lines.push(` classDef ${key}Style ${value}`);\n }\n }\n lines.push(` class ${startId} startStyle`);\n lines.push(` class ${endId} endStyle`);\n for (const [nodeId, styleClass] of context.styleClasses) {\n lines.push(` class ${nodeId} ${styleClass}`);\n }\n\n // Data-flow overlay: annotate edges with variable names and highlight warnings\n if (options?.dataFlowOverlay) {\n const dataFlow = buildDataFlowGraph(ir);\n\n // Build IR-node-id → mermaid-node-id mapping for data-flow nodes\n const irToMermaid = context.nodeIdMap;\n\n // Annotate edges between nodes with variable name labels\n lines.push('');\n lines.push(' %% Data-flow variable annotations');\n lines.push(' linkStyle default stroke:#999');\n for (const dfEdge of dataFlow.edges) {\n if (dfEdge.from === '__context__') continue;\n const fromMermaid = irToMermaid.get(dfEdge.from);\n const toMermaid = irToMermaid.get(dfEdge.to);\n if (fromMermaid && toMermaid && dfEdge.key && dfEdge.key !== 'value') {\n lines.push(` ${fromMermaid} -.->|${dfEdge.key}| ${toMermaid}`);\n }\n }\n\n // Highlight nodes with undefined reads\n if (dataFlow.undefinedReads.length > 0) {\n lines.push('');\n lines.push(' %% Data-flow warnings');\n lines.push(' classDef dataFlowWarning fill:#fff3cd,stroke:#856404,stroke-width:2px');\n for (const read of dataFlow.undefinedReads) {\n const mermaidId = irToMermaid.get(read.readerId);\n if (mermaidId) {\n lines.push(` class ${mermaidId} dataFlowWarning`);\n }\n }\n }\n\n // Highlight nodes with duplicate writes\n if (dataFlow.duplicateWrites.length > 0) {\n lines.push(' classDef duplicateWrite fill:#f8d7da,stroke:#721c24,stroke-width:2px');\n for (const dup of dataFlow.duplicateWrites) {\n for (const writerId of dup.writerIds) {\n const mermaidId = irToMermaid.get(writerId);\n if (mermaidId) {\n lines.push(` class ${mermaidId} duplicateWrite`);\n }\n }\n }\n }\n }\n\n // Error-flow overlay: annotate nodes with error types and highlight unhandled errors\n if (options?.errorFlowOverlay) {\n const errorFlow = analyzeErrorFlow(ir);\n const errorPropagation = analyzeErrorPropagation(ir);\n const irToMermaid = context.nodeIdMap;\n\n lines.push('');\n lines.push(' %% Error-flow overlay');\n lines.push(' classDef canFail fill:#FFECB3,stroke:#F57F17,stroke-width:2px');\n lines.push(' classDef unhandledError fill:#FFCDD2,stroke:#C62828,stroke-width:3px');\n\n // Tag nodes that can fail\n for (const stepError of errorFlow.stepErrors) {\n if (stepError.errors.length > 0) {\n const mermaidId = irToMermaid.get(stepError.stepId);\n if (mermaidId) {\n lines.push(` class ${mermaidId} canFail`);\n }\n }\n }\n\n // Tag nodes with unhandled error propagation (errors that reach the top without a handler)\n for (const prop of errorPropagation.propagation) {\n if (prop.possibleErrors.length > 0 && !prop.narrowedBy) {\n const mermaidId = irToMermaid.get(prop.atNode);\n if (mermaidId) {\n lines.push(` class ${mermaidId} unhandledError`);\n }\n }\n }\n\n // Annotate error-handler edges with narrowing info\n for (const prop of errorPropagation.propagation) {\n if (prop.narrowedBy && prop.narrowedBy.removedErrors.length > 0) {\n const handlerMermaid = irToMermaid.get(prop.narrowedBy.handler);\n const nodeMermaid = irToMermaid.get(prop.atNode);\n if (handlerMermaid && nodeMermaid) {\n const narrowed = prop.narrowedBy.removedErrors.join(', ');\n lines.push(` ${nodeMermaid} -.->|catches ${narrowed}| ${handlerMermaid}`);\n }\n }\n }\n }\n\n return { lines, context };\n}\n\n// =============================================================================\n// Node rendering (sequential flow: firstNodeId, lastNodeIds)\n// =============================================================================\n\nfunction renderNodes(\n nodes: readonly StaticFlowNode[],\n context: RenderContext,\n lines: string[],\n): RenderResult {\n if (nodes.length === 0) {\n return { firstNodeId: null, lastNodeIds: [] };\n }\n\n let firstNodeId: string | null = null;\n let prevLastNodeIds: string[] = [];\n\n for (const node of nodes) {\n const result = renderNode(node, context, lines);\n if (firstNodeId === null && result.firstNodeId) {\n firstNodeId = result.firstNodeId;\n }\n if (result.firstNodeId) {\n for (const prevId of prevLastNodeIds) {\n context.edges.push({ from: prevId, to: result.firstNodeId });\n }\n }\n prevLastNodeIds = result.lastNodeIds;\n }\n\n return { firstNodeId, lastNodeIds: prevLastNodeIds };\n}\n\nfunction getNodeId(node: StaticFlowNode, context: RenderContext): string {\n const id =\n context.opts.includeIds && 'id' in node\n ? node.id\n : `n${String(++context.nodeCounter)}`;\n return sanitizeId(id);\n}\n\nfunction getNodeLabel(\n node: StaticFlowNode,\n opts: RenderContext['opts'],\n annotations?: string[],\n): string {\n if (!opts.includeDescriptions) {\n return node.type;\n }\n\n // Base label (compact mode)\n let label: string;\n switch (node.type) {\n case 'effect':\n label = node.callee || 'Effect';\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 = `${node.callee} (${node.children.length} effects)`;\n break;\n case 'race':\n label = `${node.callee} (${node.children.length} racing)`;\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.loopType}${node.iterSource ? `(${node.iterSource})` : ''}`;\n break;\n case 'layer':\n label = `Layer${node.isMerged ? ' (merged)' : ''}`;\n break;\n case 'stream':\n label = `Stream${node.pipeline.length > 0 ? `.${node.pipeline.map((p) => p.operation).join(' → ')}` : ''}${node.sink ? ` → ${node.sink}` : ''}`;\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 if (opts.detail !== 'compact' && node.displayName) {\n label = node.displayName;\n }\n\n // Verbose: append type signature and semantic role\n if (opts.detail === 'verbose') {\n if (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 label += '\\n' + annotations.join('\\n');\n }\n return label;\n}\n\nfunction getNodeStyleClass(node: StaticFlowNode): string {\n if (node.type === 'concurrency-primitive') return 'concurrencyPrimitiveStyle';\n if (node.type === 'try-catch') return 'tryCatchStyle';\n if (node.type === 'error-handler') return 'errorHandlerStyle';\n return `${node.type}Style`;\n}\n\nfunction renderNode(\n node: StaticFlowNode,\n context: RenderContext,\n lines: string[],\n): 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 if (node.type !== 'generator') {\n lines.push(` ${nodeId}[\"${escapeLabel(label)}\"]`);\n context.styleClasses.set(nodeId, styleClass);\n context.nodeIdMap.set(node.id, 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);\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);\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);\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);\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);\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);\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);\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);\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);\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);\n const wrapperId = `${node.type}_${++context.nodeCounter}`;\n const label =\n node.type === 'retry'\n ? `Retry${node.schedule ? `(${node.schedule})` : ''}`\n : `Timeout${node.duration ? `(${node.duration})` : ''}`;\n lines.push(` ${wrapperId}[\"${label}\"]`);\n context.styleClasses.set(wrapperId, `${node.type}Style`);\n if (sourceResult.lastNodeIds.length > 0) {\n context.edges.push({\n from: sourceResult.lastNodeIds[0]!,\n to: wrapperId,\n });\n }\n return {\n firstNodeId: sourceResult.firstNodeId ?? nodeId,\n lastNodeIds: [wrapperId],\n };\n }\n\n case 'resource': {\n const acquireResult = renderNode(node.acquire, context, lines);\n const resourceId = `resource_${++context.nodeCounter}`;\n lines.push(` ${resourceId}[\"Resource\"]`);\n context.styleClasses.set(resourceId, 'resourceStyle');\n if (acquireResult.lastNodeIds.length > 0) {\n context.edges.push({\n from: acquireResult.lastNodeIds[0]!,\n to: resourceId,\n });\n }\n let lastIds = [resourceId];\n if (node.use) {\n const useResult = renderNode(node.use, context, lines);\n if (useResult.firstNodeId) {\n context.edges.push({ from: resourceId, to: useResult.firstNodeId });\n }\n lastIds = useResult.lastNodeIds;\n }\n return {\n firstNodeId: acquireResult.firstNodeId ?? nodeId,\n lastNodeIds: lastIds,\n };\n }\n\n case 'conditional': {\n const decisionId = `cond_${++context.nodeCounter}`;\n const condLabel = node.conditionLabel ?? truncate(node.condition, 25);\n lines.push(` ${decisionId}{\"${escapeLabel(condLabel)}\"}`);\n context.styleClasses.set(decisionId, 'conditionalStyle');\n context.edges.push({ from: nodeId, to: decisionId });\n\n const onTrueResult = renderNode(node.onTrue, context, lines);\n if (onTrueResult.firstNodeId) {\n context.edges.push({\n from: decisionId,\n to: onTrueResult.firstNodeId,\n label: node.trueEdgeLabel ?? 'true',\n });\n }\n const lastNodeIds: string[] = [...onTrueResult.lastNodeIds];\n\n if (node.onFalse) {\n const onFalseResult = renderNode(node.onFalse, context, lines);\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.loopType}${node.iterSource ? `(${node.iterSource})` : ''}`;\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);\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);\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\n // Render true branch\n const trueResult = renderNodes(node.onTrue, context, lines);\n if (trueResult.firstNodeId) {\n context.edges.push({ from: decisionId, to: trueResult.firstNodeId, label: 'yes' });\n }\n const lastNodeIds: string[] = [...trueResult.lastNodeIds];\n\n // Render false branch\n if (node.onFalse && node.onFalse.length > 0) {\n const falseResult = renderNodes(node.onFalse, context, lines);\n if (falseResult.firstNodeId) {\n context.edges.push({ from: decisionId, to: falseResult.firstNodeId, label: 'no' });\n }\n lastNodeIds.push(...falseResult.lastNodeIds);\n } else {\n lastNodeIds.push(decisionId); // no false branch → continues from decision\n }\n return { firstNodeId: decisionId, lastNodeIds };\n }\n\n case 'switch': {\n const switchId = `switch_${++context.nodeCounter}`;\n const switchLabel = `Switch: ${truncate(node.expression, 20)}`;\n lines.push(` ${switchId}{\"${escapeLabel(switchLabel)}\"}`);\n context.styleClasses.set(switchId, 'switchStyle');\n\n const lastNodeIds: string[] = [];\n for (const caseItem of node.cases) {\n const caseLabel = caseItem.labels.join(' / ');\n const caseResult = renderNodes(caseItem.body, context, lines);\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);\n const allLastIds: string[] = [...tryResult.lastNodeIds];\n\n if (node.catchBody && node.catchBody.length > 0) {\n const catchId = `catch_${++context.nodeCounter}`;\n const catchLabel = node.catchVariable ? `Catch(${node.catchVariable})` : 'Catch';\n lines.push(` ${catchId}[\"${escapeLabel(catchLabel)}\"]`);\n context.styleClasses.set(catchId, 'tryCatchStyle');\n\n // Edge from try body to catch\n for (const lastId of tryResult.lastNodeIds) {\n context.edges.push({ from: lastId, to: catchId, label: 'on error' });\n }\n\n const catchResult = renderNodes(node.catchBody, context, lines);\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);\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);\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 lines.push(` ${opaqueId}{{\"${escapeLabel(`⚠ ${node.reason}`)}\"}}`);\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);\n if (childResult.firstNodeId) {\n context.edges.push({ from: causeId, to: childResult.firstNodeId });\n }\n return { firstNodeId: causeId, lastNodeIds: childResult.lastNodeIds.length > 0 ? childResult.lastNodeIds : [causeId] };\n }\n return { firstNodeId: causeId, lastNodeIds: [causeId] };\n }\n\n case 'exit': {\n // Stadium shape for Exit nodes\n const exitId = `exit_${++context.nodeCounter}`;\n lines.push(` ${exitId}([\"${escapeLabel(label)}\"])`);\n context.styleClasses.set(exitId, 'exitStyle');\n context.nodeIdMap.set(node.id, exitId);\n return { firstNodeId: exitId, lastNodeIds: [exitId] };\n }\n\n case 'schedule': {\n // Parallelogram shape for Schedule nodes\n const schedId = `schedule_${++context.nodeCounter}`;\n lines.push(` ${schedId}[/\"${escapeLabel(label)}\"/]`);\n context.styleClasses.set(schedId, 'scheduleStyle');\n context.nodeIdMap.set(node.id, schedId);\n return { firstNodeId: schedId, lastNodeIds: [schedId] };\n }\n\n case 'match': {\n // Diamond shape for Match nodes (similar to switch)\n const matchId = `match_${++context.nodeCounter}`;\n lines.push(` ${matchId}{\"${escapeLabel(label)}\"}`);\n context.styleClasses.set(matchId, 'matchStyle');\n context.nodeIdMap.set(node.id, matchId);\n\n if (node.matchedTags && node.matchedTags.length > 0) {\n // Render a branch per matched tag (similar to switch cases)\n const lastNodeIds: string[] = [];\n for (const tag of node.matchedTags) {\n const tagNodeId = `match_tag_${++context.nodeCounter}`;\n lines.push(` ${tagNodeId}[\"${escapeLabel(tag)}\"]`);\n context.styleClasses.set(tagNodeId, 'matchStyle');\n context.edges.push({ from: matchId, to: tagNodeId, label: tag });\n lastNodeIds.push(tagNodeId);\n }\n if (lastNodeIds.length === 0) lastNodeIds.push(matchId);\n return { firstNodeId: matchId, lastNodeIds };\n }\n return { firstNodeId: matchId, lastNodeIds: [matchId] };\n }\n\n case 'transform': {\n // Rectangle for Transform nodes — recurse into source child\n if (node.source) {\n const sourceResult = renderNode(node.source, context, lines);\n if (sourceResult.lastNodeIds.length > 0) {\n context.edges.push({ from: sourceResult.lastNodeIds[0]!, to: nodeId });\n }\n return { firstNodeId: sourceResult.firstNodeId ?? nodeId, lastNodeIds: [nodeId] };\n }\n return { firstNodeId: nodeId, lastNodeIds: [nodeId] };\n }\n\n case 'channel': {\n // Subroutine shape for Channel nodes\n const chanId = `channel_${++context.nodeCounter}`;\n lines.push(` ${chanId}[[\"${escapeLabel(label)}\"]]`);\n context.styleClasses.set(chanId, 'channelStyle');\n context.nodeIdMap.set(node.id, chanId);\n\n if (node.source) {\n const sourceResult = renderNode(node.source, context, lines);\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);\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);\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);\n if (sourceResult.lastNodeIds.length > 0 && handlerResult.firstNodeId) {\n context.edges.push({ from: sourceResult.lastNodeIds[0]!, to: handlerResult.firstNodeId, label: 'on interrupt' });\n }\n lastIds.push(...handlerResult.lastNodeIds);\n }\n return { firstNodeId: intId, lastNodeIds: lastIds.length > 0 ? lastIds : [intId] };\n }\n return { firstNodeId: intId, lastNodeIds: [intId] };\n }\n\n default:\n return { firstNodeId: nodeId, lastNodeIds: [nodeId] };\n }\n}\n\n// =============================================================================\n// Public API: static Mermaid (sync) and renderMermaid (Effect)\n// =============================================================================\n\n/**\n * Generate a Mermaid flowchart from static Effect IR (sync).\n * Includes Start/End nodes, optional subgraphs, sequential flow.\n */\nexport function renderStaticMermaid(\n ir: StaticEffectIR,\n options?: Partial<MermaidOptions>,\n): string {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const { lines } = renderStaticMermaidInternal(ir, opts);\n return lines.join('\\n');\n}\n\n/**\n * Render Effect IR as Mermaid flowchart (Effect).\n * Same as renderStaticMermaid but returns Effect.Effect<string>.\n */\nexport const renderMermaid = (\n ir: StaticEffectIR,\n options?: Partial<MermaidOptions>,\n): Effect.Effect<string> =>\n Effect.sync(() => renderStaticMermaid(ir, options));\n\n// =============================================================================\n// Path-based Mermaid\n// =============================================================================\n\nexport interface PathsMermaidOptions {\n direction?: 'TB' | 'LR' | 'BT' | 'RL';\n /** Collapse consecutive log-like steps into one summary node (default: true). */\n collapseRepeatedLogs?: boolean;\n /** Collapse consecutive pure-transform-like steps into one summary node (default: true). */\n collapsePureTransforms?: boolean;\n /** Collapse consecutive environment-acquisition-like steps (default: false, true in style-guide mode). */\n collapseEnvironmentRuns?: boolean;\n /** Apply summary-only readability heuristics (environment grouping + service boundary prefixes). */\n styleGuide?: boolean;\n /** Prefix the first service-like calls with \"svc:\" (default: false, true in style-guide mode). */\n prefixServiceBoundaries?: boolean;\n}\n\nexport interface DisplayPathStep {\n key: string;\n name: string;\n}\n\nexport interface PathSummaryResult {\n steps: readonly DisplayPathStep[];\n collapsedGroups: number;\n}\n\nfunction isLogLikeStep(name: string): boolean {\n const n = name.toLowerCase();\n return (\n n.includes('log') ||\n n.includes('loginfo') ||\n n.includes('logdebug') ||\n n.includes('logwarning') ||\n n.includes('logerror') ||\n n.includes('taperror')\n );\n}\n\nfunction isPureTransformLikeStep(name: string): boolean {\n const n = name.toLowerCase();\n return (\n n.includes('map') ||\n n.includes('flatmap') ||\n n.includes('filter') ||\n n.includes('transform') ||\n n.includes('tap(') ||\n n === 'tap' ||\n n.includes('annotate') ||\n n.includes('hsep') ||\n n.includes('ansidoc.text')\n );\n}\n\nfunction isEnvironmentLikeStep(name: string): boolean {\n const n = name.trim();\n if (/\\(environment\\)/i.test(n)) return true;\n if (/^[A-Z][A-Za-z0-9_]+$/.test(n)) return true;\n if (/^(Context\\.Tag|GenericTag|Effect\\.serviceOption|Effect\\.service)\\b/.test(n)) return true;\n return false;\n}\n\nfunction isServiceBoundaryLikeStep(name: string): boolean {\n const n = name.trim();\n if (!/^[A-Za-z_$][\\w$]*\\.[A-Za-z_$][\\w$]*/.test(n)) return false;\n const builtinPrefixes = [\n 'Effect.',\n 'Layer.',\n 'Stream.',\n 'Schema.',\n 'Schedule.',\n 'Option.',\n 'Either.',\n 'Duration.',\n 'Console.',\n 'Array.',\n 'String.',\n 'Number.',\n 'Boolean.',\n 'Math.',\n 'Object.',\n 'JSON.',\n 'Promise.',\n 'Date.',\n ];\n return !builtinPrefixes.some((prefix) => n.startsWith(prefix));\n}\n\nfunction applyServiceBoundaryPrefixes(\n steps: readonly DisplayPathStep[],\n options: PathsMermaidOptions,\n): DisplayPathStep[] {\n const usePrefix = options.prefixServiceBoundaries ?? options.styleGuide ?? false;\n if (!usePrefix) return [...steps];\n const out = [...steps];\n let prefixed = 0;\n for (let i = 0; i < out.length; i++) {\n if (prefixed >= 2) break;\n const step = out[i];\n if (!step) continue;\n if (isServiceBoundaryLikeStep(step.name) && !step.name.startsWith('svc: ')) {\n out[i] = { ...step, name: `svc: ${step.name}` };\n prefixed++;\n }\n }\n return out;\n}\n\nexport function summarizePathSteps(\n path: EffectPath,\n options: PathsMermaidOptions,\n): PathSummaryResult {\n const collapseLogs = options.collapseRepeatedLogs ?? true;\n const collapseTransforms = options.collapsePureTransforms ?? true;\n const collapseEnvironment = options.collapseEnvironmentRuns ?? options.styleGuide ?? false;\n\n const out: DisplayPathStep[] = [];\n let collapsedGroups = 0;\n let i = 0;\n while (i < path.steps.length) {\n const current = path.steps[i];\n if (!current) break;\n const currentName = current.name ?? current.nodeId;\n\n if (collapseLogs && isLogLikeStep(currentName)) {\n let j = i + 1;\n while (j < path.steps.length) {\n const next = path.steps[j];\n if (!next) break;\n const nextName = next.name ?? next.nodeId;\n if (!isLogLikeStep(nextName)) break;\n j++;\n }\n const count = j - i;\n if (count > 1) {\n out.push({\n key: `${path.id}:logs:${i}`,\n name: `log steps ×${String(count)}`,\n });\n collapsedGroups++;\n i = j;\n continue;\n }\n }\n\n if (collapseTransforms && isPureTransformLikeStep(currentName)) {\n let j = i + 1;\n while (j < path.steps.length) {\n const next = path.steps[j];\n if (!next) break;\n const nextName = next.name ?? next.nodeId;\n if (!isPureTransformLikeStep(nextName)) break;\n j++;\n }\n const count = j - i;\n if (count > 1) {\n out.push({\n key: `${path.id}:transforms:${i}`,\n name: `transform steps ×${String(count)}`,\n });\n collapsedGroups++;\n i = j;\n continue;\n }\n }\n\n if (collapseEnvironment && isEnvironmentLikeStep(currentName)) {\n let j = i + 1;\n while (j < path.steps.length) {\n const next = path.steps[j];\n if (!next) break;\n const nextName = next.name ?? next.nodeId;\n if (!isEnvironmentLikeStep(nextName)) break;\n j++;\n }\n const count = j - i;\n if (count > 1) {\n out.push({\n key: `${path.id}:env:${i}`,\n name: `environment ×${String(count)}`,\n });\n collapsedGroups++;\n i = j;\n continue;\n }\n }\n\n out.push({ key: current.nodeId, name: currentName });\n i++;\n }\n\n return {\n steps: applyServiceBoundaryPrefixes(out, options),\n collapsedGroups,\n };\n}\n\n/**\n * Generate a simplified Mermaid diagram from execution paths.\n * Start -> step1 -> step2 -> ... -> End; nodes merged by nodeId.\n */\nexport function renderPathsMermaid(\n paths: readonly EffectPath[],\n options: PathsMermaidOptions = {},\n): string {\n const direction = options.direction ?? 'TB';\n const lines: string[] = [];\n\n lines.push(`flowchart ${direction}`);\n lines.push('');\n\n const stepNodes = new Map<string, { id: string; name: string }>();\n let nodeCounter = 0;\n\n const displayPaths = paths.map((path) => summarizePathSteps(path, options).steps);\n\n for (const displayPath of displayPaths) {\n for (const step of displayPath) {\n const key = step.key;\n if (!stepNodes.has(key)) {\n stepNodes.set(key, {\n id: `step_${++nodeCounter}`,\n name: step.name,\n });\n }\n }\n }\n\n lines.push(' start((Start))');\n lines.push(' end_node((End))');\n lines.push('');\n\n for (const [, stepInfo] of stepNodes) {\n lines.push(` ${stepInfo.id}[\"${escapeLabel(stepInfo.name)}\"]`);\n }\n lines.push('');\n\n const edges = new Set<string>();\n for (const displayPath of displayPaths) {\n if (displayPath.length === 0) continue;\n const firstStep = displayPath[0]!;\n const firstInfo = stepNodes.get(firstStep.key)!;\n edges.add(`start --> ${firstInfo.id}`);\n for (let i = 0; i < displayPath.length - 1; i++) {\n const cur = displayPath[i]!;\n const next = displayPath[i + 1]!;\n const curInfo = stepNodes.get(cur.key)!;\n const nextInfo = stepNodes.get(next.key)!;\n edges.add(`${curInfo.id} --> ${nextInfo.id}`);\n }\n const lastStep = displayPath[displayPath.length - 1]!;\n const lastInfo = stepNodes.get(lastStep.key)!;\n edges.add(`${lastInfo.id} --> end_node`);\n }\n\n lines.push(' %% Edges');\n for (const edge of edges) {\n lines.push(` ${edge}`);\n }\n\n return lines.join('\\n');\n}\n\n// =============================================================================\n// Enhanced Mermaid (types / errors overlay)\n// =============================================================================\n\nexport interface EnhancedMermaidOptions extends Partial<MermaidOptions> {\n showTypeSignatures?: boolean;\n showRequiredServices?: boolean;\n showErrorNodes?: boolean;\n}\n\nconst DEFAULT_ENHANCED_OPTIONS: EnhancedMermaidOptions = {\n ...DEFAULT_OPTIONS,\n showTypeSignatures: true,\n showRequiredServices: true,\n showErrorNodes: false,\n};\n\n/**\n * Collect type and service annotations from IR for overlay.\n */\nfunction collectEnhancedAnnotations(\n ir: StaticEffectIR,\n opts: EnhancedMermaidOptions,\n): Map<string, string[]> {\n const map = new Map<string, string[]>();\n const showTypes = opts.showTypeSignatures !== false;\n const showServices = opts.showRequiredServices === true;\n\n function visit(node: StaticFlowNode): void {\n if (node.type === 'effect') {\n const annotations: string[] = [];\n if (showTypes && node.typeSignature) {\n annotations.push(\n `<${node.typeSignature.successType}, ${node.typeSignature.errorType}, ${node.typeSignature.requirementsType}>`,\n );\n }\n if (showServices && node.requiredServices && node.requiredServices.length > 0) {\n const services = node.requiredServices.map((s) => s.serviceId).join(', ');\n annotations.push(`R: ${services}`);\n }\n if (annotations.length > 0) {\n map.set(node.id, annotations);\n }\n }\n switch (node.type) {\n case 'generator':\n for (const y of node.yields) {\n visit(y.effect);\n }\n break;\n case 'pipe':\n visit(node.initial);\n for (const t of node.transformations) {\n visit(t);\n }\n break;\n case 'parallel':\n case 'race':\n for (const c of node.children) {\n visit(c);\n }\n break;\n case 'error-handler':\n visit(node.source);\n if (node.handler) visit(node.handler);\n break;\n case 'retry':\n case 'timeout':\n visit(node.source);\n break;\n case 'resource':\n visit(node.acquire);\n visit(node.release);\n if (node.use) visit(node.use);\n break;\n case 'conditional':\n visit(node.onTrue);\n if (node.onFalse) visit(node.onFalse);\n break;\n case 'loop':\n visit(node.body);\n break;\n case 'layer':\n for (const op of node.operations) {\n visit(op);\n }\n break;\n case 'decision':\n for (const child of node.onTrue) visit(child);\n if (node.onFalse) {\n for (const child of node.onFalse) visit(child);\n }\n break;\n case 'switch':\n for (const caseItem of node.cases) {\n for (const child of caseItem.body) visit(child);\n }\n break;\n case 'try-catch':\n for (const child of node.tryBody) visit(child);\n if (node.catchBody) {\n for (const child of node.catchBody) visit(child);\n }\n if (node.finallyBody) {\n for (const child of node.finallyBody) visit(child);\n }\n break;\n case 'terminal':\n if (node.value) {\n for (const child of node.value) visit(child);\n }\n break;\n case 'opaque':\n break;\n default:\n break;\n }\n }\n\n for (const child of ir.root.children) {\n visit(child);\n }\n return map;\n}\n\n/**\n * Generate enhanced Mermaid with type signatures and/or required services on nodes.\n */\nexport function renderEnhancedMermaid(\n ir: StaticEffectIR,\n options?: EnhancedMermaidOptions,\n): string {\n const enhancedOpts = { ...DEFAULT_ENHANCED_OPTIONS, ...options };\n const nodeLabelAnnotations = collectEnhancedAnnotations(ir, enhancedOpts);\n const { lines } = renderStaticMermaidInternal(\n ir,\n enhancedOpts as Partial<MermaidOptions>,\n nodeLabelAnnotations,\n );\n return lines.join('\\n');\n}\n\n/**\n * Render enhanced Mermaid as Effect.\n */\nexport const renderEnhancedMermaidEffect = (\n ir: StaticEffectIR,\n options?: EnhancedMermaidOptions,\n): Effect.Effect<string> =>\n Effect.sync(() => renderEnhancedMermaid(ir, options));\n\n// =============================================================================\n// Enhanced diagram types (GAP 21)\n// =============================================================================\n\nfunction collectFiberNodes(\n nodes: readonly StaticFlowNode[],\n result: StaticFiberNode[],\n): void {\n for (const node of nodes) {\n if (node.type === 'fiber') {\n result.push(node);\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) collectFiberNodes(children, result);\n }\n}\n\n/**\n * Generate a Mermaid sequence diagram for fiber fork/join (GAP 21).\n */\nexport function renderSequenceMermaid(ir: StaticEffectIR): string {\n const fibers: StaticFiberNode[] = [];\n collectFiberNodes(ir.root.children, fibers);\n const forks = fibers.filter(\n (f) => f.operation === 'fork' || f.operation === 'forkScoped' || f.operation === 'forkDaemon',\n );\n const joins = fibers.filter((f) => f.operation === 'join' || f.operation === 'await');\n if (forks.length === 0 && joins.length === 0) {\n return 'sequenceDiagram\\n participant Main\\n note over Main: No fiber operations detected';\n }\n const lines: string[] = ['sequenceDiagram', ' participant Main'];\n forks.forEach((_f, i) => {\n lines.push(` participant Fiber${i + 1}`);\n });\n lines.push('');\n forks.forEach((f, i) => {\n const label = f.fiberSource ? (f.fiberSource as StaticEffectNode).callee ?? 'effect' : 'effect';\n lines.push(` Main->>Fiber${i + 1}: fork(${label})`);\n });\n joins.forEach((_, i) => {\n const fid = Math.min(i + 1, forks.length);\n lines.push(` Fiber${fid}-->>Main: join`);\n });\n return lines.join('\\n');\n}\n\nfunction collectRetryNodes(\n nodes: readonly StaticFlowNode[],\n result: StaticRetryNode[],\n): void {\n for (const node of nodes) {\n if (node.type === 'retry') {\n result.push(node);\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) collectRetryNodes(children, result);\n }\n}\n\n/**\n * Generate a Mermaid Gantt diagram for retry schedules (GAP 21).\n */\nexport function renderRetryGanttMermaid(ir: StaticEffectIR): string {\n const retries: StaticRetryNode[] = [];\n collectRetryNodes(ir.root.children, retries);\n const withSchedule = retries.filter((r) => r.scheduleInfo);\n if (withSchedule.length === 0) {\n return 'gantt\\n title Retry Schedule\\n section Retries\\n No retry schedules detected';\n }\n const lines: string[] = ['gantt', ' title Retry Schedule', ' section Attempts'];\n withSchedule.forEach((r, idx) => {\n const info = r.scheduleInfo!;\n const max =\n info.maxRetries === 'unlimited'\n ? 5\n : Math.min(\n typeof info.maxRetries === 'string'\n ? Number(info.maxRetries)\n : (info.maxRetries ?? 3),\n 5,\n );\n for (let i = 0; i < max; i++) {\n lines.push(` Attempt ${i + 1}: a${idx}_${i}, ${i === 0 ? '0' : `after a${idx}_${i - 1}`}, 100ms`);\n if (i < max - 1) {\n lines.push(` Wait: w${idx}_${i}, after a${idx}_${i}, 200ms`);\n }\n }\n });\n return lines.join('\\n');\n}\n\n// =============================================================================\n// Service Graph Mermaid\n// =============================================================================\n\n/**\n * Render a project-level service dependency graph as a Mermaid flowchart.\n * Services are hexagon-shaped nodes, with edges showing layer requirements.\n */\nexport function renderServiceGraphMermaid(\n serviceMap: ProjectServiceMap,\n options: { direction?: 'TB' | 'LR' | 'BT' | 'RL' } = {},\n): string {\n const direction = options.direction ?? 'TB';\n const sgLines: string[] = [];\n const sanitize = (s: string) => s.replace(/[^a-zA-Z0-9_]/g, '_');\n\n sgLines.push(`flowchart ${direction}`);\n sgLines.push('');\n sgLines.push(' %% Service Dependency Graph');\n sgLines.push('');\n\n // Service nodes (hexagon shape)\n for (const [serviceId, artifact] of serviceMap.services) {\n const id = sanitize(serviceId);\n const methodCount = artifact.definition.methods.length;\n const label = methodCount > 0\n ? `${serviceId}\\\\n(${methodCount} method${methodCount === 1 ? '' : 's'})`\n : serviceId;\n sgLines.push(` ${id}{{{\"${label}\"}}}`);\n }\n\n // Unresolved services (dashed)\n for (const serviceId of serviceMap.unresolvedServices) {\n const id = `unresolved_${sanitize(serviceId)}`;\n sgLines.push(` ${id}[\"? ${serviceId}\"]`);\n }\n sgLines.push('');\n\n // Edges: service requires other services (via layers)\n const edgesAdded = new Set<string>();\n for (const [serviceId, artifact] of serviceMap.services) {\n for (const layer of artifact.layerImplementations) {\n for (const req of layer.requires) {\n const edgeKey = `${serviceId}->${req}`;\n if (edgesAdded.has(edgeKey)) continue;\n edgesAdded.add(edgeKey);\n\n const fromId = sanitize(serviceId);\n const toId = serviceMap.services.has(req)\n ? sanitize(req)\n : `unresolved_${sanitize(req)}`;\n sgLines.push(` ${fromId} -->|\"${layer.name}\"| ${toId}`);\n }\n }\n }\n sgLines.push('');\n\n // Styling\n sgLines.push(' classDef service fill:#E3F2FD,stroke:#1565C0,stroke-width:2px');\n sgLines.push(' classDef unresolved fill:#FFF3CD,stroke:#856404,stroke-dasharray:5');\n for (const serviceId of serviceMap.services.keys()) {\n sgLines.push(` class ${sanitize(serviceId)} service`);\n }\n for (const serviceId of serviceMap.unresolvedServices) {\n sgLines.push(` class unresolved_${sanitize(serviceId)} unresolved`);\n }\n\n return sgLines.join('\\n');\n}","/**\n * Data Flow Analysis for Effect IR\n *\n * Builds a graph of value and service dependencies between effect nodes:\n * - Value flow: sequential edges from one effect to the next in execution order\n * - Service reads: effect nodes that require services from Context\n */\n\nimport type { StaticEffectIR, StaticFlowNode, StaticEffectNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface DataFlowNode {\n id: string;\n name?: string | undefined;\n /** Success type this effect produces (writes) */\n writes?: string | undefined;\n /** Service IDs this effect reads from Context */\n reads: string[];\n location?: { line: number; column: number } | undefined;\n}\n\nexport interface DataFlowEdge {\n from: string;\n to: string;\n key: string;\n}\n\nexport interface DataFlowGraph {\n nodes: DataFlowNode[];\n edges: DataFlowEdge[];\n producedKeys: Set<string>;\n undefinedReads: UndefinedRead[];\n duplicateWrites: DuplicateWrite[];\n}\n\nexport interface UndefinedRead {\n key: string;\n readerId: string;\n readerName?: string | undefined;\n}\n\nexport interface DuplicateWrite {\n key: string;\n writerIds: string[];\n}\n\n// =============================================================================\n// Execution-order collection (effect nodes only, sequential flow)\n// =============================================================================\n\nfunction collectEffectNodesInOrder(\n nodes: readonly StaticFlowNode[],\n result: StaticEffectNode[],\n): void {\n for (const node of nodes) {\n if (node.type === 'effect') {\n result.push(node);\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n collectEffectNodesInOrder(children, result);\n }\n }\n}\n\n// =============================================================================\n// Graph Building\n// =============================================================================\n\nexport function buildDataFlowGraph(ir: StaticEffectIR): DataFlowGraph {\n const nodes: DataFlowNode[] = [];\n const edges: DataFlowEdge[] = [];\n const producedKeys = new Set<string>();\n const keyProducers = new Map<string, string[]>();\n const effectNodesOrdered: StaticEffectNode[] = [];\n\n collectEffectNodesInOrder(ir.root.children, effectNodesOrdered);\n\n for (const eff of effectNodesOrdered) {\n const writes = eff.typeSignature?.successType;\n const reads = (eff.requiredServices ?? []).map((s) => s.serviceId);\n\n if (writes) {\n producedKeys.add(writes);\n const producers = keyProducers.get(writes) ?? [];\n producers.push(eff.id);\n keyProducers.set(writes, producers);\n }\n\n nodes.push({\n id: eff.id,\n name: eff.callee,\n writes,\n reads,\n location: eff.location\n ? { line: eff.location.line, column: eff.location.column }\n : undefined,\n });\n }\n\n // Value-flow edges: consecutive effects in order\n for (let i = 0; i < effectNodesOrdered.length - 1; i++) {\n const from = effectNodesOrdered[i];\n const to = effectNodesOrdered[i + 1];\n if (from === undefined || to === undefined) continue;\n const key = from.typeSignature?.successType ?? 'value';\n edges.push({ from: from.id, to: to.id, key });\n }\n\n // Context -> effect for each required service (virtual \"context\" source)\n const contextId = '__context__';\n for (const node of nodes) {\n for (const key of node.reads) {\n edges.push({ from: contextId, to: node.id, key });\n }\n }\n\n const undefinedReads: UndefinedRead[] = [];\n for (const node of nodes) {\n for (const key of node.reads) {\n if (!producedKeys.has(key) && key !== contextId) {\n undefinedReads.push({\n key,\n readerId: node.id,\n readerName: node.name,\n });\n }\n }\n }\n\n const duplicateWrites: DuplicateWrite[] = [];\n for (const [key, writers] of keyProducers) {\n if (writers.length > 1) {\n duplicateWrites.push({ key, writerIds: writers });\n }\n }\n\n return {\n nodes,\n edges,\n producedKeys,\n undefinedReads,\n duplicateWrites,\n };\n}\n\n// =============================================================================\n// Analysis Utilities\n// =============================================================================\n\nexport function getDataFlowOrder(\n graph: DataFlowGraph,\n): string[] | undefined {\n const inDegree = new Map<string, number>();\n const adjacency = new Map<string, string[]>();\n\n for (const node of graph.nodes) {\n inDegree.set(node.id, 0);\n adjacency.set(node.id, []);\n }\n\n for (const edge of graph.edges) {\n if (edge.from === '__context__') continue;\n const targets = adjacency.get(edge.from) ?? [];\n targets.push(edge.to);\n adjacency.set(edge.from, targets);\n inDegree.set(edge.to, (inDegree.get(edge.to) ?? 0) + 1);\n }\n\n const queue: string[] = [];\n for (const [id, degree] of inDegree) {\n if (id !== '__context__' && degree === 0) {\n queue.push(id);\n }\n }\n\n const result: string[] = [];\n while (queue.length > 0) {\n const current = queue.shift();\n if (current === undefined) break;\n result.push(current);\n for (const neighbor of adjacency.get(current) ?? []) {\n const newDegree = (inDegree.get(neighbor) ?? 0) - 1;\n inDegree.set(neighbor, newDegree);\n if (newDegree === 0) {\n queue.push(neighbor);\n }\n }\n }\n\n if (result.length !== graph.nodes.length) {\n return undefined;\n }\n return result;\n}\n\nexport function getProducers(\n graph: DataFlowGraph,\n stepId: string,\n): DataFlowNode[] {\n const producerIds = new Set<string>();\n for (const edge of graph.edges) {\n if (edge.to === stepId && edge.from !== '__context__') {\n producerIds.add(edge.from);\n }\n }\n return graph.nodes.filter((n) => producerIds.has(n.id));\n}\n\nexport function getConsumers(\n graph: DataFlowGraph,\n stepId: string,\n): DataFlowNode[] {\n const consumerIds = new Set<string>();\n for (const edge of graph.edges) {\n if (edge.from === stepId) {\n consumerIds.add(edge.to);\n }\n }\n return graph.nodes.filter((n) => consumerIds.has(n.id));\n}\n\nexport function getTransitiveDependencies(\n graph: DataFlowGraph,\n stepId: string,\n): string[] {\n const visited = new Set<string>();\n const result: string[] = [];\n\n function visit(id: string): void {\n if (visited.has(id) || id === '__context__') return;\n visited.add(id);\n for (const edge of graph.edges) {\n if (edge.to === id) {\n result.push(edge.from);\n visit(edge.from);\n }\n }\n }\n\n visit(stepId);\n return result;\n}\n\nexport function findCycles(graph: DataFlowGraph): string[][] {\n const cycles: string[][] = [];\n const visited = new Set<string>();\n const recStack = new Set<string>();\n const adjacency = new Map<string, string[]>();\n\n for (const node of graph.nodes) {\n adjacency.set(node.id, []);\n }\n for (const edge of graph.edges) {\n if (edge.from === '__context__') continue;\n const targets = adjacency.get(edge.from) ?? [];\n targets.push(edge.to);\n adjacency.set(edge.from, targets);\n }\n\n function dfs(id: string, path: string[]): void {\n visited.add(id);\n recStack.add(id);\n path.push(id);\n\n for (const neighbor of adjacency.get(id) ?? []) {\n if (!visited.has(neighbor)) {\n dfs(neighbor, path);\n } else if (recStack.has(neighbor)) {\n const cycleStart = path.indexOf(neighbor);\n cycles.push(path.slice(cycleStart));\n }\n }\n\n path.pop();\n recStack.delete(id);\n }\n\n for (const node of graph.nodes) {\n if (!visited.has(node.id)) {\n dfs(node.id, []);\n }\n }\n\n return cycles;\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\nexport interface DataFlowValidation {\n valid: boolean;\n issues: DataFlowIssue[];\n}\n\nexport interface DataFlowIssue {\n severity: 'error' | 'warning';\n type: 'undefined-read' | 'duplicate-write' | 'cycle';\n message: string;\n stepIds: string[];\n key?: string;\n}\n\nexport function validateDataFlow(graph: DataFlowGraph): DataFlowValidation {\n const issues: DataFlowIssue[] = [];\n\n for (const read of graph.undefinedReads) {\n issues.push({\n severity: 'warning',\n type: 'undefined-read',\n message: `Effect \"${read.readerName ?? read.readerId}\" reads \"${read.key}\" which is never produced`,\n stepIds: [read.readerId],\n key: read.key,\n });\n }\n\n for (const write of graph.duplicateWrites) {\n issues.push({\n severity: 'warning',\n type: 'duplicate-write',\n message: `Key \"${write.key}\" is written by multiple effects: ${write.writerIds.join(', ')}`,\n stepIds: write.writerIds,\n key: write.key,\n });\n }\n\n const cycles = findCycles(graph);\n for (const cycle of cycles) {\n issues.push({\n severity: 'error',\n type: 'cycle',\n message: `Circular data dependency: ${cycle.join(' -> ')}`,\n stepIds: cycle,\n });\n }\n\n return {\n valid: issues.length === 0,\n issues,\n };\n}\n\n// =============================================================================\n// Rendering\n// =============================================================================\n\nfunction sanitizeId(id: string): string {\n return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nexport function renderDataFlowMermaid(graph: DataFlowGraph): string {\n const lines: string[] = [];\n\n lines.push('flowchart LR');\n lines.push('');\n lines.push(' %% Data Flow Graph');\n lines.push('');\n\n for (const node of graph.nodes) {\n const label = node.name ?? node.id;\n const writes = node.writes ? ` [out: ${node.writes}]` : '';\n lines.push(` ${sanitizeId(node.id)}[\"${label}${writes}\"]`);\n }\n\n lines.push('');\n\n for (const edge of graph.edges) {\n if (edge.from === '__context__') continue;\n lines.push(\n ` ${sanitizeId(edge.from)} -->|${edge.key}| ${sanitizeId(edge.to)}`,\n );\n }\n\n if (graph.undefinedReads.length > 0) {\n lines.push('');\n lines.push(' %% Undefined Reads (warnings)');\n for (const read of graph.undefinedReads) {\n const warningId = `undefined_${sanitizeId(read.key)}`;\n lines.push(` ${warningId}[/\"${read.key} (undefined)\"/]`);\n lines.push(` ${warningId} -.-> ${sanitizeId(read.readerId)}`);\n }\n lines.push('');\n lines.push(' classDef warning fill:#fff3cd,stroke:#856404');\n for (const read of graph.undefinedReads) {\n lines.push(` class undefined_${sanitizeId(read.key)} warning`);\n }\n }\n\n return lines.join('\\n');\n}\n","/**\n * Error Flow Analysis for Effect IR\n *\n * Aggregates error types from effect nodes (typeSignature.errorType) and\n * error-handler nodes (catchTag, etc.) to build an error propagation view.\n */\n\nimport type {\n StaticEffectIR,\n StaticFlowNode,\n StaticCauseNode,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { splitTopLevelUnion } from './type-extractor';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface StepErrorInfo {\n stepId: string;\n stepName?: string | undefined;\n errors: string[];\n location?: { line: number; column: number } | undefined;\n}\n\n/** Per-node error propagation: errors at this point and how handlers narrow (GAP 4) */\nexport interface ErrorPropagation {\n atNode: string;\n possibleErrors: string[];\n narrowedBy?: {\n handler: string;\n removedErrors: string[];\n addedErrors: string[];\n };\n defects: string[];\n interruptible: boolean;\n}\n\nexport interface ErrorPropagationAnalysis {\n propagation: ErrorPropagation[];\n byNodeId: Map<string, ErrorPropagation>;\n}\n\nexport interface ErrorFlowAnalysis {\n allErrors: string[];\n stepErrors: StepErrorInfo[];\n errorToSteps: Map<string, string[]>;\n stepsWithoutErrors: string[];\n allStepsDeclareErrors: boolean;\n}\n\nexport interface ErrorFlowEdge {\n stepId: string;\n error: string;\n}\n\nexport interface ErrorValidation {\n valid: boolean;\n unusedDeclared: string[];\n undeclaredErrors: string[];\n computedErrors: string[];\n}\n\n// =============================================================================\n// Helpers: parse error type string (e.g. \"A | B\" or \"never\")\n// =============================================================================\n\nfunction parseErrorTypes(errorType: string): string[] {\n const t = errorType.trim();\n if (t === 'never' || t === 'unknown') {\n return [];\n }\n return splitTopLevelUnion(t);\n}\n\n// =============================================================================\n// Collection\n// =============================================================================\n\nfunction collectEffectErrors(\n nodes: readonly StaticFlowNode[],\n result: StepErrorInfo[],\n): void {\n for (const node of nodes) {\n if (node.type === 'effect') {\n const eff = node;\n const errors = eff.typeSignature?.errorType\n ? parseErrorTypes(eff.typeSignature.errorType)\n : [];\n result.push({\n stepId: eff.id,\n stepName: eff.callee,\n errors,\n location: eff.location\n ? { line: eff.location.line, column: eff.location.column }\n : undefined,\n });\n }\n\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n collectEffectErrors(children, result);\n }\n }\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport function analyzeErrorFlow(ir: StaticEffectIR): ErrorFlowAnalysis {\n const stepErrors: StepErrorInfo[] = [];\n const allErrorsSet = new Set<string>();\n const errorToSteps = new Map<string, string[]>();\n const stepsWithoutErrors: string[] = [];\n\n collectEffectErrors(ir.root.children, stepErrors);\n\n for (const step of stepErrors) {\n if (step.errors.length === 0) {\n stepsWithoutErrors.push(step.stepId);\n }\n for (const error of step.errors) {\n allErrorsSet.add(error);\n const steps = errorToSteps.get(error) ?? [];\n steps.push(step.stepId);\n errorToSteps.set(error, steps);\n }\n }\n\n return {\n allErrors: Array.from(allErrorsSet).sort(),\n stepErrors,\n errorToSteps,\n stepsWithoutErrors,\n allStepsDeclareErrors:\n stepsWithoutErrors.length === 0 && stepErrors.length > 0,\n };\n}\n\n// =============================================================================\n// Error Propagation & Narrowing (GAP 4)\n// =============================================================================\n\nfunction unionErrors(a: string[], b: string[]): string[] {\n return Array.from(new Set([...a, ...b])).sort();\n}\n\nfunction withoutErrors(current: string[], removed: string[]): string[] {\n const set = new Set(removed);\n return current.filter((e) => !set.has(e));\n}\n\n/** Collect error types from a subtree (effect nodes only). */\nfunction collectErrorsFromSubtree(node: StaticFlowNode): string[] {\n const out: string[] = [];\n const visit = (n: StaticFlowNode) => {\n if (n.type === 'effect') {\n const err = (n).typeSignature?.errorType;\n if (err) out.push(...parseErrorTypes(err));\n }\n const children = Option.getOrElse(getStaticChildren(n), () => []);\n children.forEach(visit);\n };\n visit(node);\n return unionErrors([], out);\n}\n\n/** Find the causeKind of the first cause node in a subtree (for cause-aware mapped-error placeholders). */\nfunction findCauseKindInSubtree(node: StaticFlowNode): StaticCauseNode['causeKind'] | undefined {\n if (node.type === 'cause') return (node).causeKind;\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n for (const child of children) {\n const result = findCauseKindInSubtree(child);\n if (result) return result;\n }\n return undefined;\n}\n\n/**\n * Walk IR in execution order, propagating error types and applying narrowing at handlers.\n */\nfunction walkPropagation(\n nodes: readonly StaticFlowNode[],\n errorsIn: string[],\n result: ErrorPropagation[],\n): string[] {\n let current = [...errorsIn];\n for (const node of nodes) {\n if (node.type === 'effect') {\n const eff = node;\n const own = eff.typeSignature?.errorType\n ? parseErrorTypes(eff.typeSignature.errorType)\n : [];\n current = unionErrors(current, own);\n result.push({\n atNode: eff.id,\n possibleErrors: [...current],\n defects: [],\n interruptible: false,\n });\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n current = walkPropagation(children, current, result);\n }\n } else if (node.type === 'error-handler') {\n const handler = node;\n current = walkPropagation([handler.source], current, result);\n const sourceErrors = [...current];\n const removed: string[] = [];\n if (handler.handlerType === 'catchTag' && handler.errorTag) {\n removed.push(handler.errorTag);\n } else if (handler.handlerType === 'catchTags') {\n // Object-form catchTags: use extracted tag keys if available, otherwise\n // fall back to heuristic (names ending in Error or starting with uppercase).\n if (handler.errorTags && handler.errorTags.length > 0) {\n removed.push(\n ...sourceErrors.filter((e) =>\n handler.errorTags ? handler.errorTags.includes(e) : false,\n ),\n );\n } else {\n removed.push(...sourceErrors.filter((e) => /Error$|^[A-Z]/.test(e)));\n }\n } else if (\n handler.handlerType === 'catchIf' ||\n handler.handlerType === 'catchSome' ||\n handler.handlerType === 'catchSomeCause' ||\n handler.handlerType === 'catchSomeDefect'\n ) {\n // Predicate/selective catches remove a subset we cannot fully infer.\n removed.push(...sourceErrors.slice(0, Math.ceil(sourceErrors.length / 2)));\n } else if (\n handler.handlerType === 'catchAll' ||\n handler.handlerType === 'catchAllCause' ||\n handler.handlerType === 'catchAllDefect' ||\n handler.handlerType === 'orElse' ||\n handler.handlerType === 'orDie' ||\n handler.handlerType === 'orDieWith'\n ) {\n removed.push(...sourceErrors);\n } else if (\n handler.handlerType === 'mapError' ||\n handler.handlerType === 'mapErrorCause' ||\n handler.handlerType === 'mapBoth'\n ) {\n // Error type is transformed — remove original errors, add a placeholder\n // since we can't statically determine the mapped-to type without full inference.\n removed.push(...sourceErrors);\n } else if (\n handler.handlerType === 'sandbox'\n ) {\n // sandbox wraps error + defects into Cause — remove typed errors (they become Cause)\n removed.push(...sourceErrors);\n } else if (\n handler.handlerType === 'ignore' ||\n handler.handlerType === 'ignoreLogged'\n ) {\n // ignore silences all errors\n removed.push(...sourceErrors);\n } else if (\n handler.handlerType === 'orElseFail' ||\n handler.handlerType === 'orElseSucceed'\n ) {\n // orElseFail replaces all errors with a new error; orElseSucceed silences them\n removed.push(...sourceErrors);\n } else if (\n handler.handlerType === 'filterOrDie' ||\n handler.handlerType === 'filterOrDieMessage'\n ) {\n // filter predicates that fail convert to defects — remove typed errors\n removed.push(...sourceErrors);\n }\n const afterNarrow = withoutErrors(current, removed);\n let handlerErrors = handler.handler\n ? collectErrorsFromSubtree(handler.handler)\n : [];\n // For mapping transforms: errors are replaced, not eliminated — mark as transformed.\n // When the source includes a cause node with a known causeKind, use a more specific placeholder.\n if (\n (handler.handlerType === 'mapError' ||\n handler.handlerType === 'mapErrorCause' ||\n handler.handlerType === 'mapBoth') &&\n removed.length > 0 &&\n handlerErrors.length === 0\n ) {\n const causeKind = findCauseKindInSubtree(handler.source);\n if (causeKind === 'fail') handlerErrors = ['<mapped-fail>'];\n else if (causeKind === 'die') handlerErrors = ['<mapped-defect>'];\n else handlerErrors = ['<mapped-error>'];\n }\n current = unionErrors(afterNarrow, handlerErrors);\n result.push({\n atNode: handler.id,\n possibleErrors: [...current],\n narrowedBy: {\n handler: handler.handlerType,\n removedErrors: removed,\n addedErrors: handlerErrors,\n },\n defects: [],\n interruptible: false,\n });\n if (handler.handler) {\n current = walkPropagation([handler.handler], current, result);\n }\n } else if (node.type === 'parallel' || node.type === 'race') {\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n let branchErrors: string[] = [];\n for (const child of children) {\n const fromChild = walkPropagation([child], current, result);\n branchErrors = unionErrors(branchErrors, fromChild);\n }\n current = branchErrors;\n } else {\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n current = walkPropagation(children, current, result);\n }\n }\n }\n return current;\n}\n\nexport function analyzeErrorPropagation(ir: StaticEffectIR): ErrorPropagationAnalysis {\n const propagation: ErrorPropagation[] = [];\n walkPropagation(ir.root.children, [], propagation);\n const byNodeId = new Map<string, ErrorPropagation>();\n for (const p of propagation) {\n byNodeId.set(p.atNode, p);\n }\n return { propagation, byNodeId };\n}\n\n// =============================================================================\n// Error Propagation\n// =============================================================================\n\nexport function getErrorsAtPoint(\n analysis: ErrorFlowAnalysis,\n afterStepId: string,\n): string[] {\n const errors = new Set<string>();\n let found = false;\n\n for (const step of analysis.stepErrors) {\n for (const error of step.errors) {\n errors.add(error);\n }\n if (step.stepId === afterStepId) {\n found = true;\n break;\n }\n }\n\n if (!found) {\n return analysis.allErrors;\n }\n return Array.from(errors).sort();\n}\n\nexport function getErrorProducers(\n analysis: ErrorFlowAnalysis,\n errorTag: string,\n): StepErrorInfo[] {\n const stepIds = analysis.errorToSteps.get(errorTag) ?? [];\n return analysis.stepErrors.filter((s) => stepIds.includes(s.stepId));\n}\n\n// =============================================================================\n// Validation\n// =============================================================================\n\nexport function validateWorkflowErrors(\n analysis: ErrorFlowAnalysis,\n declaredErrors: string[],\n): ErrorValidation {\n const declaredSet = new Set(declaredErrors);\n const computedSet = new Set(analysis.allErrors);\n\n const unusedDeclared = declaredErrors.filter((e) => !computedSet.has(e));\n const undeclaredErrors = analysis.allErrors.filter((e) => !declaredSet.has(e));\n\n return {\n valid:\n unusedDeclared.length === 0 && undeclaredErrors.length === 0,\n unusedDeclared,\n undeclaredErrors,\n computedErrors: analysis.allErrors,\n };\n}\n\n// =============================================================================\n// Rendering\n// =============================================================================\n\nfunction sanitizeId(id: string): string {\n return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nexport function renderErrorFlowMermaid(analysis: ErrorFlowAnalysis): string {\n const lines: string[] = [];\n\n lines.push('flowchart LR');\n lines.push('');\n lines.push(' %% Error Flow Graph');\n lines.push('');\n\n lines.push(' subgraph Steps');\n for (const step of analysis.stepErrors) {\n const label = step.stepName ?? step.stepId;\n lines.push(` ${sanitizeId(step.stepId)}[\"${label}\"]`);\n }\n lines.push(' end');\n lines.push('');\n\n if (analysis.allErrors.length > 0) {\n lines.push(' subgraph Errors');\n for (const error of analysis.allErrors) {\n lines.push(` err_${sanitizeId(error)}([\"${error}\"])`);\n }\n lines.push(' end');\n lines.push('');\n\n for (const step of analysis.stepErrors) {\n for (const error of step.errors) {\n lines.push(\n ` ${sanitizeId(step.stepId)} -.->|throws| err_${sanitizeId(error)}`,\n );\n }\n }\n }\n\n lines.push('');\n lines.push(' classDef error fill:#ffcdd2,stroke:#c62828');\n for (const error of analysis.allErrors) {\n lines.push(` class err_${sanitizeId(error)} error`);\n }\n\n if (analysis.stepsWithoutErrors.length > 0) {\n lines.push('');\n lines.push(' classDef noErrors fill:#fff3cd,stroke:#856404');\n for (const stepId of analysis.stepsWithoutErrors) {\n lines.push(` class ${sanitizeId(stepId)} noErrors`);\n }\n }\n\n return lines.join('\\n');\n}\n\nexport function formatErrorSummary(analysis: ErrorFlowAnalysis): string {\n const lines: string[] = [];\n\n lines.push('## Error Flow Summary');\n lines.push('');\n\n lines.push(`**Total Effects:** ${analysis.stepErrors.length}`);\n lines.push(`**Total Error Types:** ${analysis.allErrors.length}`);\n lines.push(\n `**Effects Without Declared Errors:** ${analysis.stepsWithoutErrors.length}`,\n );\n lines.push('');\n\n if (analysis.allErrors.length > 0) {\n lines.push('### Error Types');\n lines.push('');\n for (const error of analysis.allErrors) {\n const producers = analysis.errorToSteps.get(error) ?? [];\n lines.push(`- \\`${error}\\` - produced by: ${producers.join(', ')}`);\n }\n lines.push('');\n }\n\n if (analysis.stepsWithoutErrors.length > 0) {\n lines.push('### Effects Without Declared Errors');\n lines.push('');\n lines.push(\n 'The following effects do not declare their error type (typeSignature.errorType):',\n );\n lines.push('');\n for (const stepId of analysis.stepsWithoutErrors) {\n lines.push(`- ${stepId}`);\n }\n lines.push('');\n }\n\n lines.push('### Effect Error Details');\n lines.push('');\n lines.push('| Effect | Errors |');\n lines.push('|--------|--------|');\n for (const step of analysis.stepErrors) {\n const name = step.stepName ?? step.stepId;\n const errors =\n step.errors.length > 0\n ? step.errors.map((e) => `\\`${e}\\``).join(', ')\n : '_none_';\n lines.push(`| ${name} | ${errors} |`);\n }\n\n return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { splitTopLevelUnion } from '../type-extractor';\n\ninterface RailwayStep {\n readonly label: string;\n readonly errorTypes: readonly string[];\n}\n\ninterface RailwayOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n/** Generate a short node ID: A–Z, then A1–Z1, A2–Z2, etc. */\nfunction stepId(index: number): string {\n const letter = String.fromCharCode(65 + (index % 26));\n const cycle = Math.floor(index / 26);\n return cycle === 0 ? letter : `${letter}${cycle}`;\n}\n\n/** Escape characters that break Mermaid label syntax. */\nfunction escapeLabel(text: string): string {\n return text\n .replace(/\"/g, '#quot;')\n .replace(/</g, '#lt;')\n .replace(/>/g, '#gt;')\n .replace(/\\(/g, '#lpar;')\n .replace(/\\)/g, '#rpar;');\n}\n\n/** Strip trailing \"Error\" or \"Exception\" suffix from a type name. */\nfunction stripErrorSuffix(name: string): string {\n return name.replace(/(Error|Exception)$/, '');\n}\n\n/** Extract error types string from a node, split into individual type names. */\nfunction extractErrorTypes(node: StaticFlowNode): readonly string[] {\n let raw: string | undefined;\n\n if (node.type === 'effect') {\n raw = node.typeSignature?.errorType ?? node.errorType;\n } else if ('typeSignature' in node && node.typeSignature) {\n raw = (node.typeSignature as { errorType?: string }).errorType;\n }\n\n if (!raw || raw === 'never' || raw.trim() === '') return [];\n\n return splitTopLevelUnion(raw)\n .filter(s => s !== 'never');\n}\n\n/** Recursively collect error types from a node and its descendants. */\nfunction collectErrorTypes(node: StaticFlowNode): readonly string[] {\n const seen = new Set<string>();\n const errors: string[] = [];\n\n const visit = (current: StaticFlowNode): void => {\n for (const errorType of extractErrorTypes(current)) {\n if (!seen.has(errorType)) {\n seen.add(errorType);\n errors.push(errorType);\n }\n }\n\n const children = Option.getOrElse(getStaticChildren(current), () => []);\n for (const child of children) {\n visit(child);\n }\n };\n\n visit(node);\n return errors;\n}\n\n/** Compute a display label for a flow node. */\nfunction computeLabel(node: StaticFlowNode): string {\n if (node.displayName) return node.displayName;\n if (node.type === 'effect') {\n if (node.name) {\n const stripped = node.name.replace(/^Effect\\./, '');\n return stripped.charAt(0).toUpperCase() + stripped.slice(1);\n }\n return node.callee.replace(/^Effect\\./, '');\n }\n if (node.name) return node.name;\n if (node.type === 'parallel') return 'Effect.all';\n if (node.type === 'race') return 'Effect.race';\n if (node.type === 'error-handler') return 'Error Handler';\n if (node.type === 'retry') return 'Retry';\n if (node.type === 'conditional') return 'Conditional';\n return node.type;\n}\n\n/** Transparent: recurse into children, don't show this node itself. */\nfunction isTransparentRailwayNode(node: StaticFlowNode): boolean {\n switch (node.type) {\n case 'generator':\n case 'pipe':\n return true;\n default:\n return false;\n }\n}\n\n/** Show as a single labeled step — don't recurse into children. */\nfunction isOpaqueRailwayStep(node: StaticFlowNode): boolean {\n switch (node.type) {\n case 'loop':\n case 'conditional':\n case 'decision':\n case 'switch':\n case 'parallel':\n case 'race':\n case 'retry':\n case 'timeout':\n case 'resource':\n return true;\n default:\n return false;\n }\n}\n\n/** Skip entirely — don't show, don't recurse. Shown in other views. */\nfunction isSkippedRailwayNode(node: StaticFlowNode): boolean {\n switch (node.type) {\n case 'error-handler':\n case 'transform':\n case 'stream':\n case 'channel':\n case 'sink':\n case 'concurrency-primitive':\n case 'fiber':\n case 'interruption':\n case 'try-catch':\n case 'terminal':\n return true;\n default:\n return false;\n }\n}\n\n/**\n * Check if an effect node is a definition/constructor that shouldn't appear\n * as a step in the railway view. These are service method definitions,\n * constructors, and other non-workflow nodes.\n */\nfunction isSkippableEffectNode(node: StaticFlowNode): boolean {\n if (node.type !== 'effect') return false;\n const callee = (node as { callee?: string }).callee ?? '';\n\n // Effect.fn / Effect.fn(\"name\") — service method definitions\n if (callee === 'Effect.fn' || callee.startsWith('Effect.fn(')) return true;\n\n // Pure constructors without a meaningful display name (anonymous yields in service setup)\n // A node is \"anonymous\" if it has no meaningful display name —\n // displayName is either absent, equals the raw callee, or is a generic type name\n const displayName = node.displayName ?? '';\n const hasExplicitName = displayName && displayName !== callee && displayName !== node.type;\n const isAnonymous = !hasExplicitName;\n // Anonymous effect nodes (no variable binding) are infrastructure/plumbing — skip\n if (isAnonymous) return true;\n\n // Schema/Data definitions are type declarations, not workflow steps\n if (callee.startsWith('Schema.') || callee.startsWith('Data.')) return true;\n\n return false;\n}\n\n/** Flatten IR children to a linear list of concrete steps for the railway diagram. */\nfunction flattenNodesToSteps(nodes: readonly StaticFlowNode[]): readonly StaticFlowNode[] {\n const steps: StaticFlowNode[] = [];\n\n const visit = (node: StaticFlowNode): void => {\n // Transparent: recurse into children (generator, pipe wrappers)\n if (isTransparentRailwayNode(node)) {\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n for (const child of children) {\n visit(child);\n }\n return;\n }\n\n // Skip entirely: error handlers, transforms, streams, etc.\n if (isSkippedRailwayNode(node)) return;\n\n // Opaque: show as single box, don't recurse (loops, conditionals, parallel, etc.)\n if (isOpaqueRailwayStep(node)) {\n steps.push(node);\n return;\n }\n\n // Effect nodes: skip method definitions and anonymous constructors\n if (isSkippableEffectNode(node)) return;\n\n steps.push(node);\n };\n\n for (const node of nodes) {\n visit(node);\n }\n\n return steps;\n}\n\n/** Build railway step descriptors from flow nodes. */\nfunction buildSteps(nodes: readonly StaticFlowNode[]): readonly RailwayStep[] {\n return nodes.map(node => ({\n label: computeLabel(node),\n errorTypes: collectErrorTypes(node),\n }));\n}\n\n/**\n * Render a railway-oriented Mermaid flowchart from an Effect IR.\n *\n * Happy path flows left-to-right with `-->|ok|` edges.\n * Steps with typed errors get `-->|err|` branches to error nodes.\n */\nexport function renderRailwayMermaid(\n ir: StaticEffectIR,\n options: RailwayOptions = {},\n): string {\n const direction = options.direction ?? 'LR';\n const nodes = flattenNodesToSteps(ir.root.children);\n const steps = buildSteps(nodes);\n\n if (steps.length === 0) {\n return `flowchart ${direction}\\n Empty((No steps))`;\n }\n\n const lines: string[] = [`flowchart ${direction}`];\n const errorLines: string[] = [];\n\n const hasPerStepErrors = steps.some(s => s.errorTypes.length > 0);\n\n for (let i = 0; i < steps.length; i++) {\n const currentStep = steps[i];\n if (!currentStep) continue;\n const id = stepId(i);\n const label = escapeLabel(currentStep.label);\n\n if (i < steps.length - 1) {\n const nextStep = steps[i + 1];\n if (!nextStep) continue;\n const nextId = stepId(i + 1);\n const nextLabel = escapeLabel(nextStep.label);\n if (i === 0) {\n lines.push(` ${id}[${label}] -->|ok| ${nextId}[${nextLabel}]`);\n } else {\n lines.push(` ${id} -->|ok| ${nextId}[${nextLabel}]`);\n }\n } else {\n if (i === 0) {\n lines.push(` ${id}[${label}] -->|ok| Done((Success))`);\n } else {\n lines.push(` ${id} -->|ok| Done((Success))`);\n }\n }\n }\n\n if (hasPerStepErrors) {\n for (let i = 0; i < steps.length; i++) {\n const currentStep = steps[i];\n if (!currentStep) continue;\n const { errorTypes } = currentStep;\n if (errorTypes.length === 0) continue;\n\n const id = stepId(i);\n const errId = `${id}E`;\n const errLabel = escapeLabel(\n errorTypes.map(stripErrorSuffix).join(' / ')\n );\n errorLines.push(` ${id} -->|err| ${errId}[${errLabel}]`);\n }\n } else if (ir.root.errorTypes.length > 0) {\n const lastId = stepId(steps.length - 1);\n const errLabel = escapeLabel(\n ir.root.errorTypes.map(stripErrorSuffix).join(' / ')\n );\n errorLines.push(` ${lastId} -->|err| Errors[${errLabel}]`);\n }\n\n return [...lines, ...errorLines].join('\\n');\n}\n","/**\n * Service (R) Flow Analysis (GAP 3)\n *\n * Tracks which services each effect requires, where they are provided,\n * and where R is still unsatisfied.\n */\n\nimport type {\n StaticEffectIR,\n StaticFlowNode,\n StaticEffectNode,\n ServiceRequirement,\n SourceLocation,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ServiceProvision {\n nodeId: string;\n serviceId: string;\n location?: SourceLocation;\n}\n\nexport interface UnsatisfiedService {\n nodeId: string;\n serviceId: string;\n serviceType?: string;\n location?: SourceLocation;\n}\n\nexport interface ServiceLifecycleEntry {\n createdAt: string;\n consumedAt: string[];\n releasedAt?: string;\n}\n\nexport interface ServiceFlowAnalysis {\n requiredServices: ServiceRequirement[];\n providedServices: ServiceProvision[];\n unsatisfiedAt: UnsatisfiedService[];\n serviceLifecycle: Map<string, ServiceLifecycleEntry>;\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction collectRequiredFromNode(\n node: StaticFlowNode,\n result: ServiceRequirement[],\n): void {\n if (node.type === 'effect') {\n const eff = node;\n const reqs = eff.requiredServices ?? [];\n for (const r of reqs) {\n if (!result.some((x) => x.serviceId === r.serviceId)) {\n result.push(r);\n }\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n for (const c of children) collectRequiredFromNode(c, result);\n}\n\n/** Heuristic: detect provide/provideService from effect callee and first arg. */\nfunction getProvidedServiceId(\n node: StaticEffectNode,\n getFirstArgText: (node: StaticEffectNode) => string | undefined,\n): string | undefined {\n const callee = node.callee;\n if (callee.includes('provideService') || callee.includes('provide')) {\n return getFirstArgText(node);\n }\n return undefined;\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\n/**\n * Build service flow analysis from IR.\n * Tracks required vs provided services and unsatisfied requirements at each node.\n */\nexport function analyzeServiceFlow(\n ir: StaticEffectIR,\n options?: {\n /** Optional: resolve effect node to its AST to read first arg (for provideService). */\n getFirstArgText?: (effectNode: StaticEffectNode) => string | undefined;\n },\n): ServiceFlowAnalysis {\n const requiredServices: ServiceRequirement[] = [];\n for (const child of ir.root.children) {\n collectRequiredFromNode(child, requiredServices);\n }\n const dedupedRequired = Array.from(\n new Map(requiredServices.map((r) => [r.serviceId, r])).values(),\n );\n\n const providedServices: ServiceProvision[] = [];\n const unsatisfiedAt: UnsatisfiedService[] = [];\n const consumedBy = new Map<string, string[]>();\n\n const available = new Set<string>();\n const getFirstArg = options?.getFirstArgText;\n\n function walk(nodes: readonly StaticFlowNode[]) {\n for (const node of nodes) {\n if (node.type === 'effect') {\n const eff = node;\n const providedId = getFirstArg ? getProvidedServiceId(eff, getFirstArg) : undefined;\n if (providedId) {\n available.add(providedId);\n const prov: ServiceProvision = { nodeId: eff.id, serviceId: providedId };\n if (eff.location) prov.location = eff.location;\n providedServices.push(prov);\n }\n const reqs = eff.requiredServices ?? [];\n for (const r of reqs) {\n const list = consumedBy.get(r.serviceId) ?? [];\n list.push(eff.id);\n consumedBy.set(r.serviceId, list);\n if (!available.has(r.serviceId)) {\n const u: UnsatisfiedService = { nodeId: eff.id, serviceId: r.serviceId };\n if (r.serviceType !== undefined) u.serviceType = r.serviceType;\n if (r.requiredAt !== undefined) u.location = r.requiredAt;\n unsatisfiedAt.push(u);\n }\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) walk(children);\n }\n }\n walk(ir.root.children);\n\n const serviceLifecycle = new Map<string, ServiceLifecycleEntry>();\n for (const p of providedServices) {\n serviceLifecycle.set(p.serviceId, {\n createdAt: p.nodeId,\n consumedAt: consumedBy.get(p.serviceId) ?? [],\n });\n }\n for (const r of dedupedRequired) {\n if (!serviceLifecycle.has(r.serviceId)) {\n serviceLifecycle.set(r.serviceId, {\n createdAt: '',\n consumedAt: consumedBy.get(r.serviceId) ?? [],\n });\n }\n }\n\n return {\n requiredServices: dedupedRequired,\n providedServices,\n unsatisfiedAt,\n serviceLifecycle,\n };\n}\n","/**\n * Mermaid renderer for the R channel (service/dependency) graph.\n *\n * Two modes:\n * - Single-file: `renderServicesMermaid(ir)` — shows required vs provided services for one program.\n * - Project-wide: `renderServicesMermaidFromMap(serviceMap)` — shows the full service dependency graph.\n */\n\nimport type { StaticEffectIR, ProjectServiceMap } from '../types';\nimport { analyzeServiceFlow } from '../service-flow';\n\ninterface ServicesOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\nfunction escapeLabel(text: string): string {\n return text\n .replace(/\"/g, '#quot;')\n .replace(/</g, '#lt;')\n .replace(/>/g, '#gt;')\n .replace(/\\(/g, '#lpar;')\n .replace(/\\)/g, '#rpar;');\n}\n\nfunction sanitizeId(text: string): string {\n return text.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n/**\n * Render a Mermaid flowchart showing the R channel for a single IR.\n *\n * - Program node as a rectangle\n * - Required services as blue hexagons with `requires` edges\n * - Provided services as green hexagons with `provides` edges\n */\nexport function renderServicesMermaid(\n ir: StaticEffectIR,\n options: ServicesOptions = {},\n): string {\n const direction = options.direction ?? 'LR';\n const { requiredServices, providedServices } = analyzeServiceFlow(ir);\n\n // Also collect dependencies from the IR root (includes environment yields)\n const depsFromIR = ir.root.dependencies;\n const allServiceIds = new Set<string>();\n for (const req of requiredServices) allServiceIds.add(req.serviceId);\n for (const dep of depsFromIR) allServiceIds.add(dep.name);\n\n if (allServiceIds.size === 0 && providedServices.length === 0) {\n return `flowchart ${direction}\\n NoServices((No services))`;\n }\n\n const lines: string[] = [`flowchart ${direction}`];\n const programName = escapeLabel(ir.root.programName);\n\n lines.push(` prog[\"${programName}\"]`);\n lines.push('');\n\n // Required services — hexagon nodes with requires edges\n // Combine from analyzeServiceFlow and IR root dependencies\n for (const serviceId of allServiceIds) {\n const id = `svc_${sanitizeId(serviceId)}`;\n const label = escapeLabel(serviceId);\n lines.push(` ${id}{{\"${label}\"}}`);\n lines.push(` prog -->|requires| ${id}`);\n }\n\n // Provided services — hexagon nodes with provides edges\n for (const prov of providedServices) {\n const id = `prov_${sanitizeId(prov.serviceId)}`;\n const label = escapeLabel(prov.serviceId);\n lines.push(` ${id}{{\"${label}\"}}`);\n lines.push(` ${id} -->|provides| prog`);\n }\n\n lines.push('');\n\n // Styling\n lines.push(' classDef required fill:#E3F2FD,stroke:#1565C0,stroke-width:2px');\n lines.push(' classDef provided fill:#E8F5E9,stroke:#2E7D32,stroke-width:2px');\n for (const req of requiredServices) {\n lines.push(` class svc_${sanitizeId(req.serviceId)} required`);\n }\n for (const prov of providedServices) {\n lines.push(` class prov_${sanitizeId(prov.serviceId)} provided`);\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Render a Mermaid flowchart for a project-wide service dependency graph.\n *\n * - Each service is a hexagon node\n * - Edges show layer dependencies\n * - Unresolved services are dashed\n */\nexport function renderServicesMermaidFromMap(\n serviceMap: ProjectServiceMap,\n options: ServicesOptions = {},\n): string {\n const direction = options.direction ?? 'TB';\n const lines: string[] = [`flowchart ${direction}`];\n lines.push('');\n lines.push(' %% Service Dependency Graph');\n lines.push('');\n\n // Service nodes (hexagon shape)\n for (const [serviceId, artifact] of serviceMap.services) {\n const id = sanitizeId(serviceId);\n const methodCount = artifact.definition.methods.length;\n const label =\n methodCount > 0\n ? `${serviceId}\\\\n(${methodCount} method${methodCount === 1 ? '' : 's'})`\n : serviceId;\n lines.push(` ${id}{{\"${label}\"}}`);\n }\n\n // Unresolved services (dashed)\n for (const serviceId of serviceMap.unresolvedServices) {\n const id = `unresolved_${sanitizeId(serviceId)}`;\n lines.push(` ${id}[\"? ${serviceId}\"]`);\n }\n lines.push('');\n\n // Edges: service requires other services (via layers)\n const edgesAdded = new Set<string>();\n for (const [serviceId, artifact] of serviceMap.services) {\n for (const layer of artifact.layerImplementations) {\n for (const req of layer.requires) {\n const edgeKey = `${serviceId}->${req}`;\n if (edgesAdded.has(edgeKey)) continue;\n edgesAdded.add(edgeKey);\n\n const fromId = sanitizeId(serviceId);\n const toId = serviceMap.services.has(req)\n ? sanitizeId(req)\n : `unresolved_${sanitizeId(req)}`;\n lines.push(` ${fromId} -->|\"${layer.name}\"| ${toId}`);\n }\n }\n }\n lines.push('');\n\n // Styling\n lines.push(' classDef service fill:#E3F2FD,stroke:#1565C0,stroke-width:2px');\n lines.push(' classDef unresolved fill:#FFF3CD,stroke:#856404,stroke-dasharray:5');\n for (const serviceId of serviceMap.services.keys()) {\n lines.push(` class ${sanitizeId(serviceId)} service`);\n }\n for (const serviceId of serviceMap.unresolvedServices) {\n lines.push(` class unresolved_${sanitizeId(serviceId)} unresolved`);\n }\n\n return lines.join('\\n');\n}\n","import type { StaticEffectIR } from '../types';\nimport { analyzeErrorFlow } from '../error-flow';\nimport { analyzeErrorPropagation } from '../error-flow';\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\n/** Escape characters that break Mermaid label syntax. */\nfunction escapeLabel(text: string): string {\n return text\n .replace(/\"/g, '#quot;')\n .replace(/</g, '#lt;')\n .replace(/>/g, '#gt;')\n .replace(/\\(/g, '#lpar;')\n .replace(/\\)/g, '#rpar;');\n}\n\n/** Replace non-alphanumeric characters with underscores for Mermaid node IDs. */\nfunction sanitizeId(text: string): string {\n return text.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n/** Strip trailing \"Error\" or \"Exception\" suffix from a type name. */\nfunction stripErrorSuffix(name: string): string {\n return name.replace(/(Error|Exception)$/, '');\n}\n\n// =============================================================================\n// Options\n// =============================================================================\n\ninterface MermaidErrorsOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n// =============================================================================\n// Renderer\n// =============================================================================\n\n/**\n * Render a Mermaid flowchart showing error propagation:\n * - Steps (left): which steps produce errors\n * - Error types (middle): the error type nodes\n * - Handlers (right): which handlers catch which errors\n * - Unhandled: errors that are never caught\n */\nexport function renderErrorsMermaid(\n ir: StaticEffectIR,\n options: MermaidErrorsOptions = {},\n): string {\n const direction = options.direction ?? 'LR';\n const errorFlow = analyzeErrorFlow(ir);\n const propagation = analyzeErrorPropagation(ir);\n\n // No errors at all → simple empty output\n if (errorFlow.allErrors.length === 0) {\n return `flowchart ${direction}\\n NoErrors((No errors))`;\n }\n\n const lines: string[] = [`flowchart ${direction}`];\n\n // Collect handler info from propagation analysis\n const handlerNodes: { id: string; label: string; removedErrors: string[] }[] = [];\n const handledErrors = new Set<string>();\n\n for (const p of propagation.propagation) {\n if (p.narrowedBy && p.narrowedBy.removedErrors.length > 0) {\n const handlerId = `handler_${sanitizeId(p.atNode)}`;\n handlerNodes.push({\n id: handlerId,\n label: p.narrowedBy.handler,\n removedErrors: p.narrowedBy.removedErrors,\n });\n for (const err of p.narrowedBy.removedErrors) {\n handledErrors.add(err);\n }\n }\n }\n\n // Determine unhandled errors\n const unhandledErrors = errorFlow.allErrors.filter(e => !handledErrors.has(e));\n\n // --- Steps subgraph (left column) ---\n const stepsWithErrors = errorFlow.stepErrors.filter(s => s.errors.length > 0);\n if (stepsWithErrors.length > 0) {\n lines.push('');\n lines.push(' subgraph Steps');\n for (const step of stepsWithErrors) {\n const label = escapeLabel(step.stepName ?? step.stepId);\n lines.push(` step_${sanitizeId(step.stepId)}[\"${label}\"]`);\n }\n lines.push(' end');\n }\n\n // --- Error types subgraph (middle column) ---\n lines.push('');\n lines.push(' subgraph Errors');\n for (const error of errorFlow.allErrors) {\n const label = escapeLabel(stripErrorSuffix(error));\n lines.push(` err_${sanitizeId(error)}(\"${label}\")`);\n }\n lines.push(' end');\n\n // --- Handlers subgraph (right column) ---\n if (handlerNodes.length > 0) {\n lines.push('');\n lines.push(' subgraph Handlers');\n for (const handler of handlerNodes) {\n const label = escapeLabel(handler.label);\n lines.push(` ${handler.id}[\"${label}\"]`);\n }\n lines.push(' end');\n }\n\n // --- Unhandled node ---\n if (unhandledErrors.length > 0) {\n lines.push('');\n lines.push(' UNHANDLED[\"UNHANDLED\"]');\n }\n\n // --- Edges: step --produces--> error ---\n lines.push('');\n for (const step of stepsWithErrors) {\n for (const error of step.errors) {\n lines.push(` step_${sanitizeId(step.stepId)} --produces--> err_${sanitizeId(error)}`);\n }\n }\n\n // --- Edges: error --caught by--> handler ---\n for (const handler of handlerNodes) {\n for (const error of handler.removedErrors) {\n if (errorFlow.allErrors.includes(error)) {\n lines.push(` err_${sanitizeId(error)} --caught by--> ${handler.id}`);\n }\n }\n }\n\n // --- Edges: unhandled errors --> UNHANDLED ---\n for (const error of unhandledErrors) {\n lines.push(` err_${sanitizeId(error)} --unhandled--> UNHANDLED`);\n }\n\n // --- Styling ---\n lines.push('');\n lines.push(' classDef stepStyle fill:#BBDEFB');\n lines.push(' classDef errorStyle fill:#FFE0B2');\n lines.push(' classDef handlerStyle fill:#C8E6C9');\n lines.push(' classDef unhandledStyle fill:#FFCDD2');\n\n // Apply styles\n for (const step of stepsWithErrors) {\n lines.push(` class step_${sanitizeId(step.stepId)} stepStyle`);\n }\n for (const error of errorFlow.allErrors) {\n lines.push(` class err_${sanitizeId(error)} errorStyle`);\n }\n for (const handler of handlerNodes) {\n lines.push(` class ${handler.id} handlerStyle`);\n }\n if (unhandledErrors.length > 0) {\n lines.push(' class UNHANDLED unhandledStyle');\n }\n\n return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\n\ninterface DecisionsOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\nconst DECISION_TYPES = new Set(['conditional', 'decision', 'switch', 'match']);\n\n/** Escape characters that break Mermaid label syntax. */\nfunction escapeLabel(text: string): string {\n return text\n .replace(/\"/g, '#quot;')\n .replace(/</g, '#lt;')\n .replace(/>/g, '#gt;')\n .replace(/\\(/g, '#lpar;')\n .replace(/\\)/g, '#rpar;');\n}\n\n/** Truncate text to a maximum length, appending ellipsis if needed. */\nfunction truncate(text: string, max = 40): string {\n return text.length > max ? text.slice(0, max - 3) + '...' : text;\n}\n\n/** Compute a display label for a flow node. */\nfunction nodeLabel(node: StaticFlowNode): string {\n if (node.displayName) return node.displayName;\n if (node.name) return node.name;\n if (node.type === 'effect') return node.callee;\n return node.type;\n}\n\ninterface DecisionInfo {\n readonly node: StaticFlowNode;\n readonly nodeId: string;\n}\n\n/** Recursively collect all decision-type nodes from the IR tree. */\nfunction collectDecisionNodes(nodes: readonly StaticFlowNode[]): DecisionInfo[] {\n const result: DecisionInfo[] = [];\n let counter = 0;\n\n const visit = (node: StaticFlowNode): void => {\n if (DECISION_TYPES.has(node.type)) {\n result.push({ node, nodeId: `D${counter++}` });\n }\n\n // Walk into children from getStaticChildren\n const children = Option.getOrElse(getStaticChildren(node), () => [] as readonly StaticFlowNode[]);\n for (const child of children) {\n visit(child);\n }\n\n // Also walk into branch-specific children not covered by getStaticChildren\n if (node.type === 'conditional') {\n const cond = node;\n visit(cond.onTrue);\n if (cond.onFalse) visit(cond.onFalse);\n } else if (node.type === 'decision') {\n const dec = node;\n for (const child of dec.onTrue) visit(child);\n if (dec.onFalse) for (const child of dec.onFalse) visit(child);\n } else if (node.type === 'switch') {\n const sw = node;\n for (const c of sw.cases) {\n for (const child of c.body) visit(child);\n }\n }\n };\n\n for (const node of nodes) {\n visit(node);\n }\n\n return result;\n}\n\n/** Find a decision info entry by node reference. */\nfunction findDecisionInfo(decisions: DecisionInfo[], node: StaticFlowNode): DecisionInfo | undefined {\n return decisions.find(d => d.node === node);\n}\n\n/** Find the first decision node in a list of nodes. */\nfunction findFirstDecision(decisions: DecisionInfo[], nodes: readonly StaticFlowNode[]): DecisionInfo | undefined {\n for (const node of nodes) {\n const found = findDecisionInfo(decisions, node);\n if (found) return found;\n }\n return undefined;\n}\n\n/** Render a terminal node ID and its definition line for a branch target. */\nfunction renderBranchTarget(\n node: StaticFlowNode | undefined,\n decisions: DecisionInfo[],\n terminalCounter: { value: number },\n): { targetId: string; extraLine?: string } {\n if (!node) {\n const tId = `T${terminalCounter.value++}`;\n return { targetId: tId, extraLine: ` ${tId}[\"...\"]` };\n }\n\n const decInfo = findDecisionInfo(decisions, node);\n if (decInfo) {\n return { targetId: decInfo.nodeId };\n }\n\n const label = escapeLabel(nodeLabel(node));\n const tId = `T${terminalCounter.value++}`;\n return { targetId: tId, extraLine: ` ${tId}[\"${label}\"]` };\n}\n\n/** Render a branch target from an array of nodes. */\nfunction renderArrayBranchTarget(\n nodes: readonly StaticFlowNode[] | undefined,\n decisions: DecisionInfo[],\n terminalCounter: { value: number },\n): { targetId: string; extraLine?: string } {\n if (!nodes || nodes.length === 0) {\n const tId = `T${terminalCounter.value++}`;\n return { targetId: tId, extraLine: ` ${tId}[\"...\"]` };\n }\n\n // Check if any node in the array is a decision node\n const dec = findFirstDecision(decisions, nodes);\n if (dec) {\n return { targetId: dec.nodeId };\n }\n\n const firstNode = nodes[0];\n if (!firstNode) {\n const tId = `T${terminalCounter.value++}`;\n return { targetId: tId, extraLine: ` ${tId}[\"...\"]` };\n }\n const label = escapeLabel(nodeLabel(firstNode));\n const tId = `T${terminalCounter.value++}`;\n return { targetId: tId, extraLine: ` ${tId}[\"${label}\"]` };\n}\n\n/**\n * Render a decision-tree Mermaid flowchart from an Effect IR.\n *\n * Decision nodes (conditional, decision, switch, match) are rendered as\n * diamond-shaped nodes with labeled edges to their branches.\n */\nexport function renderDecisionsMermaid(\n ir: StaticEffectIR,\n options: DecisionsOptions = {},\n): string {\n const direction = options.direction ?? 'TB';\n const decisions = collectDecisionNodes(ir.root.children);\n\n if (decisions.length === 0) {\n return `flowchart ${direction}\\n NoDec((No decisions))`;\n }\n\n const lines: string[] = [`flowchart ${direction}`];\n const terminalCounter = { value: 0 };\n\n for (const { node, nodeId } of decisions) {\n switch (node.type) {\n case 'conditional': {\n const cond = node;\n const condText = escapeLabel(truncate(cond.condition));\n lines.push(` ${nodeId}{${condText}}`);\n\n const trueLabel = cond.trueEdgeLabel ?? 'true';\n const falseLabel = cond.falseEdgeLabel ?? 'false';\n\n const trueBranch = renderBranchTarget(cond.onTrue, decisions, terminalCounter);\n if (trueBranch.extraLine) lines.push(trueBranch.extraLine);\n lines.push(` ${nodeId} -->|${trueLabel}| ${trueBranch.targetId}`);\n\n if (cond.onFalse) {\n const falseBranch = renderBranchTarget(cond.onFalse, decisions, terminalCounter);\n if (falseBranch.extraLine) lines.push(falseBranch.extraLine);\n lines.push(` ${nodeId} -->|${falseLabel}| ${falseBranch.targetId}`);\n }\n break;\n }\n\n case 'decision': {\n const dec = node;\n const condText = escapeLabel(truncate(dec.condition));\n lines.push(` ${nodeId}{${condText}}`);\n\n const trueBranch = renderArrayBranchTarget(dec.onTrue, decisions, terminalCounter);\n if (trueBranch.extraLine) lines.push(trueBranch.extraLine);\n lines.push(` ${nodeId} -->|true| ${trueBranch.targetId}`);\n\n if (dec.onFalse) {\n const falseBranch = renderArrayBranchTarget(dec.onFalse, decisions, terminalCounter);\n if (falseBranch.extraLine) lines.push(falseBranch.extraLine);\n lines.push(` ${nodeId} -->|false| ${falseBranch.targetId}`);\n }\n break;\n }\n\n case 'switch': {\n const sw = node;\n const exprText = escapeLabel(truncate(sw.expression));\n lines.push(` ${nodeId}{${exprText}}`);\n\n for (const c of sw.cases) {\n const caseLabel = c.isDefault ? 'default' : c.labels.join(', ');\n const caseBranch = renderArrayBranchTarget(c.body, decisions, terminalCounter);\n if (caseBranch.extraLine) lines.push(caseBranch.extraLine);\n lines.push(` ${nodeId} -->|${caseLabel}| ${caseBranch.targetId}`);\n }\n break;\n }\n\n case 'match': {\n const m = node;\n const matchLabel = escapeLabel(`Match.${m.matchOp}`);\n lines.push(` ${nodeId}{${matchLabel}}`);\n\n if (m.matchedTags && m.matchedTags.length > 0) {\n for (const tag of m.matchedTags) {\n const tId = `T${terminalCounter.value++}`;\n lines.push(` ${tId}[\"${escapeLabel(tag)}\"]`);\n lines.push(` ${nodeId} -->|${escapeLabel(tag)}| ${tId}`);\n }\n } else {\n const tId = `T${terminalCounter.value++}`;\n lines.push(` ${tId}[\"...\"]`);\n lines.push(` ${nodeId} -->|match| ${tId}`);\n }\n break;\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\n\ninterface CausesOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n/** Escape characters that break Mermaid label syntax. */\nfunction escapeLabel(text: string): string {\n return text\n .replace(/\"/g, '#quot;')\n .replace(/</g, '#lt;')\n .replace(/>/g, '#gt;')\n .replace(/\\(/g, '#lpar;')\n .replace(/\\)/g, '#rpar;');\n}\n\n/** Replace non-alphanumeric characters with underscores for Mermaid node IDs. */\nfunction sanitizeId(text: string): string {\n return text.replace(/[^a-zA-Z0-9]/g, '_');\n}\n\n/** Failure patterns for Effect callee matching. */\nconst EFFECT_FAILURE_CALLEES = new Set(['Effect.fail', 'Effect.die', 'Effect.interrupt']);\n\ninterface FailureNode {\n readonly id: string;\n readonly kind: 'fail' | 'die' | 'interrupt' | 'parallel' | 'sequential';\n readonly label: string;\n readonly children: readonly FailureNode[];\n}\n\n/** Extract error type label from an effect node. */\nfunction getErrorTypeLabel(node: StaticFlowNode): string | undefined {\n if (node.type === 'effect') {\n const raw = node.typeSignature?.errorType ?? node.errorType;\n if (raw && raw !== 'never' && raw.trim() !== '') return raw;\n }\n return undefined;\n}\n\n/** Determine failure kind from an Effect callee. */\nfunction calleeToKind(callee: string): 'fail' | 'die' | 'interrupt' {\n if (callee === 'Effect.die') return 'die';\n if (callee === 'Effect.interrupt') return 'interrupt';\n return 'fail';\n}\n\n/** Recursively collect failure-related nodes from the IR tree. */\nfunction collectFailureNodes(node: StaticFlowNode): readonly FailureNode[] {\n const results: FailureNode[] = [];\n\n // Check if this node is a failure source\n if (node.type === 'cause' && node.isConstructor) {\n const op = node.causeOp;\n\n if (op === 'parallel' || op === 'sequential') {\n // Composite cause: collect children recursively\n const childFailures: FailureNode[] = [];\n const children = node.children ?? [];\n for (const child of children) {\n childFailures.push(...collectFailureNodes(child));\n }\n results.push({\n id: sanitizeId(node.id),\n kind: op,\n label: `Cause.${op}`,\n children: childFailures,\n });\n return results;\n }\n\n if (op === 'fail' || op === 'die' || op === 'interrupt') {\n results.push({\n id: sanitizeId(node.id),\n kind: op,\n label: `Cause.${op}`,\n children: [],\n });\n return results;\n }\n }\n\n if (node.type === 'exit' && node.isConstructor) {\n const op = node.exitOp;\n if (op === 'fail' || op === 'die' || op === 'interrupt') {\n results.push({\n id: sanitizeId(node.id),\n kind: op === 'fail' ? 'fail' : op === 'die' ? 'die' : 'interrupt',\n label: `Exit.${op}`,\n children: [],\n });\n return results;\n }\n }\n\n if (node.type === 'effect' && EFFECT_FAILURE_CALLEES.has(node.callee)) {\n const kind = calleeToKind(node.callee);\n const errorType = getErrorTypeLabel(node);\n const label = errorType ? `${node.callee}: ${errorType}` : node.callee;\n results.push({\n id: sanitizeId(node.id),\n kind,\n label,\n children: [],\n });\n return results;\n }\n\n // Recurse into children for non-failure nodes\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n for (const child of children) {\n results.push(...collectFailureNodes(child));\n }\n\n return results;\n}\n\n/** Render a single failure node and its edges into Mermaid lines. */\nfunction renderFailureNode(\n node: FailureNode,\n parentId: string | undefined,\n edgeLabel: string | undefined,\n lines: string[],\n styledNodes: Map<string, 'fail' | 'die' | 'interrupt' | 'composite'>,\n counter: { value: number },\n): void {\n const nodeId = `N${counter.value++}`;\n const escaped = escapeLabel(node.label);\n\n if (node.kind === 'parallel' || node.kind === 'sequential') {\n // Composite node — light blue styling\n lines.push(` ${nodeId}[${escaped}]`);\n styledNodes.set(nodeId, 'composite');\n\n if (parentId) {\n const edge = edgeLabel ? ` -->|${edgeLabel}| ` : ' --> ';\n lines.push(` ${parentId}${edge}${nodeId}`);\n }\n\n const childEdgeLabel = node.kind === 'parallel' ? 'parallel' : 'then';\n for (const child of node.children) {\n renderFailureNode(child, nodeId, childEdgeLabel, lines, styledNodes, counter);\n }\n } else {\n // Leaf failure node\n if (node.kind === 'die') {\n lines.push(` ${nodeId}[${escaped}]`);\n styledNodes.set(nodeId, 'die');\n } else if (node.kind === 'interrupt') {\n lines.push(` ${nodeId}[${escaped}]`);\n styledNodes.set(nodeId, 'interrupt');\n } else {\n // fail — rounded rect\n lines.push(` ${nodeId}(${escaped})`);\n styledNodes.set(nodeId, 'fail');\n }\n\n if (parentId) {\n const edge = edgeLabel ? ` -->|${edgeLabel}| ` : ' --> ';\n lines.push(` ${parentId}${edge}${nodeId}`);\n }\n }\n}\n\n/**\n * Render a Cause-tree Mermaid flowchart from an Effect IR.\n *\n * Shows how errors compose: parallel failures, sequential failures,\n * defects vs expected errors.\n */\nexport function renderCausesMermaid(\n ir: StaticEffectIR,\n options: CausesOptions = {},\n): string {\n const direction = options.direction ?? 'TB';\n\n // Collect all failure nodes from the IR\n const failureNodes: FailureNode[] = [];\n for (const child of ir.root.children) {\n failureNodes.push(...collectFailureNodes(child));\n }\n\n if (failureNodes.length === 0) {\n return `flowchart ${direction}\\n NoCauses((No failure causes))`;\n }\n\n const lines: string[] = [`flowchart ${direction}`];\n const styledNodes = new Map<string, 'fail' | 'die' | 'interrupt' | 'composite'>();\n const counter = { value: 0 };\n\n // Root node\n const rootId = 'Root';\n const programName = escapeLabel(ir.root.programName);\n lines.push(` ${rootId}((${programName}))`);\n\n // Render each top-level failure node\n for (const node of failureNodes) {\n renderFailureNode(node, rootId, undefined, lines, styledNodes, counter);\n }\n\n // Style definitions\n lines.push('');\n lines.push(' classDef failStyle fill:#FFCDD2,stroke:#C62828');\n lines.push(' classDef dieStyle fill:#B71C1C,color:#fff');\n lines.push(' classDef interruptStyle fill:#FFE0B2,stroke:#E65100');\n lines.push(' classDef compositeStyle fill:#E3F2FD');\n\n // Apply styles\n const styleGroups: { failStyle: string[]; dieStyle: string[]; interruptStyle: string[]; compositeStyle: string[] } = {\n failStyle: [],\n dieStyle: [],\n interruptStyle: [],\n compositeStyle: [],\n };\n\n for (const [nodeId, kind] of styledNodes) {\n if (kind === 'fail') styleGroups.failStyle.push(nodeId);\n else if (kind === 'die') styleGroups.dieStyle.push(nodeId);\n else if (kind === 'interrupt') styleGroups.interruptStyle.push(nodeId);\n else styleGroups.compositeStyle.push(nodeId);\n }\n\n for (const [className, nodeIds] of Object.entries(styleGroups)) {\n if (nodeIds.length > 0) {\n lines.push(` class ${nodeIds.join(',')} ${className}`);\n }\n }\n\n return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\n\ninterface ConcurrencyOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\ntype ConcurrencyNode =\n | { kind: 'parallel'; node: Extract<StaticFlowNode, { type: 'parallel' }> }\n | { kind: 'race'; node: Extract<StaticFlowNode, { type: 'race' }> }\n | { kind: 'fiber'; node: Extract<StaticFlowNode, { type: 'fiber' }> }\n | { kind: 'primitive'; node: Extract<StaticFlowNode, { type: 'concurrency-primitive' }> };\n\n/** Escape characters that break Mermaid label syntax. */\nfunction escapeLabel(text: string): string {\n return text\n .replace(/\"/g, '#quot;')\n .replace(/</g, '#lt;')\n .replace(/>/g, '#gt;')\n .replace(/\\(/g, '#lpar;')\n .replace(/\\)/g, '#rpar;');\n}\n\n/** Generate a short node ID. */\nfunction nodeId(prefix: string, index: number): string {\n return `${prefix}${index}`;\n}\n\n/** Compute a display label for a child flow node. */\nfunction childLabel(node: StaticFlowNode, index: number): string {\n if (node.displayName) return node.displayName;\n if (node.name) return node.name;\n if (node.type === 'effect') return node.callee;\n return `child_${index}`;\n}\n\n/** Capitalize a primitive name. */\nfunction capitalize(s: string): string {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\n/** Recursively collect concurrency-related nodes from the IR. */\nfunction collectConcurrencyNodes(nodes: readonly StaticFlowNode[]): ConcurrencyNode[] {\n const result: ConcurrencyNode[] = [];\n\n const visit = (node: StaticFlowNode): void => {\n switch (node.type) {\n case 'parallel':\n result.push({ kind: 'parallel', node });\n break;\n case 'race':\n result.push({ kind: 'race', node });\n break;\n case 'fiber':\n result.push({ kind: 'fiber', node });\n break;\n case 'concurrency-primitive':\n result.push({ kind: 'primitive', node });\n break;\n }\n\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n for (const child of children) {\n visit(child);\n }\n };\n\n for (const node of nodes) {\n visit(node);\n }\n\n return result;\n}\n\n/**\n * Render a concurrency-focused Mermaid flowchart from an Effect IR.\n *\n * Shows parallel execution, races, fiber forks/joins, and concurrency primitives.\n */\nexport function renderConcurrencyMermaid(\n ir: StaticEffectIR,\n options: ConcurrencyOptions = {},\n): string {\n const direction = options.direction ?? 'TB';\n const collected = collectConcurrencyNodes(ir.root.children);\n\n if (collected.length === 0) {\n return `flowchart ${direction}\\n NoConcurrency((No concurrency))`;\n }\n\n const lines: string[] = [`flowchart ${direction}`];\n const styleLines: string[] = [];\n let globalIdx = 0;\n\n // Track node IDs for execution-order connections\n const orderedIds: string[] = [];\n\n for (const entry of collected) {\n switch (entry.kind) {\n case 'parallel': {\n const pNode = entry.node;\n const pId = nodeId('P', globalIdx++);\n const count = pNode.children.length;\n const modeLabel = pNode.mode === 'parallel' ? 'parallel' : 'sequential';\n const label = escapeLabel(`${pNode.callee} #lpar;${count} effects, ${modeLabel}#rpar;`);\n lines.push(` ${pId}[${label}]`);\n styleLines.push(` style ${pId} fill:#E3F2FD`);\n\n // Fork to children\n const joinId = nodeId('PJ', globalIdx++);\n for (let i = 0; i < pNode.children.length; i++) {\n const child = pNode.children[i];\n if (!child) continue;\n const cId = nodeId('PC', globalIdx++);\n const cLabel = escapeLabel(\n pNode.branchLabels?.[i] ?? childLabel(child, i),\n );\n const branchLabel = pNode.branchLabels?.[i];\n const edgeLabel = branchLabel\n ? escapeLabel(branchLabel)\n : undefined;\n lines.push(` ${cId}[${cLabel}]`);\n if (edgeLabel) {\n lines.push(` ${pId} -->|${edgeLabel}| ${cId}`);\n } else {\n lines.push(` ${pId} --> ${cId}`);\n }\n lines.push(` ${cId} --> ${joinId}`);\n }\n\n lines.push(` ${joinId}([Join])`);\n styleLines.push(` style ${joinId} fill:#E3F2FD`);\n orderedIds.push(pId);\n orderedIds.push(joinId);\n break;\n }\n\n case 'race': {\n const rNode = entry.node;\n const rId = nodeId('R', globalIdx++);\n lines.push(` ${rId}{Race}`);\n styleLines.push(` style ${rId} fill:#FFF3E0`);\n\n const winnerId = nodeId('RW', globalIdx++);\n for (let i = 0; i < rNode.children.length; i++) {\n const child = rNode.children[i];\n if (!child) continue;\n const cId = nodeId('RC', globalIdx++);\n const cLabel = escapeLabel(\n rNode.raceLabels?.[i] ?? childLabel(child, i),\n );\n lines.push(` ${cId}[${cLabel}]`);\n lines.push(` ${rId} -->|competes| ${cId}`);\n lines.push(` ${cId} -.->|winner?| ${winnerId}`);\n }\n\n lines.push(` ${winnerId}([First to complete])`);\n styleLines.push(` style ${winnerId} fill:#FFF3E0`);\n orderedIds.push(rId);\n orderedIds.push(winnerId);\n break;\n }\n\n case 'fiber': {\n const fNode = entry.node;\n const fId = nodeId('F', globalIdx++);\n const op = fNode.operation;\n\n if (op === 'fork' || op === 'forkScoped' || op === 'forkDaemon' || op === 'forkAll' || op === 'forkIn' || op === 'forkWithErrorHandler') {\n const sourceLabel = fNode.fiberSource?.displayName ?? fNode.fiberSource?.name ?? 'effect';\n const label = escapeLabel(`${op}#lpar;${sourceLabel}#rpar;`);\n lines.push(` ${fId}[${label}]`);\n\n if (op === 'forkScoped') {\n styleLines.push(` style ${fId} fill:#C8E6C9`);\n } else if (op === 'forkDaemon') {\n styleLines.push(` style ${fId} fill:#FFE0B2`);\n } else {\n styleLines.push(` style ${fId} fill:#FFF9C4`);\n }\n } else if (op === 'join' || op === 'await') {\n const label = escapeLabel(op);\n lines.push(` ${fId}[${label}]`);\n styleLines.push(` style ${fId} fill:#BBDEFB`);\n } else {\n const label = escapeLabel(`Fiber.${op}`);\n lines.push(` ${fId}[${label}]`);\n styleLines.push(` style ${fId} fill:#BBDEFB`);\n }\n\n orderedIds.push(fId);\n break;\n }\n\n case 'primitive': {\n const cpNode = entry.node;\n const cpId = nodeId('CP', globalIdx++);\n const primName = capitalize(cpNode.primitive);\n const label = escapeLabel(`${primName}.${cpNode.operation}`);\n // Hexagon shape: {{...}}\n lines.push(` ${cpId}{{${label}}}`);\n styleLines.push(` style ${cpId} fill:#F3E5F5`);\n orderedIds.push(cpId);\n break;\n }\n }\n }\n\n // Connect nodes in execution order\n for (let i = 0; i < orderedIds.length - 1; i++) {\n const from = orderedIds[i];\n const to = orderedIds[i + 1];\n if (!from || !to) continue;\n lines.push(` ${from} --> ${to}`);\n }\n\n return [...lines, ...styleLines].join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\n\ninterface TimelineStep {\n readonly kind: 'service-call' | 'effect-constructor' | 'retry' | 'timeout' | 'parallel';\n readonly node: StaticFlowNode;\n}\n\n/** Collect steps in execution order from an IR tree. */\nfunction collectSteps(nodes: readonly StaticFlowNode[]): readonly TimelineStep[] {\n const steps: TimelineStep[] = [];\n\n const visit = (node: StaticFlowNode): void => {\n if (node.type === 'parallel') {\n steps.push({ kind: 'parallel', node });\n return;\n }\n\n if (node.type === 'retry') {\n steps.push({ kind: 'retry', node });\n // Also visit the source effect inside the retry\n visit(node.source);\n return;\n }\n\n if (node.type === 'timeout') {\n steps.push({ kind: 'timeout', node });\n visit(node.source);\n return;\n }\n\n if (node.type === 'effect') {\n const callee = node.callee;\n // Skip noise: Effect.fn definitions, anonymous constructors, Schema/Data\n if (callee === 'Effect.fn' || callee.startsWith('Effect.fn(')) return;\n if (callee.startsWith('Schema.') || callee.startsWith('Data.')) return;\n const displayName = node.displayName ?? '';\n const hasExplicitName = displayName && displayName !== callee && displayName !== node.type;\n if (!hasExplicitName && (callee.startsWith('Effect.') || callee === 'Effect')) return;\n\n if (node.serviceCall) {\n steps.push({ kind: 'service-call', node });\n } else {\n steps.push({ kind: 'effect-constructor', node });\n }\n return;\n }\n\n // For structural nodes (generator, pipe, error-handler, etc.), recurse into children\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n for (const child of children) {\n visit(child);\n }\n };\n\n for (const node of nodes) {\n visit(node);\n }\n\n return steps;\n}\n\n/** Collect all unique service types from steps. */\nfunction collectParticipants(steps: readonly TimelineStep[]): readonly string[] {\n const seen = new Set<string>();\n const participants: string[] = [];\n\n const visitStep = (step: TimelineStep): void => {\n if (step.kind === 'service-call' && step.node.type === 'effect' && step.node.serviceCall) {\n const svc = step.node.serviceCall.serviceType;\n if (!seen.has(svc)) {\n seen.add(svc);\n participants.push(svc);\n }\n } else if (step.kind === 'parallel') {\n // Look into parallel children for service calls\n const children = Option.getOrElse(getStaticChildren(step.node), () => []);\n for (const child of children) {\n if (child.type === 'effect' && child.serviceCall) {\n const svc = child.serviceCall.serviceType;\n if (!seen.has(svc)) {\n seen.add(svc);\n participants.push(svc);\n }\n }\n }\n }\n };\n\n for (const step of steps) {\n visitStep(step);\n }\n\n return participants;\n}\n\n/** Render a parallel node as par/and/end block. */\nfunction renderParallelBlock(node: StaticFlowNode, lines: string[], indent: string): void {\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length === 0) return;\n\n lines.push(`${indent}par Parallel`);\n for (let i = 0; i < children.length; i++) {\n if (i > 0) {\n lines.push(`${indent}and`);\n }\n const child = children[i];\n if (!child) continue;\n if (child.type === 'effect' && child.serviceCall) {\n lines.push(`${indent} Program->>${child.serviceCall.serviceType}: ${child.serviceCall.methodName}()`);\n lines.push(`${indent} ${child.serviceCall.serviceType}-->>Program: result`);\n } else if (child.type === 'effect') {\n lines.push(`${indent} Note over Program: ${child.callee}`);\n } else {\n const label = child.displayName ?? child.name ?? child.type;\n lines.push(`${indent} Note over Program: ${label}`);\n }\n }\n lines.push(`${indent}end`);\n}\n\n/**\n * Render a Mermaid sequence diagram from an Effect IR showing\n * execution order with service calls and timing info.\n */\nexport function renderTimelineMermaid(ir: StaticEffectIR): string {\n const steps = collectSteps(ir.root.children);\n\n if (steps.length === 0) {\n return 'sequenceDiagram\\n participant Program\\n Note over Program: Empty program';\n }\n\n const participants = collectParticipants(steps);\n const lines: string[] = ['sequenceDiagram'];\n lines.push(' participant Program');\n for (const p of participants) {\n lines.push(` participant ${p}`);\n }\n\n for (const step of steps) {\n switch (step.kind) {\n case 'service-call': {\n const node = step.node;\n if (node.type === 'effect' && node.serviceCall) {\n const svc = node.serviceCall.serviceType;\n const method = node.serviceCall.methodName;\n lines.push(` Program->>${svc}: ${method}()`);\n lines.push(` ${svc}-->>Program: result`);\n }\n break;\n }\n case 'effect-constructor': {\n const node = step.node;\n if (node.type === 'effect') {\n lines.push(` Note over Program: ${node.callee}`);\n }\n break;\n }\n case 'retry': {\n const node = step.node;\n if (node.type === 'retry') {\n const info = node.scheduleInfo;\n if (info) {\n const retries = info.maxRetries !== undefined ? `${info.maxRetries}x` : 'unlimited';\n lines.push(` Note over Program: retry (${retries}, ${info.baseStrategy})`);\n } else if (node.schedule) {\n lines.push(` Note over Program: retry (${node.schedule})`);\n } else {\n lines.push(` Note over Program: retry`);\n }\n }\n break;\n }\n case 'timeout': {\n const node = step.node;\n if (node.type === 'timeout') {\n const dur = node.duration ?? 'unknown';\n lines.push(` Note over Program: timeout(${dur})`);\n }\n break;\n }\n case 'parallel': {\n renderParallelBlock(step.node, lines, ' ');\n break;\n }\n }\n }\n\n return lines.join('\\n');\n}\n","/**\n * Layer Dependency Graph (GAP 2)\n *\n * Collects StaticLayerNode from IR and builds a dependency graph\n * (provides, requires, merge/provide edges) for visualization.\n */\n\nimport type { StaticEffectIR, StaticFlowNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface LayerNodeInfo {\n id: string;\n name?: string;\n provides: string[];\n requires: string[];\n lifecycle: string;\n isMerged: boolean;\n operationLayerIds: string[];\n}\n\nexport interface LayerGraphEdge {\n from: string;\n to: string;\n kind: 'provides' | 'requires' | 'merge';\n}\n\nexport interface LayerDependencyGraph {\n layers: LayerNodeInfo[];\n edges: LayerGraphEdge[];\n serviceToLayers: Map<string, string[]>;\n}\n\n// =============================================================================\n// Collection\n// =============================================================================\n\nfunction collectLayerNodes(\n nodes: readonly StaticFlowNode[],\n result: LayerNodeInfo[],\n): void {\n for (const node of nodes) {\n if (node.type === 'layer') {\n const layer = node;\n const info: LayerNodeInfo = {\n id: layer.id,\n provides: [...(layer.provides ?? [])],\n requires: [...(layer.requires ?? [])],\n lifecycle: layer.lifecycle ?? 'default',\n isMerged: layer.isMerged,\n operationLayerIds: layer.operations\n .filter((op) => op.type === 'layer')\n .map((op) => op.id),\n };\n if (layer.name !== undefined) info.name = layer.name;\n result.push(info);\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) collectLayerNodes(children, result);\n }\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport function buildLayerDependencyGraph(ir: StaticEffectIR): LayerDependencyGraph {\n const layers: LayerNodeInfo[] = [];\n collectLayerNodes(ir.root.children, layers);\n\n const edges: LayerGraphEdge[] = [];\n const serviceToLayers = new Map<string, string[]>();\n\n for (const layer of layers) {\n for (const depLayerId of layer.operationLayerIds) {\n edges.push({ from: layer.id, to: depLayerId, kind: 'merge' });\n }\n for (const svc of layer.provides) {\n const list = serviceToLayers.get(svc) ?? [];\n list.push(layer.id);\n serviceToLayers.set(svc, list);\n edges.push({ from: layer.id, to: svc, kind: 'provides' });\n }\n for (const req of layer.requires) {\n edges.push({ from: layer.id, to: req, kind: 'requires' });\n }\n }\n\n return { layers, edges, serviceToLayers };\n}\n\n// =============================================================================\n// Cycle Detection\n// =============================================================================\n\nexport interface LayerCycle {\n /** Layer IDs forming the cycle (first == last to close the loop) */\n path: string[];\n}\n\n/**\n * Detect cycles in the layer provides→requires graph.\n * Returns all unique cycles found with the full cycle path.\n */\nexport function detectLayerCycles(graph: LayerDependencyGraph): LayerCycle[] {\n // Build adjacency: layer → layers it depends on (via requires → provider lookup)\n const providerByService = new Map<string, string[]>();\n for (const layer of graph.layers) {\n for (const svc of layer.provides) {\n const providers = providerByService.get(svc) ?? [];\n providers.push(layer.id);\n providerByService.set(svc, providers);\n }\n }\n\n const adjacency = new Map<string, string[]>();\n for (const layer of graph.layers) {\n const deps: string[] = [];\n for (const req of layer.requires) {\n for (const provider of providerByService.get(req) ?? []) {\n if (provider !== layer.id) deps.push(provider);\n }\n }\n adjacency.set(layer.id, deps);\n }\n\n const cycles: LayerCycle[] = [];\n const visiting = new Set<string>();\n const visited = new Set<string>();\n\n function dfs(node: string, path: string[]): void {\n if (visited.has(node)) return;\n if (visiting.has(node)) {\n const cycleStart = path.indexOf(node);\n if (cycleStart >= 0) {\n cycles.push({ path: [...path.slice(cycleStart), node] });\n }\n return;\n }\n visiting.add(node);\n path.push(node);\n for (const next of adjacency.get(node) ?? []) {\n dfs(next, path);\n }\n path.pop();\n visiting.delete(node);\n visited.add(node);\n }\n\n for (const layerId of adjacency.keys()) {\n dfs(layerId, []);\n }\n\n return cycles;\n}\n\n// =============================================================================\n// Diamond Dependency Detection\n// =============================================================================\n\nexport interface DiamondDependency {\n serviceId: string;\n providers: string[];\n}\n\n/**\n * Detect diamond dependencies: services reachable through multiple provide paths.\n */\nexport function detectDiamondDependencies(graph: LayerDependencyGraph): DiamondDependency[] {\n const diamonds: DiamondDependency[] = [];\n for (const [serviceId, providers] of graph.serviceToLayers) {\n if (providers.length > 1) {\n diamonds.push({ serviceId, providers: [...providers] });\n }\n }\n return diamonds;\n}\n\n// =============================================================================\n// Composition Completeness\n// =============================================================================\n\nexport interface UnsatisfiedService {\n serviceId: string;\n requiredBy: string[];\n}\n\n/**\n * Find services required by layers but not provided by any layer.\n */\nexport function findUnsatisfiedServices(graph: LayerDependencyGraph): UnsatisfiedService[] {\n const allProvided = new Set<string>();\n for (const layer of graph.layers) {\n for (const svc of layer.provides) {\n allProvided.add(svc);\n }\n }\n\n const unsatisfied = new Map<string, string[]>();\n for (const layer of graph.layers) {\n for (const req of layer.requires) {\n if (!allProvided.has(req)) {\n const requiredBy = unsatisfied.get(req) ?? [];\n requiredBy.push(layer.id);\n unsatisfied.set(req, requiredBy);\n }\n }\n }\n\n return Array.from(unsatisfied.entries()).map(([serviceId, requiredBy]) => ({\n serviceId,\n requiredBy,\n }));\n}\n\n// =============================================================================\n// Layer Depth Calculation\n// =============================================================================\n\nfunction computeLayerDepths(graph: LayerDependencyGraph): Map<string, number> {\n const providerByService = new Map<string, string[]>();\n for (const layer of graph.layers) {\n for (const svc of layer.provides) {\n const providers = providerByService.get(svc) ?? [];\n providers.push(layer.id);\n providerByService.set(svc, providers);\n }\n }\n\n const depths = new Map<string, number>();\n const visited = new Set<string>();\n\n function computeDepth(layerId: string): number {\n const cached = depths.get(layerId);\n if (cached !== undefined) return cached;\n if (visited.has(layerId)) return 0; // cycle guard\n visited.add(layerId);\n\n const layer = graph.layers.find(l => l.id === layerId);\n if (!layer) return 0;\n\n let maxDep = 0;\n for (const req of layer.requires) {\n for (const provider of providerByService.get(req) ?? []) {\n if (provider !== layerId) {\n maxDep = Math.max(maxDep, computeDepth(provider) + 1);\n }\n }\n }\n depths.set(layerId, maxDep);\n return maxDep;\n }\n\n for (const layer of graph.layers) {\n computeDepth(layer.id);\n }\n return depths;\n}\n\n// =============================================================================\n// Mermaid output (GAP 2)\n// =============================================================================\n\nfunction sanitizeId(id: string): string {\n return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\nconst DEPTH_COLORS = [\n '#C8E6C9', '#A5D6A7', '#81C784', '#66BB6A', '#4CAF50',\n '#43A047', '#388E3C', '#2E7D32', '#1B5E20',\n];\n\nexport function renderLayerGraphMermaid(graph: LayerDependencyGraph): string {\n const lines: string[] = [];\n lines.push('graph TD');\n lines.push('');\n\n const cycles = detectLayerCycles(graph);\n const cycleEdges = new Set<string>();\n for (const cycle of cycles) {\n for (let i = 0; i < cycle.path.length - 1; i++) {\n cycleEdges.add(`${cycle.path[i]}→${cycle.path[i + 1]}`);\n }\n }\n\n const depths = computeLayerDepths(graph);\n\n for (const layer of graph.layers) {\n const label = layer.name ?? layer.id;\n lines.push(` ${sanitizeId(layer.id)}[\"${label}\"]`);\n }\n lines.push('');\n\n const provided = new Set<string>();\n for (const e of graph.edges) {\n if (e.kind === 'provides') provided.add(e.to);\n }\n for (const svc of provided) {\n lines.push(` ${sanitizeId(svc)}[\"${svc}\"]`);\n }\n lines.push('');\n\n for (const e of graph.edges) {\n const isCycleEdge = cycleEdges.has(`${e.from}→${e.to}`);\n if (e.kind === 'provides') {\n lines.push(` ${sanitizeId(e.from)} -.->|provides| ${sanitizeId(e.to)}`);\n } else if (e.kind === 'requires') {\n if (isCycleEdge) {\n lines.push(` ${sanitizeId(e.from)} -->|⚠ CYCLE| ${sanitizeId(e.to)}`);\n } else {\n lines.push(` ${sanitizeId(e.from)} --> ${sanitizeId(e.to)}`);\n }\n } else {\n lines.push(` ${sanitizeId(e.from)} -->|merge| ${sanitizeId(e.to)}`);\n }\n }\n\n // Color-code layers by depth\n lines.push('');\n lines.push(' %% Depth-based styling');\n const maxDepth = Math.max(...Array.from(depths.values()), 0);\n for (let d = 0; d <= maxDepth && d < DEPTH_COLORS.length; d++) {\n lines.push(` classDef depth${d} fill:${DEPTH_COLORS[d]},stroke:#333`);\n }\n for (const layer of graph.layers) {\n const depth = Math.min(depths.get(layer.id) ?? 0, DEPTH_COLORS.length - 1);\n lines.push(` class ${sanitizeId(layer.id)} depth${depth}`);\n }\n\n // Cycle warning styling\n if (cycles.length > 0) {\n lines.push(' classDef cycleNode fill:#FFCDD2,stroke:#C62828,stroke-width:3px');\n const cycleNodes = new Set<string>();\n for (const cycle of cycles) {\n for (const id of cycle.path) cycleNodes.add(id);\n }\n for (const id of cycleNodes) {\n lines.push(` class ${sanitizeId(id)} cycleNode`);\n }\n }\n\n return lines.join('\\n');\n}\n","import type { StaticEffectIR } from '../types';\nimport { buildLayerDependencyGraph } from '../layer-graph';\n\ninterface LayersOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n/** Sanitize an ID for use as a Mermaid node identifier. */\nfunction sanitizeId(id: string): string {\n return id.replace(/[^a-zA-Z0-9_]/g, '_');\n}\n\n/**\n * Render a layered architecture Mermaid flowchart from an Effect IR.\n *\n * Shows which layers provide which services and their dependencies.\n * - Layer nodes are rectangles with name and lifecycle info.\n * - Service nodes are hexagons.\n * - Provides edges are solid green arrows.\n * - Requires edges are dashed blue arrows.\n * - Merge edges are gray arrows.\n */\nexport function renderLayersMermaid(\n ir: StaticEffectIR,\n options: LayersOptions = {},\n): string {\n const direction = options.direction ?? 'TB';\n const graph = buildLayerDependencyGraph(ir);\n\n if (graph.layers.length === 0) {\n return `flowchart ${direction}\\n NoLayers((No layers))`;\n }\n\n const lines: string[] = [`flowchart ${direction}`];\n\n // Collect all unique services\n const allServices = new Set<string>();\n for (const layer of graph.layers) {\n for (const svc of layer.provides) allServices.add(svc);\n for (const req of layer.requires) allServices.add(req);\n }\n\n // Track merged layers for styling\n const mergedLayerIds = new Set<string>();\n\n // Layer nodes: rectangles with label\n for (const layer of graph.layers) {\n const label = layer.name ?? layer.id;\n const lifecycle = layer.lifecycle !== 'default' ? ` (${layer.lifecycle})` : '';\n const nodeId = sanitizeId(layer.id);\n lines.push(` ${nodeId}[\"${label}${lifecycle}\"]`);\n if (layer.isMerged) mergedLayerIds.add(nodeId);\n }\n\n // Service nodes: hexagons\n for (const svc of allServices) {\n lines.push(` ${sanitizeId(svc)}{{\"${svc}\"}}`);\n }\n\n // Edges\n for (const edge of graph.edges) {\n const from = sanitizeId(edge.from);\n const to = sanitizeId(edge.to);\n if (edge.kind === 'provides') {\n lines.push(` ${from} -->|provides| ${to}`);\n } else if (edge.kind === 'requires') {\n lines.push(` ${from} -.->|requires| ${to}`);\n } else {\n lines.push(` ${from} -->|merge| ${to}`);\n }\n }\n\n // Styling\n lines.push('');\n lines.push(' classDef layerStyle fill:#E8EAF6,stroke:#3F51B5');\n lines.push(' classDef serviceStyle fill:#E3F2FD,stroke:#1E88E5');\n lines.push(' classDef mergedStyle fill:#F3E5F5,stroke:#8E24AA');\n\n // Apply layer styles\n for (const layer of graph.layers) {\n const nodeId = sanitizeId(layer.id);\n if (mergedLayerIds.has(nodeId)) {\n lines.push(` class ${nodeId} mergedStyle`);\n } else {\n lines.push(` class ${nodeId} layerStyle`);\n }\n }\n\n // Apply service styles\n for (const svc of allServices) {\n lines.push(` class ${sanitizeId(svc)} serviceStyle`);\n }\n\n return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode, type StaticRetryNode, type StaticTimeoutNode } from '../types';\n\ninterface RetryOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\ninterface ResilienceNode {\n readonly node: StaticFlowNode;\n readonly index: number;\n}\n\n/** Escape characters that break Mermaid label syntax. */\nfunction escapeLabel(text: string): string {\n return text\n .replace(/\"/g, '#quot;')\n .replace(/</g, '#lt;')\n .replace(/>/g, '#gt;')\n .replace(/\\(/g, '#lpar;')\n .replace(/\\)/g, '#rpar;');\n}\n\n/** Recursively collect retry and timeout nodes from the IR. */\nfunction collectResilienceNodes(\n nodes: readonly StaticFlowNode[],\n result: ResilienceNode[],\n): void {\n for (const node of nodes) {\n if (node.type === 'retry' || node.type === 'timeout') {\n result.push({ node, index: result.length });\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) collectResilienceNodes(children, result);\n }\n}\n\n/** Build a retry strategy label from scheduleInfo. */\nfunction buildRetryLabel(node: StaticFlowNode): string {\n if (node.type !== 'retry') return '';\n const info = (node).scheduleInfo;\n if (!info) return 'retry';\n\n const parts: string[] = [info.baseStrategy];\n if (info.maxRetries !== undefined && info.maxRetries !== 'unlimited') {\n parts.push(`${info.maxRetries}x`);\n }\n if (info.initialDelay) {\n parts.push(info.initialDelay);\n }\n if (info.maxDelay) {\n parts.push(`max ${info.maxDelay}`);\n }\n if (info.jittered) {\n parts.push('+jitter');\n }\n return parts.join(' ');\n}\n\n/** Compute display name for the operation being retried/timed-out. */\nfunction operationLabel(node: StaticFlowNode): string {\n const source = (node as StaticRetryNode | StaticTimeoutNode).source as\n | StaticFlowNode\n | undefined;\n if (source === undefined) return 'Operation';\n if (source.displayName) return source.displayName;\n if (source.name) return source.name;\n return 'Operation';\n}\n\n/**\n * Render a Mermaid flowchart showing retry and timeout resilience patterns.\n */\nexport function renderRetryMermaid(\n ir: StaticEffectIR,\n options: RetryOptions = {},\n): string {\n const direction = options.direction ?? 'LR';\n const collected: ResilienceNode[] = [];\n collectResilienceNodes(ir.root.children, collected);\n\n if (collected.length === 0) {\n return `flowchart ${direction}\\n NoRetry((No retry/timeout patterns))`;\n }\n\n const lines: string[] = [`flowchart ${direction}`];\n\n for (const { node, index } of collected) {\n const prefix = `N${index}`;\n const opLabel = escapeLabel(operationLabel(node));\n\n if (node.type === 'retry') {\n const retryNode = node;\n const retryLabel = escapeLabel(buildRetryLabel(node));\n\n lines.push(` ${prefix}_Op[${opLabel}] -->|fail| ${prefix}_R{Retry}`);\n lines.push(` ${prefix}_R -->|\"${retryLabel}\"| ${prefix}_Op`);\n\n if (retryNode.hasFallback) {\n lines.push(` ${prefix}_R -->|exhausted| ${prefix}_F[Fallback]`);\n } else {\n lines.push(` ${prefix}_R -->|exhausted| ${prefix}_Fail((Failure))`);\n }\n\n // Styles\n lines.push(` style ${prefix}_R fill:#9b59b6,stroke:#8e44ad,color:#fff`);\n if (retryNode.hasFallback) {\n lines.push(` style ${prefix}_F fill:#2ecc71,stroke:#27ae60,color:#fff`);\n } else {\n lines.push(` style ${prefix}_Fail fill:#e74c3c,stroke:#c0392b,color:#fff`);\n }\n } else if (node.type === 'timeout') {\n const timeoutNode = node;\n const duration = timeoutNode.duration ?? '?';\n const timeoutLabel = escapeLabel(`timeout: ${duration}ms`);\n\n lines.push(` ${prefix}_Op[${opLabel}] -->|within| ${prefix}_T[${timeoutLabel}]`);\n\n if (timeoutNode.hasFallback) {\n lines.push(` ${prefix}_T -->|exceeded| ${prefix}_F[Fallback]`);\n } else {\n lines.push(` ${prefix}_T -->|exceeded| ${prefix}_Fail((Timeout))`);\n }\n\n // Styles\n lines.push(` style ${prefix}_T fill:#e67e22,stroke:#d35400,color:#fff`);\n if (timeoutNode.hasFallback) {\n lines.push(` style ${prefix}_F fill:#2ecc71,stroke:#27ae60,color:#fff`);\n } else {\n lines.push(` style ${prefix}_Fail fill:#e74c3c,stroke:#c0392b,color:#fff`);\n }\n }\n }\n\n return lines.join('\\n');\n}\n","import type { StaticEffectIR } from '../types';\n\ninterface TestabilityOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\n/**\n * Render a testability-focused Mermaid flowchart from an Effect IR.\n *\n * Shows what needs mocking for testing: required services, isolation boundaries,\n * and mock complexity (easy leaf services vs hard infrastructure/layer services).\n */\nexport function renderTestabilityMermaid(\n ir: StaticEffectIR,\n options: TestabilityOptions = {},\n): string {\n const direction = options.direction ?? 'LR';\n const services = ir.root.requiredServices ?? [];\n const deps = ir.root.dependencies;\n\n if (services.length === 0) {\n return `flowchart ${direction}\\n NoMocks((No services to mock - pure computation))`;\n }\n\n // Build a set of layer dependency names for classification\n const layerNames = new Set(deps.filter(d => d.isLayer).map(d => d.name));\n\n const lines: string[] = [`flowchart ${direction}`];\n const easyIds: string[] = [];\n const hardIds: string[] = [];\n\n for (let i = 0; i < services.length; i++) {\n const sid = `S${i}`;\n const service = services[i];\n if (!service) continue;\n lines.push(` Prog[${ir.root.programName}] -->|needs mock| ${sid}{{\"${service.serviceId}\"}}`);\n\n if (layerNames.has(service.serviceId)) {\n hardIds.push(sid);\n } else {\n easyIds.push(sid);\n }\n }\n\n // Add class definitions\n lines.push('');\n lines.push(' classDef easy fill:#C8E6C9');\n lines.push(' classDef hard fill:#FFE0B2');\n\n if (easyIds.length > 0) {\n lines.push(` class ${easyIds.join(',')} easy`);\n }\n if (hardIds.length > 0) {\n lines.push(` class ${hardIds.join(',')} hard`);\n }\n\n // Summary note\n const mockWord = services.length === 1 ? 'mock' : 'mocks';\n lines.push('');\n lines.push(` Note[Requires ${services.length} service ${mockWord}]`);\n\n return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\n\ninterface DataflowOptions {\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL';\n}\n\ninterface DataflowStep {\n readonly successType: string;\n readonly errorType: string;\n readonly transformLabel?: string | undefined;\n readonly isEffectful: boolean;\n}\n\n/** Generate a short node ID: S0, S1, S2, ... */\nfunction stepId(index: number): string {\n return `S${index}`;\n}\n\n/** Escape characters that break Mermaid label syntax. */\nfunction escapeLabel(text: string): string {\n return text\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 pipe chains from IR, collecting transformation steps with type info.\n */\nfunction collectPipeSteps(node: StaticFlowNode): DataflowStep[][] {\n const chains: DataflowStep[][] = [];\n\n if (node.type === 'pipe') {\n const pipeNode = node as {\n initial: StaticFlowNode;\n transformations: readonly StaticFlowNode[];\n typeFlow?: readonly { successType: string; errorType: string }[];\n };\n\n const steps: DataflowStep[] = [];\n\n // Initial step type from initial node's typeSignature or typeFlow[0]\n const initialSig =\n pipeNode.typeFlow?.[0] ??\n ('typeSignature' in pipeNode.initial\n ? (pipeNode.initial as { typeSignature?: { successType: string; errorType: string } }).typeSignature\n : undefined);\n\n if (initialSig) {\n steps.push({\n successType: initialSig.successType,\n errorType: initialSig.errorType,\n isEffectful: false,\n });\n }\n\n for (let i = 0; i < pipeNode.transformations.length; i++) {\n const t = pipeNode.transformations[i];\n if (!t) continue;\n const transformType =\n t.type === 'transform'\n ? (t as { transformType: string }).transformType\n : t.name ?? t.type;\n const isEffectful =\n t.type === 'transform'\n ? (t as { isEffectful: boolean }).isEffectful\n : false;\n\n // Type from typeFlow (index i+1) or from outputType on the transform\n const sig =\n pipeNode.typeFlow?.[i + 1] ??\n (t.type === 'transform'\n ? (t as { outputType?: { successType: string; errorType: string } }).outputType\n : undefined);\n\n if (sig) {\n steps.push({\n successType: sig.successType,\n errorType: sig.errorType,\n transformLabel: transformType,\n isEffectful,\n });\n } else {\n steps.push({\n successType: 'unknown',\n errorType: 'unknown',\n transformLabel: transformType,\n isEffectful,\n });\n }\n }\n\n if (steps.length > 0) {\n chains.push(steps);\n }\n }\n\n // Recurse into children\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n for (const child of children) {\n chains.push(...collectPipeSteps(child));\n }\n\n return chains;\n}\n\n/**\n * Extract generator yield steps as a dataflow chain.\n */\nfunction collectGeneratorSteps(node: StaticFlowNode): DataflowStep[][] {\n const chains: DataflowStep[][] = [];\n\n if (node.type === 'generator') {\n const genNode = node as {\n yields: readonly { variableName?: string; effect: StaticFlowNode }[];\n };\n\n const steps: DataflowStep[] = [];\n for (const y of genNode.yields) {\n const sig =\n 'typeSignature' in y.effect\n ? (y.effect as { typeSignature?: { successType: string; errorType: string } }).typeSignature\n : undefined;\n\n if (sig) {\n steps.push({\n successType: sig.successType,\n errorType: sig.errorType,\n transformLabel: y.variableName ?? y.effect.name,\n isEffectful: true,\n });\n } else {\n steps.push({\n successType: 'unknown',\n errorType: 'unknown',\n transformLabel: y.variableName ?? y.effect.name,\n isEffectful: true,\n });\n }\n }\n\n if (steps.length > 0) {\n chains.push(steps);\n }\n }\n\n // Recurse into children\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n for (const child of children) {\n chains.push(...collectGeneratorSteps(child));\n }\n\n return chains;\n}\n\n/**\n * Render a dataflow Mermaid flowchart from an Effect IR.\n *\n * Shows data transformation pipelines: how types evolve through pipe chains\n * and generator yield sequences.\n */\nexport function renderDataflowMermaid(\n ir: StaticEffectIR,\n options: DataflowOptions = {},\n): string {\n const direction = options.direction ?? 'LR';\n\n // Collect all chains from IR\n const allChains: DataflowStep[][] = [];\n for (const child of ir.root.children) {\n allChains.push(...collectPipeSteps(child));\n allChains.push(...collectGeneratorSteps(child));\n }\n\n if (allChains.length === 0) {\n return `flowchart ${direction}\\n NoData((No data transformations))`;\n }\n\n const lines: string[] = [`flowchart ${direction}`];\n const styleLines: string[] = [];\n let globalIdx = 0;\n\n for (const steps of allChains) {\n const baseIdx = globalIdx;\n\n for (let i = 0; i < steps.length; i++) {\n const step = steps[i];\n if (!step) continue;\n const id = stepId(baseIdx + i);\n const label = escapeLabel(step.successType);\n\n // Track node for styling\n if (step.successType === 'unknown') {\n styleLines.push(` style ${id} fill:#EEEEEE`);\n } else {\n styleLines.push(` style ${id} fill:#E8F5E9`);\n }\n\n if (i < steps.length - 1) {\n const nextStep = steps[i + 1];\n if (!nextStep) continue;\n const nextId = stepId(baseIdx + i + 1);\n const nextLabel = escapeLabel(nextStep.successType);\n\n // Build edge label\n let edgeLabel = nextStep.transformLabel ?? '';\n\n // Annotate error type changes\n const prevError = step.errorType;\n const nextError = nextStep.errorType;\n if (nextError !== prevError && nextError !== 'never' && nextError !== 'unknown') {\n edgeLabel = edgeLabel ? `${edgeLabel}<br/>E: ${escapeLabel(nextError)}` : `E: ${escapeLabel(nextError)}`;\n }\n\n // Effectful transforms get bold edges (==>)\n const arrow = nextStep.isEffectful ? '==>' : '-->';\n\n if (i === 0) {\n lines.push(` ${id}[\"${label}\"] ${arrow}|${edgeLabel}| ${nextId}[\"${nextLabel}\"]`);\n } else {\n lines.push(` ${id} ${arrow}|${edgeLabel}| ${nextId}[\"${nextLabel}\"]`);\n }\n } else if (i === 0) {\n // Single-step chain: just render the node\n lines.push(` ${id}[\"${label}\"]`);\n }\n }\n\n globalIdx += steps.length;\n }\n\n return [...lines, ...styleLines].join('\\n');\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { calculateComplexity } from '../complexity';\n\nexport type DiagramType = 'mermaid' | 'railway';\n\n/**\n * Infer the best diagram type for an Effect program.\n *\n * Decision order:\n * 1. Hard rules: parallel/race/switch/loop/conditional/decision → mermaid\n * 2. Soft heuristics: low complexity → railway, otherwise mermaid\n */\nexport function inferBestDiagramType(ir: StaticEffectIR): DiagramType {\n const nodes = ir.root.children;\n\n // Hard rules: structural nodes that railway cannot represent\n if (hasNodeType(nodes, 'parallel')) return 'mermaid';\n if (hasNodeType(nodes, 'race')) return 'mermaid';\n if (hasNodeType(nodes, 'switch')) return 'mermaid';\n if (hasNodeType(nodes, 'loop')) return 'mermaid';\n if (hasNodeType(nodes, 'conditional')) return 'mermaid';\n if (hasNodeType(nodes, 'decision')) return 'mermaid';\n\n // Check stats for structural indicators that may not appear as IR nodes\n // (e.g., when the analyzer records counts but the IR is simplified)\n const stats = ir.metadata.stats;\n if (\n stats.decisionCount > 2 ||\n stats.switchCount > 0 ||\n stats.conditionalCount > 2\n ) {\n return 'mermaid';\n }\n\n // Soft heuristics based on complexity metrics\n const metrics = calculateComplexity(ir);\n\n if (\n metrics.cyclomaticComplexity <= 3 &&\n metrics.decisionPoints <= 1 &&\n metrics.maxDepth <= 2\n ) {\n return 'railway';\n }\n\n return 'mermaid';\n}\n\nfunction hasNodeType(\n nodes: readonly StaticFlowNode[],\n type: StaticFlowNode['type'],\n): boolean {\n for (const node of nodes) {\n if (node.type === type) return true;\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0 && hasNodeType(children, type)) return true;\n }\n return false;\n}\n","/**\n * Complexity Metrics Calculator\n *\n * Calculates complexity metrics for Effect programs including:\n * - Cyclomatic complexity (McCabe)\n * - Cognitive complexity (Sonar-style)\n * - Path count (bounded or unbounded)\n * - Depth and breadth metrics\n */\n\nimport { Option } from 'effect';\nimport { getStaticChildren } from './types';\nimport type {\n StaticEffectIR,\n StaticFlowNode,\n ComplexityMetrics,\n ComplexityThresholds,\n} from './types';\n\n// =============================================================================\n// Default Thresholds\n// =============================================================================\n\nexport const DEFAULT_THRESHOLDS: ComplexityThresholds = {\n cyclomaticWarning: 10,\n cyclomaticError: 20,\n pathCountWarning: 50,\n maxDepthWarning: 5,\n};\n\n// =============================================================================\n// Main Calculator\n// =============================================================================\n\nexport function calculateComplexity(ir: StaticEffectIR): ComplexityMetrics {\n const nodes = ir.root.children;\n\n const cyclomatic = calculateCyclomaticComplexity(nodes);\n const cognitive = calculateCognitiveComplexity(nodes);\n const pathCount = calculatePathCount(nodes);\n const maxDepth = calculateMaxDepth(nodes);\n const maxParallelBreadth = calculateMaxParallelBreadth(nodes);\n const decisionPoints = countDecisionPoints(nodes);\n\n return {\n cyclomaticComplexity: cyclomatic,\n cognitiveComplexity: cognitive,\n pathCount,\n maxDepth,\n maxParallelBreadth,\n decisionPoints,\n };\n}\n\n// =============================================================================\n// Cyclomatic Complexity\n// =============================================================================\n\nfunction calculateCyclomaticComplexity(\n nodes: readonly StaticFlowNode[],\n): number {\n let complexity = 1;\n for (const node of nodes) {\n complexity += countDecisionPointsInNode(node);\n }\n return complexity;\n}\n\nfunction countDecisionPointsInNode(node: StaticFlowNode): number {\n const children = getStaticChildren(node);\n const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n let count = 0;\n\n switch (node.type) {\n case 'conditional':\n count += 1;\n for (const child of childList) {\n count += countDecisionPointsInNode(child);\n }\n break;\n\n case 'race':\n count += Math.max(0, node.children.length - 1);\n for (const child of node.children) {\n count += countDecisionPointsInNode(child);\n }\n break;\n\n case 'loop':\n count += 1;\n count += countDecisionPointsInNode(node.body);\n break;\n\n case 'generator':\n case 'pipe':\n case 'parallel':\n case 'error-handler':\n case 'retry':\n case 'timeout':\n case 'resource':\n case 'layer':\n for (const child of childList) {\n count += countDecisionPointsInNode(child);\n }\n break;\n\n case 'decision':\n count += 1;\n for (const child of childList) {\n count += countDecisionPointsInNode(child);\n }\n break;\n\n case 'switch':\n count += Math.max(0, node.cases.length - 1);\n for (const child of childList) {\n count += countDecisionPointsInNode(child);\n }\n break;\n\n case 'try-catch':\n count += 1;\n for (const child of childList) {\n count += countDecisionPointsInNode(child);\n }\n break;\n\n case 'terminal':\n case 'opaque':\n for (const child of childList) {\n count += countDecisionPointsInNode(child);\n }\n break;\n\n case 'match':\n if (node.matchedTags && node.matchedTags.length > 1) {\n count += node.matchedTags.length - 1;\n }\n break;\n\n case 'interruption':\n if (node.handler) {\n count += 1;\n count += countDecisionPointsInNode(node.handler);\n }\n if (node.source) {\n count += countDecisionPointsInNode(node.source);\n }\n break;\n\n case 'cause':\n if (node.children) {\n for (const child of node.children) {\n count += countDecisionPointsInNode(child);\n }\n }\n break;\n\n case 'transform':\n if (node.source) {\n count += countDecisionPointsInNode(node.source);\n }\n break;\n\n case 'channel':\n case 'sink':\n if (node.source) {\n count += countDecisionPointsInNode(node.source);\n }\n break;\n\n case 'exit':\n case 'schedule':\n case 'effect':\n case 'unknown':\n break;\n }\n\n return count;\n}\n\n// =============================================================================\n// Cognitive Complexity\n// =============================================================================\n\nfunction calculateCognitiveComplexity(\n nodes: readonly StaticFlowNode[],\n): number {\n return calculateCognitiveForNodes(nodes, 0);\n}\n\nfunction calculateCognitiveForNodes(\n nodes: readonly StaticFlowNode[],\n nestingDepth: number,\n): number {\n let complexity = 0;\n for (const node of nodes) {\n complexity += calculateCognitiveForNode(node, nestingDepth);\n }\n return complexity;\n}\n\nfunction calculateCognitiveForNode(\n node: StaticFlowNode,\n nestingDepth: number,\n): number {\n const children = getStaticChildren(node);\n const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n let complexity = 0;\n\n switch (node.type) {\n case 'conditional':\n complexity += 1 + nestingDepth;\n complexity += calculateCognitiveForNode(node.onTrue, nestingDepth + 1);\n if (node.onFalse) {\n complexity += calculateCognitiveForNode(node.onFalse, nestingDepth + 1);\n }\n break;\n\n case 'loop':\n complexity += 1 + nestingDepth;\n complexity += calculateCognitiveForNode(node.body, nestingDepth + 1);\n break;\n\n case 'race':\n complexity += node.children.length;\n for (const child of node.children) {\n complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n }\n break;\n\n case 'parallel':\n complexity += Math.max(0, node.children.length - 1);\n for (const child of node.children) {\n complexity += calculateCognitiveForNode(child, nestingDepth);\n }\n break;\n\n case 'generator':\n case 'pipe':\n case 'error-handler':\n case 'retry':\n case 'timeout':\n case 'resource':\n case 'layer':\n for (const child of childList) {\n complexity += calculateCognitiveForNode(child, nestingDepth);\n }\n break;\n\n case 'decision':\n complexity += 1 + nestingDepth;\n for (const child of node.onTrue) {\n complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n }\n if (node.onFalse) {\n for (const child of node.onFalse) {\n complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n }\n }\n break;\n\n case 'switch':\n complexity += 1 + nestingDepth;\n for (const caseItem of node.cases) {\n for (const child of caseItem.body) {\n complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n }\n }\n break;\n\n case 'try-catch':\n complexity += 1 + nestingDepth;\n for (const child of childList) {\n complexity += calculateCognitiveForNode(child, nestingDepth + 1);\n }\n break;\n\n case 'terminal':\n if (node.value) {\n for (const child of node.value) {\n complexity += calculateCognitiveForNode(child, nestingDepth);\n }\n }\n break;\n\n case 'opaque':\n break;\n\n case 'match':\n if (node.matchedTags && node.matchedTags.length > 0) {\n complexity += 1 + nestingDepth;\n }\n break;\n\n case 'interruption':\n if (node.handler) {\n complexity += 1 + nestingDepth;\n complexity += calculateCognitiveForNode(node.handler, nestingDepth + 1);\n }\n if (node.source) {\n complexity += calculateCognitiveForNode(node.source, nestingDepth);\n }\n break;\n\n case 'cause':\n if (node.children) {\n for (const child of node.children) {\n complexity += calculateCognitiveForNode(child, nestingDepth);\n }\n }\n break;\n\n case 'transform':\n if (node.source) {\n complexity += calculateCognitiveForNode(node.source, nestingDepth);\n }\n break;\n\n case 'channel':\n case 'sink':\n if (node.source) {\n complexity += calculateCognitiveForNode(node.source, nestingDepth);\n }\n break;\n\n case 'exit':\n case 'schedule':\n case 'effect':\n case 'unknown':\n break;\n }\n\n return complexity;\n}\n\n// =============================================================================\n// Path Count\n// =============================================================================\n\nfunction calculatePathCount(\n nodes: readonly StaticFlowNode[],\n): number | 'unbounded' {\n let pathCount = 1;\n let hasUnbounded = false;\n\n for (const node of nodes) {\n const result = pathCountForNode(node);\n if (result === 'unbounded') {\n hasUnbounded = true;\n } else {\n pathCount *= result;\n }\n }\n\n return hasUnbounded ? 'unbounded' : pathCount;\n}\n\nfunction pathCountForNode(node: StaticFlowNode): number | 'unbounded' {\n const children = getStaticChildren(node);\n const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n switch (node.type) {\n case 'conditional': {\n const truePaths = pathCountForNodes([node.onTrue]);\n const falsePaths = node.onFalse\n ? pathCountForNodes([node.onFalse])\n : 1;\n if (truePaths === 'unbounded' || falsePaths === 'unbounded') {\n return 'unbounded';\n }\n return truePaths + falsePaths;\n }\n\n case 'race': {\n let total = 0;\n for (const child of node.children) {\n const childPaths = pathCountForNode(child);\n if (childPaths === 'unbounded') return 'unbounded';\n total += childPaths;\n }\n return Math.max(1, total);\n }\n\n case 'parallel': {\n let product = 1;\n for (const child of node.children) {\n const childPaths = pathCountForNode(child);\n if (childPaths === 'unbounded') return 'unbounded';\n product *= childPaths;\n }\n return product;\n }\n\n case 'loop':\n return 'unbounded';\n\n case 'generator':\n case 'pipe':\n case 'error-handler':\n case 'retry':\n case 'timeout':\n case 'resource':\n case 'layer':\n return pathCountForNodes(childList);\n\n case 'effect':\n case 'unknown':\n case 'opaque':\n return 1;\n\n case 'decision': {\n const truePaths = pathCountForNodes([...node.onTrue]);\n const falsePaths = node.onFalse\n ? pathCountForNodes([...node.onFalse])\n : 1;\n if (truePaths === 'unbounded' || falsePaths === 'unbounded') {\n return 'unbounded';\n }\n return truePaths + falsePaths;\n }\n\n case 'switch': {\n let total = 0;\n for (const c of node.cases) {\n const casePaths = pathCountForNodes([...c.body]);\n if (casePaths === 'unbounded') return 'unbounded';\n total += casePaths;\n }\n return Math.max(1, total);\n }\n\n case 'try-catch':\n case 'terminal':\n case 'stream':\n case 'concurrency-primitive':\n case 'fiber':\n case 'interruption':\n case 'transform':\n case 'match':\n case 'cause':\n case 'exit':\n case 'schedule':\n case 'channel':\n case 'sink':\n return pathCountForNodes(childList);\n }\n}\n\nfunction pathCountForNodes(\n nodes: readonly StaticFlowNode[],\n): number | 'unbounded' {\n let product = 1;\n for (const node of nodes) {\n const paths = pathCountForNode(node);\n if (paths === 'unbounded') return 'unbounded';\n product *= paths;\n }\n return product;\n}\n\n// =============================================================================\n// Depth\n// =============================================================================\n\nfunction calculateMaxDepth(nodes: readonly StaticFlowNode[]): number {\n let maxDepth = 0;\n for (const node of nodes) {\n maxDepth = Math.max(maxDepth, depthOfNode(node, 0));\n }\n return maxDepth;\n}\n\nfunction depthOfNode(node: StaticFlowNode, currentDepth: number): number {\n const children = getStaticChildren(node);\n const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n let maxChildDepth = currentDepth;\n\n switch (node.type) {\n case 'conditional':\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(node.onTrue, currentDepth + 1),\n );\n if (node.onFalse) {\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(node.onFalse, currentDepth + 1),\n );\n }\n break;\n\n case 'loop':\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(node.body, currentDepth + 1),\n );\n break;\n\n case 'parallel':\n case 'race':\n for (const child of node.children) {\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(child, currentDepth + 1),\n );\n }\n break;\n\n case 'generator':\n case 'pipe':\n case 'error-handler':\n case 'retry':\n case 'timeout':\n case 'resource':\n case 'layer':\n for (const child of childList) {\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(child, currentDepth),\n );\n }\n break;\n\n case 'decision':\n for (const child of node.onTrue) {\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(child, currentDepth + 1),\n );\n }\n if (node.onFalse) {\n for (const child of node.onFalse) {\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(child, currentDepth + 1),\n );\n }\n }\n break;\n\n case 'switch':\n for (const caseItem of node.cases) {\n for (const child of caseItem.body) {\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(child, currentDepth + 1),\n );\n }\n }\n break;\n\n case 'try-catch':\n for (const child of childList) {\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(child, currentDepth + 1),\n );\n }\n break;\n\n case 'terminal':\n if (node.value) {\n for (const child of node.value) {\n maxChildDepth = Math.max(\n maxChildDepth,\n depthOfNode(child, currentDepth),\n );\n }\n }\n break;\n\n case 'opaque':\n break;\n\n case 'match':\n break;\n\n case 'interruption':\n if (node.source) {\n maxChildDepth = Math.max(maxChildDepth, depthOfNode(node.source, currentDepth + 1));\n }\n if (node.handler) {\n maxChildDepth = Math.max(maxChildDepth, depthOfNode(node.handler, currentDepth + 1));\n }\n break;\n\n case 'cause':\n if (node.children) {\n for (const child of node.children) {\n maxChildDepth = Math.max(maxChildDepth, depthOfNode(child, currentDepth));\n }\n }\n break;\n\n case 'transform':\n if (node.source) {\n maxChildDepth = Math.max(maxChildDepth, depthOfNode(node.source, currentDepth));\n }\n break;\n\n case 'channel':\n case 'sink':\n if (node.source) {\n maxChildDepth = Math.max(maxChildDepth, depthOfNode(node.source, currentDepth));\n }\n break;\n\n case 'exit':\n case 'schedule':\n case 'effect':\n case 'unknown':\n break;\n }\n\n return maxChildDepth;\n}\n\n// =============================================================================\n// Parallel Breadth\n// =============================================================================\n\nfunction calculateMaxParallelBreadth(\n nodes: readonly StaticFlowNode[],\n): number {\n let maxBreadth = 0;\n for (const node of nodes) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node));\n }\n return maxBreadth;\n}\n\nfunction parallelBreadthOfNode(node: StaticFlowNode): number {\n const children = getStaticChildren(node);\n const childList = Option.getOrElse(children, () => [] as readonly StaticFlowNode[]);\n\n let maxBreadth = 0;\n\n switch (node.type) {\n case 'parallel':\n case 'race':\n maxBreadth = node.children.length;\n for (const child of node.children) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n }\n break;\n\n case 'conditional':\n maxBreadth = Math.max(\n parallelBreadthOfNode(node.onTrue),\n node.onFalse ? parallelBreadthOfNode(node.onFalse) : 0,\n );\n break;\n\n case 'loop':\n maxBreadth = parallelBreadthOfNode(node.body);\n break;\n\n case 'generator':\n case 'pipe':\n case 'error-handler':\n case 'retry':\n case 'timeout':\n case 'resource':\n case 'layer':\n for (const child of childList) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n }\n break;\n\n case 'decision':\n for (const child of node.onTrue) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n }\n if (node.onFalse) {\n for (const child of node.onFalse) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n }\n }\n break;\n\n case 'switch':\n for (const caseItem of node.cases) {\n for (const child of caseItem.body) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n }\n }\n break;\n\n case 'try-catch':\n for (const child of childList) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n }\n break;\n\n case 'terminal':\n if (node.value) {\n for (const child of node.value) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n }\n }\n break;\n\n case 'opaque':\n break;\n\n case 'interruption':\n if (node.source) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node.source));\n }\n if (node.handler) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node.handler));\n }\n break;\n\n case 'cause':\n if (node.children) {\n for (const child of node.children) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(child));\n }\n }\n break;\n\n case 'transform':\n if (node.source) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node.source));\n }\n break;\n\n case 'channel':\n case 'sink':\n if (node.source) {\n maxBreadth = Math.max(maxBreadth, parallelBreadthOfNode(node.source));\n }\n break;\n\n case 'match':\n case 'exit':\n case 'schedule':\n case 'effect':\n case 'unknown':\n break;\n }\n\n return maxBreadth;\n}\n\n// =============================================================================\n// Decision Points\n// =============================================================================\n\nfunction countDecisionPoints(nodes: readonly StaticFlowNode[]): number {\n let count = 0;\n for (const node of nodes) {\n count += countDecisionPointsInNode(node);\n }\n return count;\n}\n\n// =============================================================================\n// Assessment\n// =============================================================================\n\nexport interface ComplexityAssessment {\n level: 'low' | 'medium' | 'high' | 'very-high';\n warnings: ComplexityWarning[];\n recommendations: string[];\n}\n\nexport interface ComplexityWarning {\n type: 'cyclomatic' | 'cognitive' | 'paths' | 'depth' | 'breadth';\n message: string;\n severity: 'warning' | 'error';\n}\n\nexport function assessComplexity(\n metrics: ComplexityMetrics,\n thresholds: ComplexityThresholds = DEFAULT_THRESHOLDS,\n): ComplexityAssessment {\n const warnings: ComplexityWarning[] = [];\n const recommendations: string[] = [];\n\n if (metrics.cyclomaticComplexity >= thresholds.cyclomaticError) {\n warnings.push({\n type: 'cyclomatic',\n message: `Cyclomatic complexity (${metrics.cyclomaticComplexity}) exceeds error threshold (${thresholds.cyclomaticError})`,\n severity: 'error',\n });\n recommendations.push(\n 'Consider breaking this program into smaller effects',\n );\n } else if (metrics.cyclomaticComplexity >= thresholds.cyclomaticWarning) {\n warnings.push({\n type: 'cyclomatic',\n message: `Cyclomatic complexity (${metrics.cyclomaticComplexity}) exceeds warning threshold (${thresholds.cyclomaticWarning})`,\n severity: 'warning',\n });\n recommendations.push(\n 'Consider simplifying conditional logic or extracting sub-effects',\n );\n }\n\n if (metrics.pathCount === 'unbounded') {\n warnings.push({\n type: 'paths',\n message: 'Program has unbounded paths due to loops',\n severity: 'warning',\n });\n recommendations.push(\n 'Ensure loop termination conditions are well-tested',\n );\n } else if (metrics.pathCount >= thresholds.pathCountWarning) {\n warnings.push({\n type: 'paths',\n message: `Path count (${metrics.pathCount}) exceeds threshold (${thresholds.pathCountWarning})`,\n severity: 'warning',\n });\n recommendations.push(\n 'High path count makes exhaustive testing difficult - consider simplifying',\n );\n }\n\n if (metrics.maxDepth >= thresholds.maxDepthWarning) {\n warnings.push({\n type: 'depth',\n message: `Nesting depth (${metrics.maxDepth}) exceeds threshold (${thresholds.maxDepthWarning})`,\n severity: 'warning',\n });\n recommendations.push(\n 'Deep nesting reduces readability - consider flattening or extracting',\n );\n }\n\n let level: ComplexityAssessment['level'] = 'low';\n const hasError = warnings.some((w) => w.severity === 'error');\n const hasWarning = warnings.some((w) => w.severity === 'warning');\n\n if (hasError) {\n level = 'very-high';\n } else if (hasWarning) {\n level = warnings.length >= 2 ? 'high' : 'medium';\n }\n\n return {\n level,\n warnings,\n recommendations,\n };\n}\n\n// =============================================================================\n// Summary\n// =============================================================================\n\nexport function formatComplexitySummary(\n metrics: ComplexityMetrics,\n assessment: ComplexityAssessment,\n): string {\n const lines: string[] = [];\n\n lines.push('## Effect Program Complexity Report');\n lines.push('');\n lines.push(`**Overall Complexity:** ${assessment.level.toUpperCase()}`);\n lines.push('');\n lines.push('### Metrics');\n lines.push('');\n lines.push('| Metric | Value |');\n lines.push('|--------|-------|');\n lines.push(`| Cyclomatic Complexity | ${metrics.cyclomaticComplexity} |`);\n lines.push(`| Cognitive Complexity | ${metrics.cognitiveComplexity} |`);\n lines.push(`| Unique Paths | ${metrics.pathCount} |`);\n lines.push(`| Max Nesting Depth | ${metrics.maxDepth} |`);\n lines.push(`| Max Parallel Breadth | ${metrics.maxParallelBreadth} |`);\n lines.push(`| Decision Points | ${metrics.decisionPoints} |`);\n lines.push('');\n\n if (assessment.warnings.length > 0) {\n lines.push('### Warnings');\n lines.push('');\n for (const warning of assessment.warnings) {\n const icon = warning.severity === 'error' ? 'ERROR' : 'WARNING';\n lines.push(`- **${icon}:** ${warning.message}`);\n }\n lines.push('');\n }\n\n if (assessment.recommendations.length > 0) {\n lines.push('### Recommendations');\n lines.push('');\n for (const rec of assessment.recommendations) {\n lines.push(`- ${rec}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import { Option } from 'effect';\nimport type {\n StaticEffectIR,\n StaticFlowNode,\n StaticEffectNode,\n DiagramQuality,\n DiagramQualityMetrics,\n DiagramQualityWithFile,\n DiagramTopOffendersReport,\n DiagramTopOffenderEntry,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { generatePaths } from './path-generator';\nimport { summarizePathSteps } from './output/mermaid';\n\nexport interface DiagramQualityHintInput {\n readonly reasons?: readonly string[] | undefined;\n readonly tips?: readonly string[] | undefined;\n}\n\nexport interface DiagramQualityOptions {\n readonly styleGuideSummary?: boolean | undefined;\n readonly hints?: DiagramQualityHintInput | undefined;\n}\n\nconst MAX_PROGRAM_TIPS = 3;\nconst MAX_FILE_TIPS = 5;\n\nfunction clamp(n: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, n));\n}\n\nfunction uniqueCapped(items: readonly string[], max: number): string[] {\n return [...new Set(items)].slice(0, max);\n}\n\nfunction startsWithAllowedTipPrefix(tip: string): boolean {\n return (\n tip.startsWith('Consider') ||\n tip.startsWith('If you want clearer diagrams') ||\n tip.startsWith('For larger programs')\n );\n}\n\nfunction normalizeTip(tip: string): string {\n if (startsWithAllowedTipPrefix(tip)) return tip;\n return `Consider ${tip.charAt(0).toLowerCase()}${tip.slice(1)}`;\n}\n\nfunction collectAllNodes(nodes: readonly StaticFlowNode[]): StaticFlowNode[] {\n const out: StaticFlowNode[] = [];\n const visit = (list: readonly StaticFlowNode[]) => {\n for (const node of list) {\n out.push(node);\n const children = Option.getOrElse(getStaticChildren(node), () => [] as readonly StaticFlowNode[]);\n if (children.length > 0) visit(children);\n }\n };\n visit(nodes);\n return out;\n}\n\nfunction isLogLike(name: string): boolean {\n const n = name.toLowerCase();\n return n.includes('log') || n.includes('logger') || n.includes('taperror');\n}\n\nfunction looksAnonymousEffectNode(node: StaticEffectNode): boolean {\n const callee = node.callee.trim();\n if (callee === '' || callee === '_' || callee === 'Effect') return true;\n if (/call expression/i.test(callee)) return true;\n if (/^program-\\d+$/i.test(node.name ?? '')) return true;\n return false;\n}\n\nfunction isServiceCallNode(node: StaticFlowNode): node is StaticEffectNode {\n return (\n node.type === 'effect' &&\n (node.semanticRole === 'service-call' ||\n node.serviceCall !== undefined ||\n node.serviceMethod !== undefined)\n );\n}\n\nfunction hasNamedServiceCallee(node: StaticEffectNode): boolean {\n const c = node.callee.trim();\n if (c === '' || c === '_' || c === 'Effect') return false;\n if (/unknown/i.test(c) || /call expression/i.test(c)) return false;\n return true;\n}\n\nfunction computeMetrics(\n ir: StaticEffectIR,\n options: DiagramQualityOptions = {},\n): DiagramQualityMetrics {\n const nodes = collectAllNodes(ir.root.children);\n const detailedSteps = nodes.length;\n const effects = nodes.filter((n): n is StaticEffectNode => n.type === 'effect');\n\n const sideEffects = effects.filter((n) => n.semanticRole === 'side-effect');\n const logEffects = effects.filter((n) => isLogLike(n.displayName ?? n.name ?? n.callee));\n const unknownNodes = nodes.filter((n) => n.type === 'unknown').length;\n\n const anonymousNodeCount = nodes.filter((n) => {\n if (n.type === 'unknown') return true;\n if (n.type === 'pipe') return true;\n if (n.type === 'effect') return looksAnonymousEffectNode(n);\n return false;\n }).length;\n\n const serviceCalls = nodes.filter((n) => isServiceCallNode(n));\n const namedServiceCalls = serviceCalls.filter((n) => hasNamedServiceCallee(n));\n\n const pipeNodes = nodes.filter((n): n is StaticFlowNode & { type: 'pipe'; transformations: readonly StaticFlowNode[] } => n.type === 'pipe');\n const pipeChainCount = pipeNodes.length;\n const maxPipeChainLength = pipeNodes.length > 0\n ? Math.max(...pipeNodes.map((p) => 1 + p.transformations.length))\n : 0;\n\n const paths = generatePaths(ir);\n const representativePath = [...paths].sort((a, b) => b.steps.length - a.steps.length)[0];\n const summary = representativePath\n ? summarizePathSteps(representativePath, {\n collapseRepeatedLogs: true,\n collapsePureTransforms: true,\n styleGuide: options.styleGuideSummary ?? false,\n })\n : { steps: [] as const, collapsedGroups: 0 };\n\n const ratioBase = detailedSteps > 0 ? detailedSteps : 1;\n const serviceBase = serviceCalls.length > 0 ? serviceCalls.length : 1;\n\n return {\n stepCountDetailed: detailedSteps,\n stepCountSummary: summary.steps.length,\n collapsedGroupsSummary: summary.collapsedGroups,\n logRatio: logEffects.length / ratioBase,\n sideEffectRatio: sideEffects.length / ratioBase,\n anonymousNodeCount,\n anonymousRatio: anonymousNodeCount / ratioBase,\n unknownNodeCount: unknownNodes,\n serviceCallCount: serviceCalls.length,\n namedServiceCallRatio: namedServiceCalls.length / serviceBase,\n pipeChainCount,\n maxPipeChainLength,\n };\n}\n\nfunction scoreFromMetrics(metrics: DiagramQualityMetrics): { score: number; band: DiagramQuality['band'] } {\n const unknownPenalty = Math.min(35, metrics.unknownNodeCount * 8);\n const anonymousPenalty = Math.min(25, Math.round(metrics.anonymousRatio * 40));\n const stepPenalty =\n metrics.stepCountDetailed > 24\n ? Math.min(22, Math.round((metrics.stepCountDetailed - 24) * 0.6))\n : 0;\n const logPenalty = Math.min(12, Math.round(metrics.logRatio * 30));\n const sideEffectPenalty =\n metrics.sideEffectRatio > 0.75\n ? Math.min(8, Math.round((metrics.sideEffectRatio - 0.75) * 40))\n : 0;\n\n const score = clamp(\n Math.round(100 - unknownPenalty - anonymousPenalty - stepPenalty - logPenalty - sideEffectPenalty),\n 0,\n 100,\n );\n const band: DiagramQuality['band'] = score >= 75 ? 'good' : score >= 50 ? 'ok' : 'noisy';\n return { score, band };\n}\n\nfunction reasonsFromMetrics(metrics: DiagramQualityMetrics): string[] {\n const reasons: string[] = [];\n const logCount = Math.round(metrics.logRatio * Math.max(metrics.stepCountDetailed, 1));\n\n if (metrics.stepCountDetailed >= 60) {\n reasons.push(`High step count (${String(metrics.stepCountDetailed)}). Consider summary mode.`);\n } else if (metrics.stepCountDetailed >= 35) {\n reasons.push(`Moderate step count (${String(metrics.stepCountDetailed)}). Summary mode may improve readability.`);\n }\n\n if (logCount >= 12 || metrics.logRatio >= 0.35) {\n reasons.push(`Many log steps (${String(logCount)}). Consider collapsing logs or summary mode.`);\n }\n\n if (metrics.anonymousNodeCount >= 5) {\n reasons.push(`${String(metrics.anonymousNodeCount)} anonymous nodes from pipe chains or unnamed calls.`);\n }\n\n if (metrics.unknownNodeCount > 0) {\n reasons.push(`${String(metrics.unknownNodeCount)} unresolved nodes may reduce diagram clarity.`);\n }\n\n if (metrics.serviceCallCount >= 3 && metrics.namedServiceCallRatio < 0.7) {\n reasons.push(\n `Service call naming clarity is ${(metrics.namedServiceCallRatio * 100).toFixed(0)}% (${String(metrics.serviceCallCount)} calls).`,\n );\n }\n\n return reasons;\n}\n\nfunction tipsFromMetrics(metrics: DiagramQualityMetrics): string[] {\n const tips: string[] = [];\n const logCount = Math.round(metrics.logRatio * Math.max(metrics.stepCountDetailed, 1));\n\n if (metrics.stepCountDetailed >= 35) {\n tips.push('For larger programs, consider summary mode.');\n }\n if (logCount >= 12 || metrics.logRatio >= 0.35) {\n tips.push('For larger programs, consider grouping logs or using summary mode.');\n }\n if (metrics.anonymousNodeCount >= 5) {\n tips.push('Consider naming intermediate values or extracting named helpers.');\n }\n if (metrics.pipeChainCount >= 4 || metrics.maxPipeChainLength >= 6) {\n tips.push('If you want clearer diagrams, consider splitting long pipe chains into named steps.');\n }\n if (metrics.serviceCallCount >= 3 && metrics.namedServiceCallRatio < 0.7) {\n tips.push('Consider naming service-call intermediates to make boundaries explicit.');\n }\n\n return uniqueCapped(tips.map(normalizeTip), MAX_PROGRAM_TIPS);\n}\n\nexport function computeProgramDiagramQuality(\n ir: StaticEffectIR,\n options: DiagramQualityOptions = {},\n): DiagramQuality {\n const metrics = computeMetrics(ir, options);\n const { score, band } = scoreFromMetrics(metrics);\n const reasons = reasonsFromMetrics(metrics);\n const tips = tipsFromMetrics(metrics);\n\n const hintReasons = options.hints?.reasons ?? [];\n const hintTips = (options.hints?.tips ?? []).map(normalizeTip);\n\n return {\n score,\n band,\n metrics,\n reasons: uniqueCapped([...reasons, ...hintReasons], 8),\n tips: uniqueCapped([...tips, ...hintTips], MAX_PROGRAM_TIPS),\n };\n}\n\nfunction aggregateMetrics(qualities: readonly DiagramQuality[]): DiagramQualityMetrics {\n if (qualities.length === 0) {\n return {\n stepCountDetailed: 0,\n stepCountSummary: 0,\n collapsedGroupsSummary: 0,\n logRatio: 0,\n sideEffectRatio: 0,\n anonymousNodeCount: 0,\n anonymousRatio: 0,\n unknownNodeCount: 0,\n serviceCallCount: 0,\n namedServiceCallRatio: 0,\n pipeChainCount: 0,\n maxPipeChainLength: 0,\n };\n }\n\n const weights = qualities.map((q) => Math.max(1, q.metrics.stepCountDetailed));\n const totalWeight = weights.reduce((a, b) => a + b, 0);\n const weightedAvg = (picker: (q: DiagramQuality) => number): number =>\n qualities.reduce((sum, q, i) => sum + picker(q) * (weights[i] ?? 1), 0) / totalWeight;\n const weightedSum = (picker: (q: DiagramQuality) => number): number =>\n qualities.reduce((sum, q) => sum + picker(q), 0);\n\n return {\n stepCountDetailed: Math.round(weightedAvg((q) => q.metrics.stepCountDetailed)),\n stepCountSummary: Math.round(weightedAvg((q) => q.metrics.stepCountSummary)),\n collapsedGroupsSummary: Math.round(weightedAvg((q) => q.metrics.collapsedGroupsSummary)),\n logRatio: weightedAvg((q) => q.metrics.logRatio),\n sideEffectRatio: weightedAvg((q) => q.metrics.sideEffectRatio),\n anonymousNodeCount: Math.round(weightedSum((q) => q.metrics.anonymousNodeCount)),\n anonymousRatio: weightedAvg((q) => q.metrics.anonymousRatio),\n unknownNodeCount: Math.round(weightedSum((q) => q.metrics.unknownNodeCount)),\n serviceCallCount: Math.round(weightedSum((q) => q.metrics.serviceCallCount)),\n namedServiceCallRatio: weightedAvg((q) => q.metrics.namedServiceCallRatio),\n pipeChainCount: Math.round(weightedSum((q) => q.metrics.pipeChainCount)),\n maxPipeChainLength: Math.max(...qualities.map((q) => q.metrics.maxPipeChainLength)),\n };\n}\n\nexport function computeFileDiagramQuality(\n filePath: string,\n programs: readonly StaticEffectIR[],\n options: DiagramQualityOptions = {},\n): DiagramQualityWithFile {\n const programQualities = programs.map((ir) => computeProgramDiagramQuality(ir, options));\n const metrics = aggregateMetrics(programQualities);\n const weightedScore = programQualities.length > 0\n ? Math.round(\n programQualities.reduce(\n (sum, q) => sum + q.score * Math.max(1, q.metrics.stepCountDetailed),\n 0,\n ) /\n programQualities.reduce((sum, q) => sum + Math.max(1, q.metrics.stepCountDetailed), 0),\n )\n : 100;\n\n const band: DiagramQuality['band'] =\n weightedScore >= 75 ? 'good' : weightedScore >= 50 ? 'ok' : 'noisy';\n\n const reasons = uniqueCapped(\n [\n ...reasonsFromMetrics(metrics),\n ...(options.hints?.reasons ?? []),\n ],\n 10,\n );\n const tips = uniqueCapped(\n [\n ...tipsFromMetrics(metrics),\n ...((options.hints?.tips ?? []).map(normalizeTip)),\n ].filter(startsWithAllowedTipPrefix),\n MAX_FILE_TIPS,\n );\n\n return {\n filePath,\n quality: {\n score: weightedScore,\n band,\n metrics,\n reasons,\n tips,\n },\n };\n}\n\nfunction makeEntry(filePath: string, metricValue: number, tip: string): DiagramTopOffenderEntry {\n return {\n filePath,\n metricValue,\n tip: normalizeTip(tip),\n };\n}\n\nfunction rankTop(\n entries: readonly DiagramQualityWithFile[],\n valueOf: (q: DiagramQualityWithFile) => number,\n tip: (q: DiagramQualityWithFile) => string,\n topN: number,\n): DiagramTopOffenderEntry[] {\n return [...entries]\n .sort((a, b) => {\n const dv = valueOf(b) - valueOf(a);\n if (dv !== 0) return dv;\n return a.filePath.localeCompare(b.filePath);\n })\n .slice(0, topN)\n .map((q) => makeEntry(q.filePath, valueOf(q), tip(q)));\n}\n\nexport function buildTopOffendersReport(\n fileQualities: readonly DiagramQualityWithFile[],\n topN = 10,\n): DiagramTopOffendersReport {\n const capped = clamp(topN, 1, 50);\n return {\n largestPrograms: rankTop(\n fileQualities,\n (q) => q.quality.metrics.stepCountDetailed,\n () => 'For larger programs, consider summary mode.',\n capped,\n ),\n mostAnonymousNodes: rankTop(\n fileQualities,\n (q) => q.quality.metrics.anonymousNodeCount,\n () => 'Consider naming intermediate values or extracting named helpers.',\n capped,\n ),\n mostUnknownNodes: rankTop(\n fileQualities,\n (q) => q.quality.metrics.unknownNodeCount,\n () => 'If you want clearer diagrams, consider extracting helpers to reduce unresolved nodes.',\n capped,\n ),\n highestLogRatio: rankTop(\n fileQualities,\n (q) => q.quality.metrics.logRatio,\n () => 'For larger programs, consider grouping logs or using summary mode.',\n capped,\n ),\n };\n}\n\n","/**\n * Path Generator\n *\n * Generates all possible execution paths through an Effect program based on\n * static analysis. Each path represents a unique sequence of steps that could\n * execute given certain conditions.\n */\n\nimport type {\n StaticEffectIR,\n StaticFlowNode,\n StaticDecisionNode,\n StaticSwitchNode,\n StaticTryCatchNode,\n StaticTerminalNode,\n StaticCauseNode,\n StaticMatchNode,\n StaticTransformNode,\n StaticChannelNode,\n StaticSinkNode,\n StaticInterruptionNode,\n EffectPath,\n PathStepRef,\n PathCondition,\n} from './types';\n\n// =============================================================================\n// Options\n// =============================================================================\n\nexport interface PathGeneratorOptions {\n /** Maximum paths to generate (default: 1000) */\n maxPaths?: number;\n /** Whether to include loop iterations as separate paths (default: false) */\n expandLoops?: boolean;\n /** Maximum loop iterations to expand if expandLoops is true (default: 3) */\n maxLoopIterations?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<PathGeneratorOptions> = {\n maxPaths: 1000,\n expandLoops: false,\n maxLoopIterations: 3,\n};\n\n// =============================================================================\n// Path Generation\n// =============================================================================\n\nexport interface PathGenerationResult {\n /** Generated effect paths */\n paths: EffectPath[];\n /** Whether the maxPaths limit was hit (truncation occurred) */\n limitHit: boolean;\n}\n\n/**\n * Generate all possible execution paths through an Effect program.\n */\nexport function generatePaths(\n ir: StaticEffectIR,\n options: PathGeneratorOptions = {},\n): EffectPath[] {\n return generatePathsWithMetadata(ir, options).paths;\n}\n\n/**\n * Generate all possible execution paths with metadata.\n */\nexport function generatePathsWithMetadata(\n ir: StaticEffectIR,\n options: PathGeneratorOptions = {},\n): PathGenerationResult {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n\n const context: PathContext = {\n opts,\n pathCount: 0,\n hasHitLimit: false,\n controlStack: [],\n };\n\n const initialState: PathState = {\n steps: [],\n conditions: [],\n hasLoops: false,\n hasUnresolvedRefs: false,\n };\n\n const states = generatePathsForNodes(ir.root.children, initialState, context);\n\n const paths: EffectPath[] = states.map((state, index) => ({\n id: `path-${index + 1}`,\n description: generatePathDescription(state),\n steps: state.steps,\n conditions: state.conditions,\n hasLoops: state.hasLoops,\n hasUnresolvedRefs: state.hasUnresolvedRefs,\n }));\n\n return {\n paths,\n limitHit: context.hasHitLimit,\n };\n}\n\n// =============================================================================\n// Internal Types\n// =============================================================================\n\ninterface ControlTarget {\n readonly kind: 'loop' | 'switch' | 'block';\n readonly label?: string;\n readonly breakContinuationNodeId: string;\n readonly continueContinuationNodeId?: string; // only for loops\n}\n\ninterface PathContext {\n opts: Required<PathGeneratorOptions>;\n pathCount: number;\n hasHitLimit: boolean;\n controlStack: ControlTarget[];\n}\n\ninterface PathState {\n steps: PathStepRef[];\n conditions: PathCondition[];\n hasLoops: boolean;\n hasUnresolvedRefs: boolean;\n}\n\n// =============================================================================\n// Path Generation Logic\n// =============================================================================\n\nfunction generatePathsForNodes(\n nodes: readonly StaticFlowNode[],\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n if (nodes.length === 0) {\n return [currentState];\n }\n\n let states: PathState[] = [currentState];\n\n for (const node of nodes) {\n const newStates: PathState[] = [];\n for (const state of states) {\n newStates.push(...generatePathsForNode(node, state, context));\n }\n states = newStates;\n if (node.type === 'terminal') {\n const term = node;\n if (term.terminalKind === 'return' || term.terminalKind === 'throw') {\n return states;\n }\n }\n }\n\n return states;\n}\n\nfunction generatePathsForNode(\n node: StaticFlowNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n switch (node.type) {\n case 'effect':\n return handleEffectNode(node, currentState);\n case 'generator':\n return handleGeneratorNode(node, currentState, context);\n case 'pipe':\n return handlePipeNode(node, currentState, context);\n case 'parallel':\n return handleParallelNode(node, currentState, context);\n case 'race':\n return handleRaceNode(node, currentState, context);\n case 'error-handler':\n return handleErrorHandlerNode(node, currentState, context);\n case 'retry':\n case 'timeout':\n return handleSingleChildNode(node, currentState, context);\n case 'resource':\n return handleResourceNode(node, currentState, context);\n case 'conditional':\n return handleConditionalNode(node, currentState, context);\n case 'loop':\n return handleLoopNode(node, currentState, context);\n case 'layer':\n return handleLayerNode(node, currentState, context);\n case 'stream':\n return handleStreamNode(node, currentState, context);\n case 'concurrency-primitive':\n case 'fiber':\n return handleConcurrencyOrFiberNode(node, currentState, context);\n case 'decision':\n return handleDecisionNode(node, currentState, context);\n case 'switch':\n return handleSwitchNode(node, currentState, context);\n case 'try-catch':\n return handleTryCatchNode(node, currentState, context);\n case 'terminal':\n return handleTerminalNode(node, currentState, context);\n case 'cause':\n return handleCauseNode(node, currentState, context);\n case 'exit':\n case 'schedule':\n return handleLeafStepNode(node, currentState);\n case 'match':\n return handleMatchNode(node, currentState, context);\n case 'transform':\n return handleTransformNode(node, currentState, context);\n case 'channel':\n return handleChannelNode(node, currentState, context);\n case 'sink':\n return handleSinkNode(node, currentState, context);\n case 'interruption':\n return handleInterruptionNode(node, currentState, context);\n case 'opaque':\n return [currentState]; // treat as no-op, path continues\n case 'unknown':\n return [currentState];\n default:\n return [currentState];\n }\n}\n\nfunction handleEffectNode(\n node: StaticFlowNode & { type: 'effect' },\n currentState: PathState,\n): PathState[] {\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name: node.name ?? node.callee,\n repeated: false,\n };\n return [\n {\n ...currentState,\n steps: [...currentState.steps, stepRef],\n },\n ];\n}\n\nfunction handleGeneratorNode(\n node: StaticFlowNode & { type: 'generator' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const children = node.yields.map((y) => y.effect);\n return generatePathsForNodes(children, currentState, context);\n}\n\nfunction handlePipeNode(\n node: StaticFlowNode & { type: 'pipe' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const children = [node.initial, ...node.transformations];\n return generatePathsForNodes(children, currentState, context);\n}\n\nfunction handleParallelNode(\n node: StaticFlowNode & { type: 'parallel' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n let combinedStates: PathState[] = [currentState];\n\n for (const child of node.children) {\n const newCombinedStates: PathState[] = [];\n for (const state of combinedStates) {\n const childStates = generatePathsForNode(child, state, context);\n for (const childState of childStates) {\n newCombinedStates.push({\n steps: childState.steps,\n conditions: childState.conditions,\n hasLoops: state.hasLoops || childState.hasLoops,\n hasUnresolvedRefs:\n state.hasUnresolvedRefs || childState.hasUnresolvedRefs,\n });\n }\n }\n combinedStates = newCombinedStates;\n }\n\n return combinedStates;\n}\n\nfunction handleRaceNode(\n node: StaticFlowNode & { type: 'race' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n if (node.children.length === 0) {\n return [currentState];\n }\n\n const atLimit =\n context.hasHitLimit ||\n context.pathCount + node.children.length >= context.opts.maxPaths;\n if (atLimit) {\n context.hasHitLimit = true;\n const first = node.children[0];\n if (first) {\n return generatePathsForNode(first, currentState, context);\n }\n return [currentState];\n }\n\n const allStates: PathState[] = [];\n const maxAllowed = context.opts.maxPaths;\n\n for (const child of node.children) {\n if (allStates.length >= maxAllowed) {\n context.hasHitLimit = true;\n break;\n }\n const childStates = generatePathsForNode(child, currentState, context);\n const roomLeft = maxAllowed - allStates.length;\n const toAdd = childStates.slice(0, roomLeft);\n allStates.push(...toAdd);\n if (toAdd.length < childStates.length) {\n context.hasHitLimit = true;\n }\n }\n\n context.pathCount += Math.max(0, allStates.length - 1);\n return allStates.length > 0 ? allStates : [currentState];\n}\n\nfunction handleErrorHandlerNode(\n node: StaticFlowNode & { type: 'error-handler' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const sourceStates = generatePathsForNode(node.source, currentState, context);\n if (!node.handler) {\n return sourceStates;\n }\n const handlerStates = generatePathsForNode(\n node.handler,\n currentState,\n context,\n );\n return [...sourceStates, ...handlerStates];\n}\n\nfunction handleSingleChildNode(\n node: StaticFlowNode & { type: 'retry' | 'timeout' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n return generatePathsForNode(node.source, currentState, context);\n}\n\nfunction handleResourceNode(\n node: StaticFlowNode & { type: 'resource' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const resourceNodes: StaticFlowNode[] = [node.acquire, node.release];\n if (node.use) {\n resourceNodes.push(node.use);\n }\n return generatePathsForNodes(resourceNodes, currentState, context);\n}\n\nfunction handleConditionalNode(\n node: StaticFlowNode & { type: 'conditional' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const trueCondition: PathCondition = {\n expression: node.condition,\n mustBe: node.conditionalType === 'unless' ? false : true,\n location: node.location,\n };\n\n const trueState: PathState = {\n ...currentState,\n conditions: [...currentState.conditions, trueCondition],\n };\n\n const trueStates = generatePathsForNode(node.onTrue, trueState, context);\n\n const falseCondition: PathCondition = {\n expression: node.condition,\n mustBe: node.conditionalType === 'unless' ? true : false,\n location: node.location,\n };\n\n const falseState: PathState = {\n ...currentState,\n conditions: [...currentState.conditions, falseCondition],\n };\n\n if (node.onFalse) {\n const falseStates = generatePathsForNode(node.onFalse, falseState, context);\n return [...trueStates, ...falseStates];\n }\n\n return [...trueStates, falseState];\n}\n\nfunction handleLoopNode(\n node: StaticFlowNode & { type: 'loop' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const bodyStates = generatePathsForNode(node.body, currentState, context);\n return bodyStates.map((state) => ({\n ...state,\n steps: state.steps.map((step, idx) =>\n idx >= currentState.steps.length ? { ...step, repeated: true } : step,\n ),\n hasLoops: true,\n }));\n}\n\nfunction handleLayerNode(\n node: StaticFlowNode & { type: 'layer' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n return generatePathsForNodes(node.operations, currentState, context);\n}\n\nfunction handleStreamNode(\n node: StaticFlowNode & { type: 'stream' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name: node.pipeline.length > 0 ? `Stream.${node.pipeline.map((p) => p.operation).join(' → ')}` : 'Stream',\n repeated: false,\n };\n const stateWithStep = {\n ...currentState,\n steps: [...currentState.steps, stepRef],\n };\n return generatePathsForNode(node.source, stateWithStep, context);\n}\n\nfunction handleConcurrencyOrFiberNode(\n node: StaticFlowNode & { type: 'concurrency-primitive' | 'fiber' },\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name:\n node.type === 'concurrency-primitive'\n ? `${node.primitive}.${node.operation}`\n : node.operation,\n repeated: false,\n };\n const stateWithStep = {\n ...currentState,\n steps: [...currentState.steps, stepRef],\n };\n const child =\n node.type === 'concurrency-primitive' ? node.source : node.fiberSource;\n if (child) {\n return generatePathsForNode(child, stateWithStep, context);\n }\n return [stateWithStep];\n}\n\nfunction handleDecisionNode(\n node: StaticDecisionNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const trueCondition: PathCondition = {\n expression: node.condition,\n mustBe: true,\n location: node.location,\n };\n const trueState: PathState = {\n ...currentState,\n conditions: [...currentState.conditions, trueCondition],\n };\n const trueStates = generatePathsForNodes(node.onTrue, trueState, context);\n\n if (node.onFalse && node.onFalse.length > 0) {\n const falseCondition: PathCondition = {\n expression: node.condition,\n mustBe: false,\n location: node.location,\n };\n const falseState: PathState = {\n ...currentState,\n conditions: [...currentState.conditions, falseCondition],\n };\n const falseStates = generatePathsForNodes(node.onFalse, falseState, context);\n return [...trueStates, ...falseStates];\n }\n\n const falseCondition: PathCondition = {\n expression: node.condition,\n mustBe: false,\n location: node.location,\n };\n const falseState: PathState = {\n ...currentState,\n conditions: [...currentState.conditions, falseCondition],\n };\n return [...trueStates, falseState];\n}\n\nfunction handleSwitchNode(\n node: StaticSwitchNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const allStates: PathState[] = [];\n\n for (const caseItem of node.cases) {\n const caseLabel = caseItem.labels.join(' / ');\n const caseCondition: PathCondition = {\n expression: `${node.expression} === ${caseLabel}`,\n mustBe: true,\n location: node.location,\n };\n const caseState: PathState = {\n ...currentState,\n conditions: [...currentState.conditions, caseCondition],\n };\n const caseStates = generatePathsForNodes(caseItem.body, caseState, context);\n allStates.push(...caseStates);\n }\n\n return allStates.length > 0 ? allStates : [currentState];\n}\n\nfunction handleTryCatchNode(\n node: StaticTryCatchNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n // Try path (success)\n const tryStates = generatePathsForNodes(node.tryBody, currentState, context);\n\n // Catch path\n const catchStates: PathState[] = [];\n if (node.catchBody && node.catchBody.length > 0) {\n const catchCondition: PathCondition = {\n expression: 'throws',\n mustBe: true,\n location: node.location,\n };\n const catchState: PathState = {\n ...currentState,\n conditions: [...currentState.conditions, catchCondition],\n };\n catchStates.push(...generatePathsForNodes(node.catchBody, catchState, context));\n }\n\n const combined = [...tryStates, ...catchStates];\n\n // Finally path: if present, append to all paths\n if (node.finallyBody && node.finallyBody.length > 0) {\n const finalStates: PathState[] = [];\n for (const state of combined) {\n finalStates.push(...generatePathsForNodes(node.finallyBody, state, context));\n }\n return finalStates;\n }\n\n return combined;\n}\n\nfunction handleTerminalNode(\n node: StaticTerminalNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n // If the terminal has value nodes (e.g., return yield* effect), process them first\n let state = currentState;\n if (node.value && node.value.length > 0) {\n const valueStates = generatePathsForNodes(node.value, currentState, context);\n // Take the first resulting state (value expressions produce sequential steps)\n state = valueStates[0] ?? currentState;\n }\n\n switch (node.terminalKind) {\n case 'return':\n case 'throw':\n // Path terminates — add a step marking the termination\n return [{\n ...state,\n steps: [...state.steps, {\n nodeId: node.id,\n name: node.terminalKind,\n repeated: false,\n }],\n }];\n\n case 'break':\n case 'continue':\n // These are structurally captured — just continue the path\n return [state];\n }\n}\n\n// =============================================================================\n// New node type handlers (cause, exit, schedule, match, transform, channel, sink, interruption)\n// =============================================================================\n\nfunction handleLeafStepNode(\n node: StaticFlowNode,\n currentState: PathState,\n): PathState[] {\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name: node.name ?? node.type,\n repeated: false,\n };\n return [{\n ...currentState,\n steps: [...currentState.steps, stepRef],\n }];\n}\n\nfunction handleCauseNode(\n node: StaticCauseNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name: node.name ?? `Cause.${node.causeOp}`,\n repeated: false,\n };\n const stateWithStep: PathState = {\n ...currentState,\n steps: [...currentState.steps, stepRef],\n };\n\n if (node.children && node.children.length > 0) {\n return generatePathsForNodes([...node.children], stateWithStep, context);\n }\n return [stateWithStep];\n}\n\nfunction handleMatchNode(\n node: StaticMatchNode,\n currentState: PathState,\n _context: PathContext,\n): PathState[] {\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name: node.name ?? `Match.${node.matchOp}`,\n repeated: false,\n };\n return [{\n ...currentState,\n steps: [...currentState.steps, stepRef],\n }];\n}\n\nfunction handleTransformNode(\n node: StaticTransformNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n let state = currentState;\n if (node.source) {\n const sourceStates = generatePathsForNode(node.source, currentState, context);\n state = sourceStates[0] ?? currentState;\n }\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name: node.name ?? node.transformType,\n repeated: false,\n };\n return [{\n ...state,\n steps: [...state.steps, stepRef],\n }];\n}\n\nfunction handleChannelNode(\n node: StaticChannelNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n let state = currentState;\n if (node.source) {\n const sourceStates = generatePathsForNode(node.source, currentState, context);\n state = sourceStates[0] ?? currentState;\n }\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name: node.name ?? `Channel${node.pipeline.length > 0 ? `.${node.pipeline.map(p => p.operation).join('.')}` : ''}`,\n repeated: false,\n };\n return [{\n ...state,\n steps: [...state.steps, stepRef],\n }];\n}\n\nfunction handleSinkNode(\n node: StaticSinkNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n let state = currentState;\n if (node.source) {\n const sourceStates = generatePathsForNode(node.source, currentState, context);\n state = sourceStates[0] ?? currentState;\n }\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name: node.name ?? `Sink${node.pipeline.length > 0 ? `.${node.pipeline.map(p => p.operation).join('.')}` : ''}`,\n repeated: false,\n };\n return [{\n ...state,\n steps: [...state.steps, stepRef],\n }];\n}\n\nfunction handleInterruptionNode(\n node: StaticInterruptionNode,\n currentState: PathState,\n context: PathContext,\n): PathState[] {\n const stepRef: PathStepRef = {\n nodeId: node.id,\n name: node.name ?? node.interruptionType,\n repeated: false,\n };\n const stateWithStep: PathState = {\n ...currentState,\n steps: [...currentState.steps, stepRef],\n };\n\n if (node.source) {\n const sourceStates = generatePathsForNode(node.source, stateWithStep, context);\n if (node.handler) {\n // Fork: source path + handler path (on interrupt)\n const handlerStates = generatePathsForNode(node.handler, stateWithStep, context);\n return [...sourceStates, ...handlerStates];\n }\n return sourceStates;\n }\n return [stateWithStep];\n}\n\n// =============================================================================\n// Path Description\n// =============================================================================\n\nfunction generatePathDescription(state: PathState): string {\n const parts: string[] = [];\n\n if (state.conditions.length > 0) {\n const conditionParts = state.conditions.map((c) => {\n const verb = c.mustBe ? 'is true' : 'is false';\n const expr =\n c.expression.length > 30\n ? c.expression.slice(0, 30) + '...'\n : c.expression;\n return `${expr} ${verb}`;\n });\n parts.push(`When ${conditionParts.join(' AND ')}`);\n }\n\n const stepNames = state.steps\n .map((s) => {\n const name = s.name ?? s.nodeId;\n return s.repeated ? `${name} (repeated)` : name;\n })\n .join(' → ');\n\n if (stepNames) {\n parts.push(`Steps: ${stepNames}`);\n }\n\n if (state.hasLoops) {\n parts.push('[contains loops]');\n }\n if (state.hasUnresolvedRefs) {\n parts.push('[has unresolved refs]');\n }\n\n return parts.join('. ') || 'Empty path';\n}\n\n// =============================================================================\n// Path Statistics\n// =============================================================================\n\nexport interface PathStatistics {\n totalPaths: number;\n pathLimitHit: boolean;\n pathsWithLoops: number;\n pathsWithUnresolvedRefs: number;\n uniqueConditions: string[];\n maxPathLength: number;\n minPathLength: number;\n avgPathLength: number;\n}\n\nexport interface PathStatisticsOptions {\n limitHit?: boolean;\n}\n\nexport function calculatePathStatistics(\n paths: EffectPath[],\n options?: PathStatisticsOptions,\n): PathStatistics {\n if (paths.length === 0) {\n return {\n totalPaths: 0,\n pathLimitHit: false,\n pathsWithLoops: 0,\n pathsWithUnresolvedRefs: 0,\n uniqueConditions: [],\n maxPathLength: 0,\n minPathLength: 0,\n avgPathLength: 0,\n };\n }\n\n const conditions = new Set<string>();\n let pathsWithLoops = 0;\n let pathsWithUnresolvedRefs = 0;\n let totalLength = 0;\n let maxLength = 0;\n let minLength = Infinity;\n\n for (const path of paths) {\n if (path.hasLoops) pathsWithLoops++;\n if (path.hasUnresolvedRefs) pathsWithUnresolvedRefs++;\n const length = path.steps.length;\n totalLength += length;\n maxLength = Math.max(maxLength, length);\n minLength = Math.min(minLength, length);\n for (const c of path.conditions) {\n conditions.add(c.expression);\n }\n }\n\n return {\n totalPaths: paths.length,\n pathLimitHit: options?.limitHit ?? false,\n pathsWithLoops,\n pathsWithUnresolvedRefs,\n uniqueConditions: Array.from(conditions),\n maxPathLength: maxLength,\n minPathLength: minLength === Infinity ? 0 : minLength,\n avgPathLength: totalLength / paths.length,\n };\n}\n\n// =============================================================================\n// Path Filtering\n// =============================================================================\n\nexport function filterPaths(\n paths: EffectPath[],\n filter: {\n mustIncludeStep?: string;\n mustExcludeStep?: string;\n conditionTrue?: string;\n conditionFalse?: string;\n noLoops?: boolean;\n maxLength?: number;\n },\n): EffectPath[] {\n return paths.filter((path) => {\n if (filter.mustIncludeStep) {\n const has = path.steps.some(\n (s) => s.name === filter.mustIncludeStep || s.nodeId === filter.mustIncludeStep,\n );\n if (!has) return false;\n }\n if (filter.mustExcludeStep) {\n const has = path.steps.some(\n (s) =>\n s.name === filter.mustExcludeStep ||\n s.nodeId === filter.mustExcludeStep,\n );\n if (has) return false;\n }\n if (filter.conditionTrue) {\n const has = path.conditions.some(\n (c) => c.expression === filter.conditionTrue && c.mustBe,\n );\n if (!has) return false;\n }\n if (filter.conditionFalse) {\n const has = path.conditions.some(\n (c) => c.expression === filter.conditionFalse && !c.mustBe,\n );\n if (!has) return false;\n }\n if (filter.noLoops && path.hasLoops) return false;\n if (filter.maxLength !== undefined && path.steps.length > filter.maxLength)\n return false;\n return true;\n });\n}\n","import { readFile } from 'fs/promises';\nimport { resolve } from 'path';\nimport type { DiagramQualityHintInput } from './diagram-quality';\n\ninterface EslintMessage {\n readonly ruleId?: string | null;\n readonly message?: string;\n readonly severity?: number;\n}\n\ninterface EslintFileResult {\n readonly filePath?: string;\n readonly messages?: readonly EslintMessage[];\n}\n\nfunction isEffectLikeRule(ruleId: string | undefined | null): boolean {\n if (!ruleId) return false;\n return /effect/i.test(ruleId);\n}\n\nfunction mapTip(message: EslintMessage): string | undefined {\n const text = `${message.ruleId ?? ''} ${message.message ?? ''}`.toLowerCase();\n if (text.includes('yield') || text.includes('untagged')) {\n return 'Consider binding yielded values with meaningful names.';\n }\n if (text.includes('error') || text.includes('catch') || text.includes('handle')) {\n return 'If you want clearer diagrams, consider making error boundaries explicit.';\n }\n if (text.includes('service') || text.includes('layer') || text.includes('provide')) {\n return 'Consider acquiring services near the top of the workflow.';\n }\n if (text.includes('pipe') || text.includes('nested') || text.includes('lambda')) {\n return 'If you want clearer diagrams, consider extracting nested pipe lambdas into named helpers.';\n }\n return undefined;\n}\n\nfunction formatReason(message: EslintMessage): string | undefined {\n const rule = message.ruleId ?? 'eslint';\n const msg = (message.message ?? '').trim();\n if (!msg) return undefined;\n return `ESLint (${rule}): ${msg}`;\n}\n\nfunction parseResults(raw: unknown): readonly EslintFileResult[] {\n if (Array.isArray(raw)) return raw as readonly EslintFileResult[];\n if (raw && typeof raw === 'object' && 'results' in raw) {\n const results = (raw as { results?: unknown }).results;\n if (Array.isArray(results)) return results as readonly EslintFileResult[];\n }\n return [];\n}\n\nexport async function loadDiagramQualityHintsFromEslintJson(\n jsonPath: string,\n): Promise<Map<string, DiagramQualityHintInput>> {\n const content = await readFile(jsonPath, 'utf-8');\n const parsed = JSON.parse(content) as unknown;\n const results = parseResults(parsed);\n const byFile = new Map<string, { reasons: string[]; tips: string[] }>();\n\n for (const file of results) {\n const filePath = file.filePath ? resolve(file.filePath) : undefined;\n if (!filePath) continue;\n const messages = file.messages ?? [];\n for (const message of messages) {\n if (!isEffectLikeRule(message.ruleId)) continue;\n const cur = byFile.get(filePath) ?? { reasons: [], tips: [] };\n const reason = formatReason(message);\n if (reason) cur.reasons.push(reason);\n const tip = mapTip(message);\n if (tip) cur.tips.push(tip);\n byFile.set(filePath, cur);\n }\n }\n\n const out = new Map<string, DiagramQualityHintInput>();\n for (const [filePath, hints] of byFile) {\n out.set(filePath, {\n reasons: [...new Set(hints.reasons)].slice(0, 8),\n tips: [...new Set(hints.tips)].slice(0, 5),\n });\n }\n return out;\n}\n\n","/**\n * Plain-English explanation renderer for Effect IR trees.\n *\n * Walks the static IR and produces a human-readable narrative\n * describing what an Effect program does.\n */\n\nimport type {\n StaticEffectIR,\n StaticFlowNode,\n StaticEffectProgram,\n} from '../types';\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst indent = (depth: number): string => ' '.repeat(depth);\n\n/** Summarise a node in a short inline phrase (no newline). */\nfunction shortLabel(node: StaticFlowNode): string {\n switch (node.type) {\n case 'effect': {\n if (node.serviceCall) {\n return `${node.serviceCall.serviceType}.${node.serviceCall.methodName}`;\n }\n return node.displayName ?? node.callee;\n }\n case 'generator':\n return 'Effect.gen block';\n case 'pipe':\n return `pipe(${shortLabel(node.initial)})`;\n case 'parallel':\n return `${node.callee}(${node.children.length} effects)`;\n case 'race':\n return `${node.callee}(${node.children.length} effects)`;\n case 'error-handler':\n return node.handlerType;\n case 'retry':\n return 'retry';\n case 'timeout':\n return node.duration ? `timeout(${node.duration})` : 'timeout';\n case 'resource':\n return 'acquireRelease';\n case 'conditional':\n return `if ${node.conditionLabel ?? node.condition}`;\n case 'loop':\n return `${node.loopType}${node.iterSource ? `(${node.iterSource})` : ''}`;\n case 'layer':\n return node.provides ? `Layer(${node.provides.join(', ')})` : 'Layer';\n case 'stream':\n return 'Stream';\n case 'fiber':\n return `Fiber.${node.operation}`;\n case 'concurrency-primitive':\n return `${node.primitive}.${node.operation}`;\n case 'decision':\n return `if ${node.condition}`;\n case 'switch':\n return `switch(${node.expression})`;\n case 'try-catch':\n return 'try/catch';\n case 'terminal':\n return node.terminalKind;\n case 'match':\n return node.matchedTags ? `Match(${node.matchedTags.join(', ')})` : 'Match';\n case 'transform':\n return node.transformType;\n case 'channel':\n return 'Channel';\n case 'sink':\n return 'Sink';\n case 'cause':\n return `Cause.${node.causeOp}`;\n case 'exit':\n return `Exit.${node.exitOp}`;\n case 'schedule':\n return `Schedule.${node.scheduleOp}`;\n case 'interruption':\n return node.interruptionType;\n case 'opaque':\n return `(opaque: ${node.reason})`;\n case 'unknown':\n return `(unknown: ${node.reason})`;\n }\n}\n\n/** Track whether parallel/race nodes are encountered during a walk. */\ninterface WalkState {\n hasParallelism: boolean;\n serviceCallsSeen: Set<string>;\n}\n\n// ---------------------------------------------------------------------------\n// Core recursive walker\n// ---------------------------------------------------------------------------\n\n/**\n * Recursively walks a `StaticFlowNode` and produces indented description lines.\n */\nexport function explainNode(\n node: StaticFlowNode,\n depth: number,\n state: WalkState = { hasParallelism: false, serviceCallsSeen: new Set() },\n): string[] {\n const pad = indent(depth);\n const lines: string[] = [];\n\n switch (node.type) {\n // ----- effect -----------------------------------------------------------\n case 'effect': {\n if (node.serviceCall) {\n state.serviceCallsSeen.add(node.serviceCall.serviceType);\n // Tag-style service acquisition (e.g. yield* Logger)\n if (\n node.callee.includes('Tag') ||\n node.callee.includes('Context') ||\n node.callee === node.serviceCall.serviceType\n ) {\n lines.push(`${pad}Acquires ${node.serviceCall.serviceType} service`);\n } else {\n const desc = node.description ? ` — ${node.description}` : '';\n lines.push(\n `${pad}Calls ${node.serviceCall.serviceType}.${node.serviceCall.methodName}${desc}`,\n );\n }\n } else {\n const label = node.displayName ?? node.callee;\n const desc = node.description ? ` — ${node.description}` : '';\n // If displayName has a binding arrow (e.g. \"logger <- Logger\"), it's a service yield\n if (label.includes(' <- ')) {\n lines.push(`${pad}Yields ${label}`);\n } else {\n lines.push(`${pad}Calls ${label}${desc}`);\n }\n }\n break;\n }\n\n // ----- generator --------------------------------------------------------\n case 'generator': {\n for (const y of node.yields) {\n const childLines = explainNode(y.effect, depth, state);\n // If variableName and the displayName already contains it (e.g. \"logger <- Logger\"),\n // skip adding it again. Otherwise prefix with \"varName = ...\"\n const firstChild = childLines[0];\n if (y.variableName && firstChild !== undefined) {\n const trimmed = firstChild.trimStart();\n const alreadyHasBinding = trimmed.includes(`${y.variableName} <-`) || trimmed.includes(`${y.variableName} =`);\n if (!alreadyHasBinding) {\n childLines[0] = `${pad}${y.variableName} = ${trimmed.replace(/^Calls /, '')}`;\n }\n }\n lines.push(...childLines);\n }\n if (node.returnNode) {\n const retLines = explainNode(node.returnNode, depth, state);\n const firstRet = retLines[0];\n if (firstRet !== undefined) {\n const trimmed = firstRet.trimStart();\n retLines[0] = `${pad}Returns ${trimmed.replace(/^Calls /, '')}`;\n lines.push(...retLines);\n }\n }\n break;\n }\n\n // ----- pipe -------------------------------------------------------------\n case 'pipe': {\n lines.push(`${pad}Pipes ${shortLabel(node.initial)} through:`);\n const initLines = explainNode(node.initial, depth + 1, state);\n lines.push(...initLines);\n for (const t of node.transformations) {\n const tLines = explainNode(t, depth + 1, state);\n lines.push(...tLines);\n }\n break;\n }\n\n // ----- parallel ---------------------------------------------------------\n case 'parallel': {\n state.hasParallelism = true;\n const concDesc =\n node.concurrency !== undefined && node.concurrency !== 'sequential'\n ? ` (concurrency: ${node.concurrency})`\n : '';\n lines.push(\n `${pad}Runs ${node.children.length} effects in ${node.mode}${concDesc}:`,\n );\n for (const child of node.children) {\n lines.push(...explainNode(child, depth + 1, state));\n }\n break;\n }\n\n // ----- race -------------------------------------------------------------\n case 'race': {\n state.hasParallelism = true;\n lines.push(`${pad}Races ${node.children.length} effects:`);\n for (const child of node.children) {\n lines.push(...explainNode(child, depth + 1, state));\n }\n break;\n }\n\n // ----- error-handler ----------------------------------------------------\n case 'error-handler': {\n const tagInfo = node.errorTag\n ? ` \"${node.errorTag}\"`\n : node.errorTags && node.errorTags.length > 0\n ? ` [${node.errorTags.join(', ')}]`\n : '';\n switch (node.handlerType) {\n case 'catchAll':\n lines.push(`${pad}Catches all errors on:`);\n break;\n case 'catchTag':\n lines.push(`${pad}Catches tag${tagInfo} on:`);\n break;\n case 'catchTags':\n lines.push(`${pad}Catches tags${tagInfo} on:`);\n break;\n case 'orElse':\n lines.push(`${pad}Falls back (orElse) on error:`);\n break;\n case 'orDie':\n lines.push(`${pad}Converts errors to defects (orDie):`);\n break;\n case 'mapError':\n lines.push(`${pad}Maps error on:`);\n break;\n case 'ignore':\n lines.push(`${pad}Ignores errors on:`);\n break;\n default:\n lines.push(`${pad}Handles errors (${node.handlerType})${tagInfo}:`);\n }\n lines.push(...explainNode(node.source, depth + 1, state));\n if (node.handler) {\n lines.push(`${pad} Handler:`);\n lines.push(...explainNode(node.handler, depth + 2, state));\n }\n break;\n }\n\n // ----- retry ------------------------------------------------------------\n case 'retry': {\n if (node.scheduleInfo) {\n const maxPart =\n node.scheduleInfo.maxRetries !== undefined\n ? `max ${node.scheduleInfo.maxRetries}`\n : '';\n const stratPart = node.scheduleInfo.baseStrategy;\n const parts = [maxPart, stratPart].filter(Boolean).join(', ');\n lines.push(`${pad}Retries (${parts}):`);\n } else if (node.schedule) {\n lines.push(`${pad}Retries with ${node.schedule}:`);\n } else {\n lines.push(`${pad}Retries:`);\n }\n lines.push(...explainNode(node.source, depth + 1, state));\n if (node.hasFallback) {\n lines.push(`${pad} (with fallback on exhaustion)`);\n }\n break;\n }\n\n // ----- timeout ----------------------------------------------------------\n case 'timeout': {\n const dur = node.duration ? ` after ${node.duration}` : '';\n lines.push(`${pad}Times out${dur}:`);\n lines.push(...explainNode(node.source, depth + 1, state));\n if (node.hasFallback) {\n lines.push(`${pad} (with fallback on timeout)`);\n }\n break;\n }\n\n // ----- resource ---------------------------------------------------------\n case 'resource': {\n lines.push(`${pad}Acquires resource:`);\n lines.push(...explainNode(node.acquire, depth + 1, state));\n if (node.use) {\n lines.push(`${pad} Uses:`);\n lines.push(...explainNode(node.use, depth + 2, state));\n }\n lines.push(`${pad} Then releases:`);\n lines.push(...explainNode(node.release, depth + 2, state));\n break;\n }\n\n // ----- conditional ------------------------------------------------------\n case 'conditional': {\n const label = node.conditionLabel ?? node.condition;\n lines.push(`${pad}If ${label}:`);\n lines.push(...explainNode(node.onTrue, depth + 1, state));\n if (node.onFalse) {\n lines.push(`${pad}Else:`);\n lines.push(...explainNode(node.onFalse, depth + 1, state));\n }\n break;\n }\n\n // ----- decision ---------------------------------------------------------\n case 'decision': {\n lines.push(`${pad}If ${node.condition}:`);\n for (const child of node.onTrue) {\n lines.push(...explainNode(child, depth + 1, state));\n }\n if (node.onFalse && node.onFalse.length > 0) {\n lines.push(`${pad}Else:`);\n for (const child of node.onFalse) {\n lines.push(...explainNode(child, depth + 1, state));\n }\n }\n break;\n }\n\n // ----- switch -----------------------------------------------------------\n case 'switch': {\n lines.push(`${pad}Switch on ${node.expression}:`);\n for (const c of node.cases) {\n const caseLabel = c.isDefault\n ? 'default'\n : c.labels.join(', ');\n lines.push(`${pad} Case ${caseLabel}:`);\n for (const child of c.body) {\n lines.push(...explainNode(child, depth + 2, state));\n }\n }\n break;\n }\n\n // ----- try-catch --------------------------------------------------------\n case 'try-catch': {\n lines.push(`${pad}Try:`);\n for (const child of node.tryBody) {\n lines.push(...explainNode(child, depth + 1, state));\n }\n if (node.catchBody && node.catchBody.length > 0) {\n lines.push(`${pad}Catch:`);\n for (const child of node.catchBody) {\n lines.push(...explainNode(child, depth + 1, state));\n }\n }\n if (node.finallyBody && node.finallyBody.length > 0) {\n lines.push(`${pad}Finally:`);\n for (const child of node.finallyBody) {\n lines.push(...explainNode(child, depth + 1, state));\n }\n }\n break;\n }\n\n // ----- terminal ---------------------------------------------------------\n case 'terminal': {\n switch (node.terminalKind) {\n case 'return': {\n if (node.value && node.value.length > 0) {\n lines.push(`${pad}Returns:`);\n for (const child of node.value) {\n lines.push(...explainNode(child, depth + 1, state));\n }\n } else {\n lines.push(`${pad}Returns`);\n }\n break;\n }\n case 'throw':\n lines.push(`${pad}Throws`);\n break;\n case 'break':\n lines.push(`${pad}Breaks`);\n break;\n case 'continue':\n lines.push(`${pad}Continues`);\n break;\n }\n break;\n }\n\n // ----- loop -------------------------------------------------------------\n case 'loop': {\n const src = node.iterSource ? ` over ${node.iterSource}` : '';\n lines.push(`${pad}Iterates (${node.loopType})${src}:`);\n lines.push(...explainNode(node.body, depth + 1, state));\n break;\n }\n\n // ----- layer ------------------------------------------------------------\n case 'layer': {\n const provides =\n node.provides && node.provides.length > 0\n ? ` providing ${node.provides.join(', ')}`\n : '';\n const requires =\n node.requires && node.requires.length > 0\n ? ` (requires ${node.requires.join(', ')})`\n : '';\n lines.push(`${pad}Provides layer${provides}${requires}:`);\n for (const op of node.operations) {\n lines.push(...explainNode(op, depth + 1, state));\n }\n break;\n }\n\n // ----- stream -----------------------------------------------------------\n case 'stream': {\n const ops = node.pipeline.map((o) => o.operation).join(' -> ');\n const sinkPart = node.sink ? ` -> ${node.sink}` : '';\n lines.push(`${pad}Stream: ${ops}${sinkPart}`);\n lines.push(...explainNode(node.source, depth + 1, state));\n break;\n }\n\n // ----- fiber ------------------------------------------------------------\n case 'fiber': {\n const scopeNote = node.isDaemon ? ' (daemon)' : node.isScoped ? ' (scoped)' : '';\n lines.push(`${pad}Fiber ${node.operation}${scopeNote}:`);\n if (node.fiberSource) {\n lines.push(...explainNode(node.fiberSource, depth + 1, state));\n }\n break;\n }\n\n // ----- concurrency-primitive --------------------------------------------\n case 'concurrency-primitive': {\n const cap = node.capacity !== undefined ? ` (capacity: ${node.capacity})` : '';\n lines.push(`${pad}${node.primitive}.${node.operation}${cap}`);\n if (node.source) {\n lines.push(...explainNode(node.source, depth + 1, state));\n }\n break;\n }\n\n // ----- match ------------------------------------------------------------\n case 'match': {\n if (node.matchedTags && node.matchedTags.length > 0) {\n lines.push(`${pad}Matches tags: ${node.matchedTags.join(', ')}`);\n } else {\n lines.push(`${pad}Match (${node.matchOp})`);\n }\n break;\n }\n\n // ----- transform --------------------------------------------------------\n case 'transform': {\n lines.push(`${pad}Transforms via ${node.transformType}`);\n if (node.source) {\n lines.push(...explainNode(node.source, depth + 1, state));\n }\n break;\n }\n\n // ----- cause ------------------------------------------------------------\n case 'cause': {\n lines.push(`${pad}Cause.${node.causeOp}`);\n if (node.children) {\n for (const child of node.children) {\n lines.push(...explainNode(child, depth + 1, state));\n }\n }\n break;\n }\n\n // ----- exit -------------------------------------------------------------\n case 'exit': {\n lines.push(`${pad}Exit.${node.exitOp}`);\n break;\n }\n\n // ----- schedule ---------------------------------------------------------\n case 'schedule': {\n lines.push(`${pad}Schedule.${node.scheduleOp}`);\n break;\n }\n\n // ----- channel ----------------------------------------------------------\n case 'channel': {\n const ops = node.pipeline.map((o) => o.operation).join(' -> ');\n lines.push(`${pad}Channel${ops ? `: ${ops}` : ''}`);\n if (node.source) {\n lines.push(...explainNode(node.source, depth + 1, state));\n }\n break;\n }\n\n // ----- sink -------------------------------------------------------------\n case 'sink': {\n const ops = node.pipeline.map((o) => o.operation).join(' -> ');\n lines.push(`${pad}Sink${ops ? `: ${ops}` : ''}`);\n if (node.source) {\n lines.push(...explainNode(node.source, depth + 1, state));\n }\n break;\n }\n\n // ----- interruption -----------------------------------------------------\n case 'interruption': {\n lines.push(`${pad}${node.interruptionType}`);\n if (node.source) {\n lines.push(...explainNode(node.source, depth + 1, state));\n }\n if (node.handler) {\n lines.push(`${pad} On interrupt:`);\n lines.push(...explainNode(node.handler, depth + 2, state));\n }\n break;\n }\n\n // ----- opaque -----------------------------------------------------------\n case 'opaque': {\n lines.push(`${pad}(opaque: ${node.reason})`);\n break;\n }\n\n // ----- unknown ----------------------------------------------------------\n case 'unknown': {\n lines.push(`${pad}(unknown: ${node.reason})`);\n break;\n }\n }\n\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// Program-level renderer\n// ---------------------------------------------------------------------------\n\nfunction renderProgram(program: StaticEffectProgram, _ir: StaticEffectIR): string {\n const state: WalkState = {\n hasParallelism: false,\n serviceCallsSeen: new Set(),\n };\n\n // Collect body lines from children\n const bodyLines: string[] = [];\n for (const child of program.children) {\n bodyLines.push(...explainNode(child, 1, state));\n }\n\n // Number top-level steps\n const numberedLines = numberTopLevelSteps(bodyLines);\n\n // Header\n const header = `${program.programName} (${program.source}):`;\n\n // Footer sections\n const footer: string[] = [];\n\n // Services required\n const services = new Set<string>();\n for (const dep of program.dependencies) {\n services.add(dep.name);\n }\n Array.from(state.serviceCallsSeen).forEach((svc) => {\n services.add(svc);\n });\n if (services.size > 0) {\n footer.push(` Services required: ${Array.from(services).join(', ')}`);\n }\n\n // Error paths\n if (program.errorTypes.length > 0) {\n footer.push(` Error paths: ${program.errorTypes.join(', ')}`);\n }\n\n // Concurrency\n if (state.hasParallelism) {\n footer.push(' Concurrency: uses parallelism / racing');\n } else {\n footer.push(' Concurrency: sequential (no parallelism)');\n }\n\n const sections = [header, numberedLines.join('\\n')];\n if (footer.length > 0) {\n sections.push('');\n sections.push(footer.join('\\n'));\n }\n\n return sections.join('\\n');\n}\n\n/**\n * Numbers lines at depth=1 (2 leading spaces) as top-level steps,\n * leaving deeper lines unchanged.\n */\nfunction numberTopLevelSteps(lines: string[]): string[] {\n let step = 0;\n return lines.map((line) => {\n // Depth-1 lines start with exactly 2 spaces then a non-space character\n if (/^ {2}\\S/.test(line)) {\n step++;\n return ` ${step}. ${line.trimStart()}`;\n }\n return line;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Renders a full plain-English explanation for a single Effect IR program.\n */\nexport function renderExplanation(ir: StaticEffectIR): string {\n return renderProgram(ir.root, ir);\n}\n\n/**\n * Renders explanations for multiple programs, separated by `---`.\n */\nexport function renderMultipleExplanations(irs: readonly StaticEffectIR[]): string {\n return irs.map((ir) => renderExplanation(ir)).join('\\n\\n---\\n\\n');\n}\n","/**\n * Summary Output Module\n *\n * Produces ultra-compact one-liner-per-program output for quick overview\n * of Effect program characteristics.\n */\n\nimport type { StaticEffectIR } from '../types';\nimport { calculateComplexity } from '../complexity';\n\n// =============================================================================\n// Source Kind Abbreviations\n// =============================================================================\n\nconst SOURCE_ABBREVIATIONS: Record<StaticEffectIR['root']['source'], string> = {\n generator: 'gen',\n direct: 'direct',\n pipe: 'pipe',\n run: 'run',\n 'workflow-execute': 'wf-exec',\n class: 'class',\n classProperty: 'classProp',\n classMethod: 'classMeth',\n};\n\nfunction abbreviateSource(source: StaticEffectIR['root']['source']): string {\n return SOURCE_ABBREVIATIONS[source];\n}\n\n// =============================================================================\n// Single Program Summary\n// =============================================================================\n\n/**\n * Render a one-line summary for a single Effect program IR.\n *\n * Format:\n * programName | gen | 6 steps | 2 services | 0 errors | 1 handler | complexity: 2\n */\nexport function renderSummary(ir: StaticEffectIR): string {\n const name = ir.root.programName;\n const kind = abbreviateSource(ir.root.source);\n const steps = ir.metadata.stats.totalEffects;\n const services = ir.root.dependencies.length;\n const errors = ir.root.errorTypes.length;\n const handlers = ir.metadata.stats.errorHandlerCount;\n const complexity = calculateComplexity(ir).cyclomaticComplexity;\n\n return [\n name,\n kind,\n `${steps} steps`,\n `${services} services`,\n `${errors} errors`,\n `${handlers} ${handlers === 1 ? 'handler' : 'handlers'}`,\n `complexity: ${complexity}`,\n ].join(' | ');\n}\n\n// =============================================================================\n// Multiple Program Summary Table\n// =============================================================================\n\ninterface SummaryRow {\n readonly program: string;\n readonly kind: string;\n readonly steps: number;\n readonly services: number;\n readonly errors: number;\n readonly handlers: number;\n readonly complexity: number;\n}\n\nfunction extractRow(ir: StaticEffectIR): SummaryRow {\n return {\n program: ir.root.programName,\n kind: abbreviateSource(ir.root.source),\n steps: ir.metadata.stats.totalEffects,\n services: ir.root.dependencies.length,\n errors: ir.root.errorTypes.length,\n handlers: ir.metadata.stats.errorHandlerCount,\n complexity: calculateComplexity(ir).cyclomaticComplexity,\n };\n}\n\n/**\n * Render a formatted, column-aligned table summarizing multiple Effect program IRs.\n *\n * Example output:\n * Program | Kind | Steps | Services | Errors | Handlers | Complexity\n * -----------------+------+-------+----------+--------+----------+-----------\n * serviceProgram | gen | 6 | 2 | 0 | 0 | 2\n * databaseProgram | gen | 5 | 2 | 1 | 1 | 3\n */\nexport function renderMultipleSummaries(irs: readonly StaticEffectIR[]): string {\n if (irs.length === 0) {\n return '(no programs)';\n }\n\n const rows = irs.map(extractRow);\n\n // Header labels\n const headers = {\n program: 'Program',\n kind: 'Kind',\n steps: 'Steps',\n services: 'Services',\n errors: 'Errors',\n handlers: 'Handlers',\n complexity: 'Complexity',\n };\n\n // Calculate column widths: max of header width and all row values\n const widths = {\n program: Math.max(headers.program.length, ...rows.map((r) => r.program.length)),\n kind: Math.max(headers.kind.length, ...rows.map((r) => r.kind.length)),\n steps: Math.max(headers.steps.length, ...rows.map((r) => String(r.steps).length)),\n services: Math.max(headers.services.length, ...rows.map((r) => String(r.services).length)),\n errors: Math.max(headers.errors.length, ...rows.map((r) => String(r.errors).length)),\n handlers: Math.max(headers.handlers.length, ...rows.map((r) => String(r.handlers).length)),\n complexity: Math.max(headers.complexity.length, ...rows.map((r) => String(r.complexity).length)),\n };\n\n const padRight = (s: string, w: number) => s + ' '.repeat(Math.max(0, w - s.length));\n const padLeft = (s: string, w: number) => ' '.repeat(Math.max(0, w - s.length)) + s;\n\n // Header line\n const headerLine = [\n padRight(headers.program, widths.program),\n padRight(headers.kind, widths.kind),\n padRight(headers.steps, widths.steps),\n padRight(headers.services, widths.services),\n padRight(headers.errors, widths.errors),\n padRight(headers.handlers, widths.handlers),\n padRight(headers.complexity, widths.complexity),\n ].join(' | ');\n\n // Separator line\n const separatorLine = [\n '-'.repeat(widths.program),\n '-'.repeat(widths.kind),\n '-'.repeat(widths.steps),\n '-'.repeat(widths.services),\n '-'.repeat(widths.errors),\n '-'.repeat(widths.handlers),\n '-'.repeat(widths.complexity),\n ].join('-+-');\n\n // Data rows: program left-aligned, numeric columns right-aligned\n const dataLines = rows.map((row) =>\n [\n padRight(row.program, widths.program),\n padRight(row.kind, widths.kind),\n padLeft(String(row.steps), widths.steps),\n padLeft(String(row.services), widths.services),\n padLeft(String(row.errors), widths.errors),\n padLeft(String(row.handlers), widths.handlers),\n padLeft(String(row.complexity), widths.complexity),\n ].join(' | '),\n );\n\n return [headerLine, separatorLine, ...dataLines].join('\\n');\n}\n","import type { StaticEffectIR, ProjectServiceMap } from '../types';\n\n/**\n * Build a program x service dependency matrix as a markdown table from IR dependencies.\n */\nexport function renderDependencyMatrix(irs: readonly StaticEffectIR[]): string {\n // Collect all unique service/dependency names and program names.\n // Note: program names can collide (e.g. multiple `main` programs across files).\n // We render one row per program name, but preserve the *actual* program count in the footer.\n const serviceSet = new Set<string>();\n const depsByProgramName = new Map<string, Set<string>>();\n\n for (const ir of irs) {\n const programName = ir.root.programName;\n const depSet = depsByProgramName.get(programName) ?? new Set<string>();\n for (const dep of ir.root.dependencies) {\n serviceSet.add(dep.name);\n depSet.add(dep.name);\n }\n depsByProgramName.set(programName, depSet);\n }\n\n const services = [...serviceSet].sort((a, b) => a.localeCompare(b));\n const programNames = [...depsByProgramName.keys()].sort((a, b) =>\n a.localeCompare(b),\n );\n\n return buildMarkdownTable(\n programNames,\n services,\n (program, service) => {\n const deps = depsByProgramName.get(program);\n return deps ? deps.has(service) : false;\n },\n { programs: irs.length, services: services.length },\n );\n}\n\n/**\n * Build a program x service dependency matrix as a markdown table from the\n * project-level service map (more accurate than IR-based).\n */\nexport function renderDependencyMatrixFromServiceMap(\n serviceMap: ProjectServiceMap,\n): string {\n const services: string[] = [];\n const programSet = new Set<string>();\n const programInstances = new Set<string>();\n const serviceToProgramsMap = new Map<string, Set<string>>();\n\n for (const [serviceId, artifact] of serviceMap.services) {\n services.push(serviceId);\n const consumerPrograms = new Set<string>();\n for (const consumer of artifact.consumers) {\n consumerPrograms.add(consumer.programName);\n programSet.add(consumer.programName);\n // Program names can collide across files; preserve true program instance count.\n programInstances.add(`${consumer.filePath}::${consumer.programName}`);\n }\n serviceToProgramsMap.set(serviceId, consumerPrograms);\n }\n\n services.sort((a, b) => a.localeCompare(b));\n const programs = [...programSet].sort((a, b) => a.localeCompare(b));\n\n return buildMarkdownTable(programs, services, (program, service) => {\n const consumers = serviceToProgramsMap.get(service);\n return consumers ? consumers.has(program) : false;\n }, { programs: programInstances.size, services: services.length });\n}\n\n/**\n * Render a markdown table with programs as rows and services as columns.\n */\nfunction buildMarkdownTable(\n programs: readonly string[],\n services: readonly string[],\n hasRelation: (program: string, service: string) => boolean,\n summary?: { readonly programs: number; readonly services: number },\n): string {\n const summaryPrograms = summary?.programs ?? programs.length;\n const summaryServices = summary?.services ?? services.length;\n if (programs.length === 0 || services.length === 0) {\n return `_No dependencies found._\\n\\n${summaryPrograms} programs × ${summaryServices} services`;\n }\n\n const lines: string[] = [];\n\n // Header row\n lines.push(`| Program | ${services.join(' | ')} |`);\n\n // Separator row with centered alignment for service columns\n const separators = services.map((s) => `:${'-'.repeat(Math.max(s.length - 2, 1))}:`);\n lines.push(`|${'-'.repeat(9)}|${separators.join('|')}|`);\n\n // Data rows\n for (const program of programs) {\n const cells = services.map((service) => (hasRelation(program, service) ? '✓' : ''));\n lines.push(`| ${program} | ${cells.join(' | ')} |`);\n }\n\n lines.push('');\n lines.push(`${summaryPrograms} programs × ${summaryServices} services`);\n\n return lines.join('\\n');\n}\n","/**\n * JSON output generation for Effect IR\n */\n\nimport { Effect } from 'effect';\nimport type { StaticEffectIR, JSONRenderOptions } from '../types';\n\nconst DEFAULT_OPTIONS: JSONRenderOptions = {\n pretty: true,\n includeMetadata: true,\n compact: false,\n};\n\n/**\n * Render Effect IR as JSON string\n */\nexport const renderJSON = (\n ir: StaticEffectIR,\n options?: Partial<JSONRenderOptions>,\n): Effect.Effect<string> =>\n Effect.gen(function* () {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const space = opts.pretty ? 2 : undefined;\n\n const data = opts.includeMetadata\n ? {\n root: ir.root,\n metadata: ir.metadata,\n references:\n ir.references instanceof Map\n ? Object.fromEntries(ir.references)\n : ir.references,\n }\n : { root: ir.root };\n\n return JSON.stringify(data, replacer, space);\n });\n\n/**\n * Render multiple Effect IRs as JSON array\n */\nexport const renderMultipleJSON = (\n irs: readonly StaticEffectIR[],\n options?: Partial<JSONRenderOptions>,\n): Effect.Effect<string> =>\n Effect.gen(function* () {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n const space = opts.pretty ? 2 : undefined;\n\n const data = irs.map((ir) =>\n opts.includeMetadata\n ? {\n root: ir.root,\n metadata: ir.metadata,\n references:\n ir.references instanceof Map\n ? Object.fromEntries(ir.references)\n : ir.references,\n }\n : { root: ir.root },\n );\n\n return JSON.stringify(data, replacer, space);\n });\n\n/**\n * JSON replacer to handle circular references and special types\n */\nconst replacer = (_key: string, value: unknown): unknown => {\n // Handle Map\n if (value instanceof Map) {\n return Object.fromEntries(value);\n }\n\n // Handle Set\n if (value instanceof Set) {\n return Array.from(value);\n }\n\n // Handle BigInt\n if (typeof value === 'bigint') {\n return value.toString();\n }\n\n // Handle Option\n if (value && typeof value === 'object' && '_tag' in value) {\n // This is likely an Option\n return value;\n }\n\n return value;\n};\n","/**\n * Interactive HTML Output (GAP 22 v2)\n *\n * Generates a self-contained HTML file with:\n * - Embedded IR and Mermaid diagram\n * - Search/filter nodes by type, name, complexity\n * - Click-to-navigate: click node to see source location, IR details\n * - Path explorer: select a path and highlight it\n * - Complexity heatmap: color nodes by complexity contribution\n * - Error/data flow toggles\n * - 6-theme system with system preference detection and localStorage persistence\n */\n\nimport type { StaticEffectIR } from '../types';\nimport { renderStaticMermaid } from './mermaid';\nimport { generatePaths } from '../path-generator';\nimport { calculateComplexity } from '../complexity';\n\nexport type HtmlTheme = 'midnight' | 'ocean' | 'ember' | 'forest' | 'daylight' | 'paper';\n\nexport interface HtmlOutputOptions {\n readonly title?: string | undefined;\n /** Named theme, or legacy 'light'/'dark' aliases (mapped to daylight/midnight). */\n readonly theme?: HtmlTheme | 'light' | 'dark' | undefined;\n}\n\n/**\n * Maps legacy theme aliases to their named equivalents.\n * Returns the theme name unchanged if it's already a named theme.\n */\nexport function resolveThemeName(\n theme: HtmlTheme | 'light' | 'dark' | undefined,\n): HtmlTheme | undefined {\n if (theme === 'light') return 'daylight';\n if (theme === 'dark') return 'midnight';\n return theme;\n}\n\n\n/**\n * Render IR as a self-contained HTML page with interactive features.\n */\nexport function renderInteractiveHTML(\n ir: StaticEffectIR,\n options: HtmlOutputOptions = {},\n): string {\n const title = options.title ?? `${ir.root.programName} - Effect Analysis`;\n const resolvedTheme = resolveThemeName(options.theme);\n const mermaidCode = renderStaticMermaid(ir).replace(/<\\/script>/gi, '<\\\\/script>');\n\n // Generate paths and complexity for embedding\n const paths = generatePaths(ir);\n const complexity = calculateComplexity(ir);\n\n // Also generate the data-flow and error-flow overlay versions\n const mermaidWithDataFlow = renderStaticMermaid(ir, { dataFlowOverlay: true }).replace(/<\\/script>/gi, '<\\\\/script>');\n const mermaidWithErrorFlow = renderStaticMermaid(ir, { errorFlowOverlay: true }).replace(/<\\/script>/gi, '<\\\\/script>');\n\n const irJson = JSON.stringify(ir, null, 2)\n .replace(/</g, '\\\\u003c')\n .replace(/>/g, '\\\\u003e');\n\n const pathsJson = JSON.stringify(paths, null, 2)\n .replace(/</g, '\\\\u003c')\n .replace(/>/g, '\\\\u003e');\n\n const complexityJson = JSON.stringify(complexity, null, 2)\n .replace(/</g, '\\\\u003c')\n .replace(/>/g, '\\\\u003e');\n\n const initialThemeJs = resolvedTheme ? `\"${resolvedTheme}\"` : 'null';\n\n return `<!DOCTYPE html>\n<html lang=\"en\" data-theme=\"midnight\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>${escapeHtml(title)}</title>\n <script src=\"https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js\"></scr` + `ipt>\n <style>\n /* Theme definitions */\n [data-theme=\"midnight\"] {\n --bg: #0f1117; --fg: #d4d7e0; --panel-bg: #161921; --header-bg: #1c1f2b;\n --border: #262a3a; --accent: #7b9dea; --accent-dim: rgba(123,157,234,0.12);\n --selected-bg: #1a3a5c;\n }\n [data-theme=\"ocean\"] {\n --bg: #0a1628; --fg: #c8d8ee; --panel-bg: #0f1e35; --header-bg: #142742;\n --border: #1a3452; --accent: #4da6e8; --accent-dim: rgba(77,166,232,0.12);\n --selected-bg: #0f2847;\n }\n [data-theme=\"ember\"] {\n --bg: #1a0f0f; --fg: #e0d0c8; --panel-bg: #221414; --header-bg: #2e1a1a;\n --border: #3a2222; --accent: #e8845a; --accent-dim: rgba(232,132,90,0.12);\n --selected-bg: #2e1a1a;\n }\n [data-theme=\"forest\"] {\n --bg: #0c1a0f; --fg: #c8d8c8; --panel-bg: #111f14; --header-bg: #18281a;\n --border: #1e3a20; --accent: #5ac87a; --accent-dim: rgba(90,200,122,0.12);\n --selected-bg: #18281a;\n }\n [data-theme=\"daylight\"] {\n --bg: #f8f9fb; --fg: #1a2030; --panel-bg: #ffffff; --header-bg: #ffffff;\n --border: #dde1ea; --accent: #3a6fd8; --accent-dim: rgba(58,111,216,0.08);\n --selected-bg: #e3f2fd;\n }\n [data-theme=\"paper\"] {\n --bg: #faf8f5; --fg: #2a2218; --panel-bg: #fffefa; --header-bg: #fffefa;\n --border: #e0d8cc; --accent: #b07830; --accent-dim: rgba(176,120,48,0.08);\n --selected-bg: #f4f0e8;\n }\n\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body { font-family: system-ui, -apple-system, sans-serif; background: var(--bg); color: var(--fg); }\n\n .header { padding: 0.75rem 1rem; background: var(--header-bg); border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }\n .header h1 { font-size: 1.1rem; font-weight: 600; }\n .header .stats { font-size: 0.8rem; opacity: 0.7; }\n\n .theme-picker { position: relative; margin-left: auto; }\n .theme-picker button { padding: 4px 10px; border: 1px solid var(--border); border-radius: 4px; background: var(--panel-bg); color: var(--fg); cursor: pointer; font-size: 0.8rem; }\n .theme-menu { display: none; position: absolute; right: 0; top: 100%; margin-top: 4px; background: var(--panel-bg); border: 1px solid var(--border); border-radius: 6px; padding: 4px 0; min-width: 140px; z-index: 100; box-shadow: 0 4px 12px rgba(0,0,0,0.2); }\n .theme-menu.open { display: block; }\n .theme-menu button { display: block; width: 100%; padding: 6px 12px; border: none; background: transparent; color: var(--fg); text-align: left; cursor: pointer; font-size: 0.8rem; }\n .theme-menu button:hover { background: var(--accent-dim); }\n .theme-menu button.active { color: var(--accent); font-weight: 600; }\n\n .toolbar { padding: 0.5rem 1rem; background: var(--panel-bg); border-bottom: 1px solid var(--border); display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: center; }\n .toolbar input[type=\"text\"] { padding: 4px 8px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg); color: var(--fg); font-size: 0.85rem; width: 200px; }\n .toolbar select { padding: 4px 8px; border: 1px solid var(--border); border-radius: 4px; background: var(--bg); color: var(--fg); font-size: 0.85rem; }\n .toolbar label { font-size: 0.85rem; display: flex; align-items: center; gap: 4px; cursor: pointer; }\n .toolbar .sep { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }\n\n .layout { display: grid; grid-template-columns: 1fr 380px; height: calc(100vh - 90px); }\n @media (max-width: 900px) { .layout { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; } }\n\n .diagram-pane { overflow: auto; padding: 1rem; border-right: 1px solid var(--border); }\n .diagram-pane .mermaid { min-height: 200px; }\n\n .sidebar { overflow-y: auto; display: flex; flex-direction: column; }\n .sidebar-tabs { display: flex; border-bottom: 1px solid var(--border); background: var(--header-bg); }\n .sidebar-tabs button { flex: 1; padding: 8px; border: none; background: transparent; color: var(--fg); cursor: pointer; font-size: 0.8rem; border-bottom: 2px solid transparent; }\n .sidebar-tabs button.active { border-bottom-color: var(--accent); font-weight: 600; }\n .sidebar-tabs button:hover { background: var(--panel-bg); }\n\n .tab-content { flex: 1; overflow-y: auto; padding: 0.75rem; font-size: 0.85rem; }\n .tab-content[hidden] { display: none; }\n\n .detail-section { margin-bottom: 1rem; }\n .detail-section h3 { font-size: 0.9rem; margin-bottom: 0.4rem; color: var(--accent); }\n .detail-section pre { background: var(--panel-bg); padding: 0.5rem; border-radius: 4px; overflow-x: auto; font-size: 0.75rem; white-space: pre-wrap; word-break: break-word; }\n .detail-section table { width: 100%; border-collapse: collapse; font-size: 0.8rem; }\n .detail-section td, .detail-section th { padding: 4px 8px; text-align: left; border-bottom: 1px solid var(--border); }\n\n .path-item { padding: 6px 8px; border: 1px solid var(--border); border-radius: 4px; margin-bottom: 4px; cursor: pointer; font-size: 0.8rem; }\n .path-item:hover { background: var(--panel-bg); }\n .path-item.selected { border-color: var(--accent); background: var(--selected-bg); }\n .path-step { display: inline-block; padding: 2px 6px; margin: 1px; background: var(--panel-bg); border-radius: 3px; font-size: 0.75rem; }\n\n .complexity-badge { display: inline-block; padding: 2px 8px; border-radius: 10px; font-size: 0.75rem; font-weight: 600; }\n .complexity-low { background: #C8E6C9; color: #1B5E20; }\n .complexity-medium { background: #FFF9C4; color: #F57F17; }\n .complexity-high { background: #FFCDD2; color: #B71C1C; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <h1>${escapeHtml(title)}</h1>\n <span class=\"stats\" id=\"complexity-stats\"></span>\n <div class=\"theme-picker\">\n <button onclick=\"toggleThemeMenu()\" id=\"theme-btn\">Theme</button>\n <div class=\"theme-menu\" id=\"theme-menu\">\n <button onclick=\"applyTheme('midnight')\">Midnight</button>\n <button onclick=\"applyTheme('ocean')\">Ocean</button>\n <button onclick=\"applyTheme('ember')\">Ember</button>\n <button onclick=\"applyTheme('forest')\">Forest</button>\n <button onclick=\"applyTheme('daylight')\">Daylight</button>\n <button onclick=\"applyTheme('paper')\">Paper</button>\n </div>\n </div>\n </div>\n <div class=\"toolbar\">\n <input type=\"text\" id=\"search\" placeholder=\"Search nodes...\" oninput=\"handleSearch(this.value)\">\n <select id=\"typeFilter\" onchange=\"handleTypeFilter(this.value)\">\n <option value=\"\">All types</option>\n </select>\n <div class=\"sep\"></div>\n <label><input type=\"checkbox\" id=\"toggleDataFlow\" onchange=\"toggleOverlay('data')\"> Data Flow</label>\n <label><input type=\"checkbox\" id=\"toggleErrorFlow\" onchange=\"toggleOverlay('error')\"> Error Flow</label>\n <div class=\"sep\"></div>\n <select id=\"pathSelect\" onchange=\"selectPath(this.value)\">\n <option value=\"\">Select path...</option>\n </select>\n </div>\n <div class=\"layout\">\n <div class=\"diagram-pane\">\n <pre class=\"mermaid\" id=\"mermaid-diagram\">${escapeHtml(mermaidCode)}</pre>\n </div>\n <div class=\"sidebar\">\n <div class=\"sidebar-tabs\">\n <button class=\"active\" onclick=\"showTab('details')\">Details</button>\n <button onclick=\"showTab('paths')\">Paths</button>\n <button onclick=\"showTab('ir')\">IR</button>\n </div>\n <div class=\"tab-content\" id=\"tab-details\">\n <div class=\"detail-section\">\n <h3>Complexity</h3>\n <table id=\"complexity-table\"></table>\n </div>\n <div class=\"detail-section\" id=\"node-details\">\n <h3>Node Details</h3>\n <p style=\"opacity:0.6\">Click a node in the diagram to see details.</p>\n </div>\n </div>\n <div class=\"tab-content\" id=\"tab-paths\" hidden>\n <div id=\"paths-list\"></div>\n </div>\n <div class=\"tab-content\" id=\"tab-ir\" hidden>\n <pre id=\"ir-json\" style=\"font-size:0.7rem\">${irJson}</pre>\n </div>\n </div>\n </div>\n <script>\n var INITIAL_THEME = ${initialThemeJs};\n var STORAGE_KEY = 'effect-viz-theme';\n var DARK_THEMES = ['midnight', 'ocean', 'ember', 'forest'];\n\n var MERMAID_THEME_VARS = {\n midnight: { primaryColor: '#1e2233', primaryTextColor: '#d4d7e0', primaryBorderColor: '#3a4266', lineColor: '#3a4266', secondaryColor: '#262a3a', tertiaryColor: '#1c1f2b', background: '#0f1117', mainBkg: '#1e2233', nodeBorder: '#3a4266', clusterBkg: '#161921', clusterBorder: '#3a4266', titleColor: '#d4d7e0', edgeLabelBackground: '#161921', nodeTextColor: '#d4d7e0' },\n ocean: { primaryColor: '#132d4a', primaryTextColor: '#c8d8ee', primaryBorderColor: '#1f4a70', lineColor: '#1f4a70', secondaryColor: '#0f1e35', tertiaryColor: '#142742', background: '#0a1628', mainBkg: '#132d4a', nodeBorder: '#1f4a70', clusterBkg: '#0f1e35', clusterBorder: '#1f4a70', titleColor: '#c8d8ee', edgeLabelBackground: '#0f1e35', nodeTextColor: '#c8d8ee' },\n ember: { primaryColor: '#2e1c18', primaryTextColor: '#e0d0c8', primaryBorderColor: '#5a3328', lineColor: '#5a3328', secondaryColor: '#221414', tertiaryColor: '#2e1a1a', background: '#1a0f0f', mainBkg: '#2e1c18', nodeBorder: '#5a3328', clusterBkg: '#221414', clusterBorder: '#5a3328', titleColor: '#e0d0c8', edgeLabelBackground: '#221414', nodeTextColor: '#e0d0c8' },\n forest: { primaryColor: '#152e1a', primaryTextColor: '#c8d8c8', primaryBorderColor: '#264a2c', lineColor: '#264a2c', secondaryColor: '#111f14', tertiaryColor: '#18281a', background: '#0c1a0f', mainBkg: '#152e1a', nodeBorder: '#264a2c', clusterBkg: '#111f14', clusterBorder: '#264a2c', titleColor: '#c8d8c8', edgeLabelBackground: '#111f14', nodeTextColor: '#c8d8c8' },\n daylight: { primaryColor: '#e8ecf4', primaryTextColor: '#1a2030', primaryBorderColor: '#b0b8cc', lineColor: '#b0b8cc', secondaryColor: '#f0f2f8', tertiaryColor: '#ffffff', background: '#f8f9fb', mainBkg: '#e8ecf4', nodeBorder: '#b0b8cc', clusterBkg: '#ffffff', clusterBorder: '#dde1ea', titleColor: '#1a2030', edgeLabelBackground: '#ffffff', nodeTextColor: '#1a2030' },\n paper: { primaryColor: '#f0ebe0', primaryTextColor: '#2a2218', primaryBorderColor: '#c8bda8', lineColor: '#c8bda8', secondaryColor: '#f5f0e8', tertiaryColor: '#fffefa', background: '#faf8f5', mainBkg: '#f0ebe0', nodeBorder: '#c8bda8', clusterBkg: '#fffefa', clusterBorder: '#e0d8cc', titleColor: '#2a2218', edgeLabelBackground: '#fffefa', nodeTextColor: '#2a2218' }\n };\n\n function getSystemPreference() {\n if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {\n return 'midnight';\n }\n return 'daylight';\n }\n\n function resolveTheme() {\n if (INITIAL_THEME) return INITIAL_THEME;\n try {\n var stored = localStorage.getItem(STORAGE_KEY);\n if (stored) return stored;\n } catch(e) {}\n return getSystemPreference();\n }\n\n // Restyle SVG nodes after Mermaid renders to match the active theme.\n // Mermaid classDef styles are baked into SVG elements as inline style with !important,\n // so we must directly modify the style attribute to override them.\n function rethemeSvgNodes(themeName) {\n var isDark = DARK_THEMES.indexOf(themeName) >= 0;\n var vars = MERMAID_THEME_VARS[themeName] || MERMAID_THEME_VARS.midnight;\n var svg = document.querySelector('.mermaid svg');\n if (!svg) return;\n // Override all label-container shapes (nodes)\n var shapes = svg.querySelectorAll('.label-container');\n shapes.forEach(function(el) {\n el.setAttribute('style', 'fill:' + vars.primaryColor + ' !important;stroke:' + vars.primaryBorderColor + ' !important;stroke-width:1px !important');\n });\n // Override node labels text color\n var labels = svg.querySelectorAll('.nodeLabel, .label');\n labels.forEach(function(el) {\n el.style.color = vars.primaryTextColor;\n el.style.fill = vars.primaryTextColor;\n });\n // Override edge paths\n var edges = svg.querySelectorAll('.flowchart-link');\n edges.forEach(function(el) {\n el.style.stroke = vars.lineColor;\n });\n // Override edge labels\n var edgeLabels = svg.querySelectorAll('.edgeLabel');\n edgeLabels.forEach(function(el) {\n el.style.backgroundColor = vars.edgeLabelBackground;\n el.style.color = vars.primaryTextColor;\n });\n var edgeLabelRects = svg.querySelectorAll('.edgeLabel rect');\n edgeLabelRects.forEach(function(el) {\n el.setAttribute('style', 'fill:' + vars.edgeLabelBackground + ' !important');\n });\n // Override arrowheads\n var markers = svg.querySelectorAll('.marker, .arrowMarkerPath');\n markers.forEach(function(el) {\n el.setAttribute('style', 'fill:' + vars.lineColor + ' !important;stroke:' + vars.lineColor + ' !important');\n });\n }\n\n function applyTheme(name, skipRerender) {\n document.documentElement.setAttribute('data-theme', name);\n try { localStorage.setItem(STORAGE_KEY, name); } catch(e) {}\n // Update mermaid theme with custom variables matching our theme\n var vars = MERMAID_THEME_VARS[name] || MERMAID_THEME_VARS.midnight;\n mermaid.initialize({ startOnLoad: false, theme: 'base', themeVariables: vars, securityLevel: 'loose' });\n if (!skipRerender) {\n var el = document.getElementById('mermaid-diagram');\n if (el) {\n el.removeAttribute('data-processed');\n mermaid.init(undefined, el);\n // Re-apply node colors after Mermaid re-renders\n setTimeout(function() { rethemeSvgNodes(name); }, 500);\n }\n }\n // Update active state in menu\n var btns = document.querySelectorAll('.theme-menu button');\n btns.forEach(function(b) {\n b.classList.toggle('active', b.textContent.toLowerCase() === name);\n });\n document.getElementById('theme-menu').classList.remove('open');\n }\n\n function toggleThemeMenu() {\n document.getElementById('theme-menu').classList.toggle('open');\n }\n\n // Close menu on outside click\n document.addEventListener('click', function(e) {\n var picker = document.querySelector('.theme-picker');\n if (picker && !picker.contains(e.target)) {\n document.getElementById('theme-menu').classList.remove('open');\n }\n });\n\n // Listen for system preference changes\n if (window.matchMedia) {\n window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) {\n // Only react if no explicit theme was set\n try {\n if (!localStorage.getItem(STORAGE_KEY) && !INITIAL_THEME) {\n applyTheme(e.matches ? 'midnight' : 'daylight');\n }\n } catch(ex) {}\n });\n }\n\n // Apply initial theme (skip re-render since Mermaid hasn't rendered yet)\n applyTheme(resolveTheme(), true);\n\n // Init Mermaid (single init on page load)\n var currentThemeName = resolveTheme();\n var initVars = MERMAID_THEME_VARS[currentThemeName] || MERMAID_THEME_VARS.midnight;\n mermaid.initialize({ startOnLoad: true, theme: 'base', themeVariables: initVars, securityLevel: 'loose' });\n\n const IR_DATA = ${irJson};\n const PATHS_DATA = ${pathsJson};\n const COMPLEXITY = ${complexityJson};\n const DIAGRAMS = {\n base: ${JSON.stringify(mermaidCode)},\n dataFlow: ${JSON.stringify(mermaidWithDataFlow)},\n errorFlow: ${JSON.stringify(mermaidWithErrorFlow)}\n };\n\n // Complexity stats\n document.getElementById('complexity-stats').textContent =\n 'CC: ' + COMPLEXITY.cyclomaticComplexity +\n ' | Cognitive: ' + COMPLEXITY.cognitiveComplexity +\n ' | Depth: ' + COMPLEXITY.maxDepth +\n ' | Paths: ' + COMPLEXITY.pathCount;\n\n // Complexity table\n var ct = document.getElementById('complexity-table');\n ct.innerHTML = Object.entries(COMPLEXITY).map(function(e) {\n return '<tr><td>' + e[0] + '</td><td><b>' + e[1] + '</b></td></tr>';\n }).join('');\n\n // Paths list\n var pl = document.getElementById('paths-list');\n var pathSelect = document.getElementById('pathSelect');\n PATHS_DATA.forEach(function(p, i) {\n var div = document.createElement('div');\n div.className = 'path-item';\n div.onclick = function() { selectPath(i); };\n div.innerHTML = '<b>Path ' + (i+1) + '</b> (' + p.steps.length + ' steps)<br>' +\n p.steps.map(function(s) { return '<span class=\"path-step\">' + (s.name||s.nodeId) + '</span>'; }).join(' \\u2192 ');\n pl.appendChild(div);\n var opt = document.createElement('option');\n opt.value = i;\n opt.textContent = 'Path ' + (i+1) + ' (' + p.steps.length + ' steps)';\n pathSelect.appendChild(opt);\n });\n\n // Build flat node index for click-to-navigate\n var nodeIndex = {};\n function indexNodes(nodes) {\n if (!nodes) return;\n nodes.forEach(function(n) {\n if (n.id) nodeIndex[n.id] = n;\n // Recurse into known child arrays\n if (n.children) indexNodes(n.children);\n if (n.onTrue) indexNodes(n.onTrue);\n if (n.onFalse) indexNodes(n.onFalse);\n if (n.tryBody) indexNodes(n.tryBody);\n if (n.catchBody) indexNodes(n.catchBody);\n if (n.finallyBody) indexNodes(n.finallyBody);\n if (n.body) indexNodes(n.body);\n if (n.yields) n.yields.forEach(function(y) { if (y.effect) indexNodes([y.effect]); });\n if (n.source && n.source.id) indexNodes([n.source]);\n if (n.handler && n.handler.id) indexNodes([n.handler]);\n if (n.operations) indexNodes(n.operations);\n if (n.cases) n.cases.forEach(function(c) { if (c.body) indexNodes(c.body); });\n });\n }\n indexNodes(IR_DATA.root.children);\n\n // Type filter populate\n var types = new Set();\n function collectTypes(nodes) {\n if (!nodes) return;\n nodes.forEach(function(n) {\n types.add(n.type);\n if (n.children) collectTypes(n.children);\n if (n.onTrue) collectTypes(n.onTrue);\n if (n.onFalse) collectTypes(n.onFalse);\n if (n.body) collectTypes(n.body);\n if (n.tryBody) collectTypes(n.tryBody);\n if (n.catchBody) collectTypes(n.catchBody);\n });\n }\n collectTypes(IR_DATA.root.children);\n var tf = document.getElementById('typeFilter');\n Array.from(types).sort().forEach(function(t) {\n var opt = document.createElement('option');\n opt.value = t; opt.textContent = t;\n tf.appendChild(opt);\n });\n\n // Tab switching\n function showTab(name) {\n document.querySelectorAll('.tab-content').forEach(function(el) { el.hidden = true; });\n document.querySelectorAll('.sidebar-tabs button').forEach(function(el) { el.classList.remove('active'); });\n document.getElementById('tab-' + name).hidden = false;\n event.target.classList.add('active');\n }\n\n // Search\n function handleSearch(q) {\n // Simple text highlight in IR tab\n var pre = document.getElementById('ir-json');\n if (!q) { pre.innerHTML = JSON.stringify(IR_DATA, null, 2); return; }\n var text = JSON.stringify(IR_DATA, null, 2);\n var escaped = q.replace(/[.*+?^$` + `{}()|\\\\[\\\\]\\\\\\\\]/g, '\\\\\\\\$` + `&');\n pre.innerHTML = text.replace(new RegExp(escaped, 'gi'), '<mark>$` + `&</mark>');\n }\n\n function handleTypeFilter(type) {\n // Scroll IR to first occurrence of selected type\n if (!type) return;\n var pre = document.getElementById('ir-json');\n var text = pre.textContent;\n var idx = text.indexOf('\"type\": \"' + type + '\"');\n if (idx >= 0) {\n showTab('ir');\n document.querySelectorAll('.sidebar-tabs button').forEach(function(b) {\n b.classList.toggle('active', b.textContent === 'IR');\n });\n }\n }\n\n // Overlay toggles\n function toggleOverlay(kind) {\n var el = document.getElementById('mermaid-diagram');\n var dataOn = document.getElementById('toggleDataFlow').checked;\n var errorOn = document.getElementById('toggleErrorFlow').checked;\n var src = DIAGRAMS.base;\n if (dataOn) src = DIAGRAMS.dataFlow;\n if (errorOn) src = DIAGRAMS.errorFlow;\n if (dataOn && errorOn) src = DIAGRAMS.dataFlow; // data takes precedence\n el.innerHTML = src;\n el.removeAttribute('data-processed');\n mermaid.init(undefined, el);\n var curTheme = document.documentElement.getAttribute('data-theme') || 'midnight';\n setTimeout(function() { rethemeSvgNodes(curTheme); }, 500);\n }\n\n // Path selection\n function selectPath(idx) {\n idx = parseInt(idx);\n document.querySelectorAll('.path-item').forEach(function(el, i) {\n el.classList.toggle('selected', i === idx);\n });\n }\n\n // Click-to-navigate: show node details when clicking on diagram nodes\n function showNodeDetails(nodeId) {\n var node = nodeIndex[nodeId];\n if (!node) return;\n var det = document.getElementById('node-details');\n var loc = node.location ? node.location.filePath + ':' + node.location.line + ':' + node.location.column : 'N/A';\n var html = '<h3>Node Details</h3>';\n html += '<table>';\n html += '<tr><td>ID</td><td><code>' + node.id + '</code></td></tr>';\n html += '<tr><td>Type</td><td><b>' + node.type + '</b></td></tr>';\n if (node.callee) html += '<tr><td>Callee</td><td>' + node.callee + '</td></tr>';\n if (node.displayName) html += '<tr><td>Display</td><td>' + node.displayName + '</td></tr>';\n if (node.semanticRole) html += '<tr><td>Role</td><td>' + node.semanticRole + '</td></tr>';\n html += '<tr><td>Location</td><td><code>' + loc + '</code></td></tr>';\n if (node.typeSignature) {\n var sig = node.typeSignature;\n html += '<tr><td>Type Sig</td><td><code>Effect&lt;' + (sig.successType||'?') + ', ' + (sig.errorType||'?') + ', ' + (sig.requirementsType||'?') + '&gt;</code></td></tr>';\n }\n html += '</table>';\n if (node.description) html += '<p style=\"margin-top:0.5rem;opacity:0.8\">' + node.description + '</p>';\n det.innerHTML = html;\n // Switch to details tab\n document.querySelectorAll('.tab-content').forEach(function(el) { el.hidden = true; });\n document.querySelectorAll('.sidebar-tabs button').forEach(function(b) { b.classList.remove('active'); });\n document.getElementById('tab-details').hidden = false;\n document.querySelectorAll('.sidebar-tabs button')[0].classList.add('active');\n }\n\n // Register Mermaid click callbacks and apply theme to SVG after rendering\n document.addEventListener('DOMContentLoaded', function() {\n setTimeout(function() {\n rethemeSvgNodes(document.documentElement.getAttribute('data-theme') || 'midnight');\n var svgNodes = document.querySelectorAll('.mermaid svg .node');\n svgNodes.forEach(function(el) {\n el.style.cursor = 'pointer';\n el.addEventListener('click', function() {\n var id = el.id || '';\n // Mermaid node IDs often have prefixes; try to match against nodeIndex\n for (var key in nodeIndex) {\n if (id.indexOf(key) >= 0 || id.indexOf(key.replace(/[^a-zA-Z0-9]/g, '_')) >= 0) {\n showNodeDetails(key);\n return;\n }\n }\n });\n });\n }, 1000);\n });\n </scr` + `ipt>\n</body>\n</html>`;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n","/**\n * Documentation Generation for Effect IR\n *\n * Generates comprehensive markdown documentation from analyzed Effect programs:\n * workflow steps, service dependencies, complexity metrics, and embedded diagrams.\n */\n\nimport type { StaticEffectIR, StaticFlowNode } from '../types';\nimport { getStaticChildren } from '../types';\nimport { Option } from 'effect';\nimport { calculateComplexity } from '../complexity';\nimport { renderStaticMermaid } from './mermaid';\nimport { analyzeErrorFlow } from '../error-flow';\nimport { buildDataFlowGraph } from '../data-flow';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface DocSection {\n title: string;\n content: string;\n}\n\nexport interface DocumentationOptions {\n /** Include Mermaid diagram in documentation */\n includeDiagram?: boolean | undefined;\n /** Include complexity metrics */\n includeComplexity?: boolean | undefined;\n /** Include service dependency table */\n includeServiceDeps?: boolean | undefined;\n /** Include error type documentation */\n includeErrors?: boolean | undefined;\n /** Include data flow information */\n includeDataFlow?: boolean | undefined;\n}\n\nconst DEFAULT_DOC_OPTIONS: Required<DocumentationOptions> = {\n includeDiagram: true,\n includeComplexity: true,\n includeServiceDeps: true,\n includeErrors: true,\n includeDataFlow: true,\n};\n\n// =============================================================================\n// Step Collection\n// =============================================================================\n\ninterface WorkflowStep {\n name: string;\n type: string;\n description: string;\n depth: number;\n}\n\nfunction collectWorkflowSteps(\n nodes: readonly StaticFlowNode[],\n steps: WorkflowStep[],\n depth: number,\n): void {\n for (const node of nodes) {\n const step = describeNode(node, depth);\n if (step) steps.push(step);\n\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n collectWorkflowSteps(children, steps, depth + 1);\n }\n }\n}\n\nfunction describeNode(node: StaticFlowNode, depth: number): WorkflowStep | null {\n switch (node.type) {\n case 'effect':\n return {\n name: node.callee || 'Effect',\n type: 'effect',\n description: node.displayName ?? node.callee,\n depth,\n };\n case 'error-handler':\n return {\n name: node.handlerType,\n type: 'error-handler',\n description: `Error handler: ${node.handlerType}${node.errorTag ? ` (catches ${node.errorTag})` : ''}`,\n depth,\n };\n case 'parallel':\n return {\n name: node.callee || 'parallel',\n type: 'parallel',\n description: `Parallel execution of ${node.children.length} effects`,\n depth,\n };\n case 'race':\n return {\n name: node.callee || 'race',\n type: 'race',\n description: `Race between ${node.children.length} effects`,\n depth,\n };\n case 'retry':\n return {\n name: 'Retry',\n type: 'retry',\n description: `Retry${node.schedule ? ` with schedule: ${node.schedule}` : ''}`,\n depth,\n };\n case 'timeout':\n return {\n name: 'Timeout',\n type: 'timeout',\n description: `Timeout${node.duration ? ` after ${node.duration}` : ''}`,\n depth,\n };\n case 'resource':\n return {\n name: 'Resource',\n type: 'resource',\n description: 'Acquire/Release resource lifecycle',\n depth,\n };\n case 'conditional':\n return {\n name: node.conditionalType,\n type: 'conditional',\n description: `Conditional: ${node.condition}`,\n depth,\n };\n case 'decision':\n return {\n name: node.label || 'decision',\n type: 'decision',\n description: `Decision: ${node.label || node.condition}`,\n depth,\n };\n case 'loop':\n return {\n name: node.loopType,\n type: 'loop',\n description: `Loop: ${node.loopType}${node.iterSource ? ` over ${node.iterSource}` : ''}`,\n depth,\n };\n case 'layer':\n return {\n name: 'Layer',\n type: 'layer',\n description: `Layer${node.provides?.length ? ` providing: ${node.provides.join(', ')}` : ''}`,\n depth,\n };\n case 'stream':\n return {\n name: 'Stream',\n type: 'stream',\n description: `Stream pipeline${node.pipeline.length > 0 ? `: ${node.pipeline.map(p => p.operation).join(' → ')}` : ''}`,\n depth,\n };\n case 'fiber':\n return {\n name: node.operation,\n type: 'fiber',\n description: `Fiber: ${node.operation}${node.isDaemon ? ' (daemon)' : ''}${node.isScoped ? ' (scoped)' : ''}`,\n depth,\n };\n default:\n return null;\n }\n}\n\n// =============================================================================\n// Rendering\n// =============================================================================\n\n/**\n * Generate comprehensive markdown documentation from an analyzed Effect IR.\n */\nexport function renderDocumentation(\n ir: StaticEffectIR,\n options?: Partial<DocumentationOptions>,\n): string {\n const opts = { ...DEFAULT_DOC_OPTIONS, ...options };\n const sections: string[] = [];\n\n // Title\n sections.push(`# ${ir.root.programName}`);\n sections.push('');\n\n // Description\n if (ir.root.jsdocDescription) {\n sections.push(ir.root.jsdocDescription);\n sections.push('');\n }\n\n // Overview\n sections.push('## Overview');\n sections.push('');\n sections.push(`- **Source**: \\`${ir.metadata.filePath}\\``);\n sections.push(`- **Entry**: ${ir.root.source}`);\n if (ir.root.typeSignature) {\n const sig = ir.root.typeSignature;\n sections.push(`- **Type**: \\`Effect<${sig.successType}, ${sig.errorType}, ${sig.requirementsType}>\\``);\n }\n sections.push('');\n\n // Workflow Steps\n const steps: WorkflowStep[] = [];\n collectWorkflowSteps(ir.root.children, steps, 0);\n if (steps.length > 0) {\n sections.push('## Workflow Steps');\n sections.push('');\n for (const step of steps) {\n const indent = ' '.repeat(step.depth);\n sections.push(`${indent}- **${step.name}** _(${step.type})_: ${step.description}`);\n }\n sections.push('');\n }\n\n // Service Dependencies\n if (opts.includeServiceDeps && ir.root.dependencies.length > 0) {\n sections.push('## Service Dependencies');\n sections.push('');\n sections.push('| Service | Type | Layer |');\n sections.push('|---------|------|-------|');\n for (const dep of ir.root.dependencies) {\n sections.push(`| ${dep.name} | ${dep.typeSignature ?? '-'} | ${dep.isLayer ? 'Yes' : 'No'} |`);\n }\n sections.push('');\n }\n\n // Error Types\n if (opts.includeErrors) {\n const errorFlow = analyzeErrorFlow(ir);\n if (errorFlow.allErrors.length > 0) {\n sections.push('## Error Types');\n sections.push('');\n for (const error of errorFlow.allErrors) {\n const producers = errorFlow.errorToSteps.get(error) ?? [];\n sections.push(`- **${error}**: produced by ${producers.length} step(s)`);\n }\n sections.push('');\n }\n }\n\n // Complexity\n if (opts.includeComplexity) {\n const complexity = calculateComplexity(ir);\n sections.push('## Complexity Metrics');\n sections.push('');\n sections.push(`| Metric | Value |`);\n sections.push(`|--------|-------|`);\n sections.push(`| Cyclomatic Complexity | ${complexity.cyclomaticComplexity} |`);\n sections.push(`| Cognitive Complexity | ${complexity.cognitiveComplexity} |`);\n sections.push(`| Max Depth | ${complexity.maxDepth} |`);\n sections.push(`| Decision Points | ${complexity.decisionPoints} |`);\n sections.push(`| Max Parallel Breadth | ${complexity.maxParallelBreadth} |`);\n sections.push('');\n }\n\n // Data Flow\n if (opts.includeDataFlow) {\n const dataFlow = buildDataFlowGraph(ir);\n if (dataFlow.undefinedReads.length > 0 || dataFlow.duplicateWrites.length > 0) {\n sections.push('## Data Flow Warnings');\n sections.push('');\n for (const read of dataFlow.undefinedReads) {\n sections.push(`- **Undefined read**: \\`${read.key}\\` read by ${read.readerName ?? read.readerId}`);\n }\n for (const dup of dataFlow.duplicateWrites) {\n sections.push(`- **Duplicate write**: \\`${dup.key}\\` written by ${dup.writerIds.join(', ')}`);\n }\n sections.push('');\n }\n }\n\n // Diagram\n if (opts.includeDiagram) {\n sections.push('## Flow Diagram');\n sections.push('');\n sections.push('```mermaid');\n sections.push(renderStaticMermaid(ir));\n sections.push('```');\n sections.push('');\n }\n\n return sections.join('\\n');\n}\n\n/**\n * Generate documentation for multiple programs.\n */\nexport function renderMultiProgramDocs(\n irs: readonly StaticEffectIR[],\n options?: Partial<DocumentationOptions>,\n): string {\n const sections: string[] = [];\n\n sections.push('# Effect Program Documentation');\n sections.push('');\n sections.push(`Generated: ${new Date().toISOString()}`);\n sections.push('');\n\n // Table of contents\n sections.push('## Programs');\n sections.push('');\n for (const ir of irs) {\n sections.push(`- [${ir.root.programName}](#${ir.root.programName.toLowerCase().replace(/[^a-z0-9]/g, '-')})`);\n }\n sections.push('');\n\n // Each program\n for (const ir of irs) {\n sections.push('---');\n sections.push('');\n sections.push(renderDocumentation(ir, options));\n sections.push('');\n }\n\n return sections.join('\\n');\n}\n","/**\n * Showcase Output Generator\n *\n * Produces rich per-step detail from the Effect IR, matching the structure\n * of awaitly-analyze's analyzer-showcase.data.json format.\n */\n\nimport type {\n StaticEffectIR,\n StaticFlowNode,\n EffectTypeSignature,\n ShowcaseStepDetail,\n ShowcaseEntry,\n} from '../types';\nimport { getStaticChildren } from '../types';\nimport { splitTopLevelUnion } from '../type-extractor';\nimport { Option } from 'effect';\nimport { renderStaticMermaid } from './mermaid';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ShowcaseOptions {\n /** Mermaid diagram direction */\n readonly direction?: 'TB' | 'LR' | 'BT' | 'RL' | undefined;\n}\n\ninterface WalkContext {\n readonly inLoop?: boolean | undefined;\n readonly loopType?: string | undefined;\n readonly iterationSource?: string | undefined;\n readonly inRetry?: { readonly attempts: number | 'unlimited'; readonly backoff: string } | undefined;\n readonly inTimeout?: { readonly ms: string } | undefined;\n}\n\n// =============================================================================\n// Type Helpers\n// =============================================================================\n\nfunction resolveTypeConfidence(\n sig: EffectTypeSignature | undefined,\n): 'declared' | 'inferred' | 'unknown' {\n if (!sig) return 'unknown';\n return sig.typeConfidence;\n}\n\nfunction formatErrorTypeDisplay(errorType: string): string {\n if (!errorType || errorType === 'never') return 'never';\n return errorType;\n}\n\nfunction parseErrorTags(errorType: string): readonly string[] {\n if (!errorType || errorType === 'never') return [];\n return splitTopLevelUnion(errorType)\n .filter((s) => s !== 'never');\n}\n\nfunction describeFlowNode(node: StaticFlowNode): string {\n switch (node.type) {\n case 'effect':\n return node.displayName ?? node.callee;\n case 'generator':\n return node.name ?? 'generator';\n case 'pipe':\n return node.name ?? 'pipe';\n default:\n return node.name ?? node.type;\n }\n}\n\n// =============================================================================\n// Step Collection\n// =============================================================================\n\nfunction collectStepDetails(\n nodes: readonly StaticFlowNode[],\n result: ShowcaseStepDetail[],\n ctx: WalkContext,\n): void {\n for (const node of nodes) {\n const detail = nodeToStepDetail(node, ctx);\n if (detail) result.push(detail);\n\n // Build updated context for children\n let childCtx = ctx;\n\n if (node.type === 'loop') {\n childCtx = {\n ...childCtx,\n inLoop: true,\n loopType: node.loopType,\n iterationSource: node.iterSource,\n };\n // Descend into loop body\n collectStepDetails([node.body], result, childCtx);\n continue;\n }\n\n if (node.type === 'retry') {\n const retryInfo = node.scheduleInfo\n ? {\n attempts: node.scheduleInfo.maxRetries ?? 'unlimited' as const,\n backoff: node.scheduleInfo.baseStrategy,\n }\n : { attempts: 'unlimited' as const, backoff: node.schedule ?? 'unknown' };\n childCtx = { ...childCtx, inRetry: retryInfo };\n // Descend into retry source\n collectStepDetails([node.source], result, childCtx);\n continue;\n }\n\n if (node.type === 'timeout') {\n childCtx = {\n ...childCtx,\n inTimeout: { ms: node.duration ?? 'unknown' },\n };\n collectStepDetails([node.source], result, childCtx);\n continue;\n }\n\n if (node.type === 'resource') {\n // Resource node produces its own detail; descend into use if present\n if (node.use) {\n collectStepDetails([node.use], result, ctx);\n }\n continue;\n }\n\n if (node.type === 'error-handler') {\n // Descend into source and handler\n collectStepDetails([node.source], result, ctx);\n if (node.handler) {\n collectStepDetails([node.handler], result, ctx);\n }\n continue;\n }\n\n if (node.type === 'generator') {\n // Generator is transparent — iterate through yields\n const yieldEffects = node.yields.map((y) => y.effect);\n collectStepDetails(yieldEffects, result, childCtx);\n continue;\n }\n\n // Generic descent into children\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n collectStepDetails(children, result, childCtx);\n }\n }\n}\n\nfunction nodeToStepDetail(\n node: StaticFlowNode,\n ctx: WalkContext,\n): ShowcaseStepDetail | null {\n switch (node.type) {\n case 'effect': {\n const sig = node.typeSignature;\n const outputType = sig?.successType ?? 'unknown';\n const errorType = sig?.errorType ?? 'never';\n return {\n stepId: node.id,\n name: node.displayName ?? node.callee,\n callee: node.callee,\n outputType,\n outputTypeKind: resolveTypeConfidence(sig),\n outputTypeDisplay: outputType,\n outputTypeText: sig ? `Effect<${sig.successType}, ${sig.errorType}, ${sig.requirementsType}>` : `Effect<${outputType}>`,\n errorTypeDisplay: formatErrorTypeDisplay(errorType),\n errors: parseErrorTags(errorType),\n depSource: node.serviceCall?.serviceType,\n stepKind: 'effect',\n // Propagate context\n ...(ctx.inRetry ? { retry: ctx.inRetry } : {}),\n ...(ctx.inTimeout ? { timeout: ctx.inTimeout } : {}),\n ...(ctx.inLoop\n ? {\n repeats: 'loop' as const,\n loopType: ctx.loopType,\n iterationSource: ctx.iterationSource,\n }\n : {}),\n };\n }\n\n case 'retry': {\n const retryInfo = node.scheduleInfo\n ? {\n attempts: node.scheduleInfo.maxRetries ?? ('unlimited' as const),\n backoff: node.scheduleInfo.baseStrategy,\n }\n : {\n attempts: 'unlimited' as const,\n backoff: node.schedule ?? 'unknown',\n };\n return {\n stepId: node.id,\n name: node.name ?? 'Retry',\n callee: 'Effect.retry',\n outputType: 'void',\n outputTypeKind: 'unknown',\n outputTypeDisplay: 'void',\n outputTypeText: 'retry wrapper',\n errorTypeDisplay: 'never',\n errors: [],\n stepKind: 'retry',\n retry: retryInfo,\n };\n }\n\n case 'timeout': {\n return {\n stepId: node.id,\n name: node.name ?? 'Timeout',\n callee: 'Effect.timeout',\n outputType: 'void',\n outputTypeKind: 'unknown',\n outputTypeDisplay: 'void',\n outputTypeText: 'timeout wrapper',\n errorTypeDisplay: 'TimeoutException',\n errors: ['TimeoutException'],\n stepKind: 'timeout',\n timeout: { ms: node.duration ?? 'unknown' },\n };\n }\n\n case 'resource': {\n return {\n stepId: node.id,\n name: node.name ?? 'Resource',\n callee: 'Effect.acquireRelease',\n outputType: 'void',\n outputTypeKind: 'unknown',\n outputTypeDisplay: 'void',\n outputTypeText: 'resource lifecycle',\n errorTypeDisplay: 'never',\n errors: [],\n stepKind: 'resource',\n kind: 'resource',\n acquire: describeFlowNode(node.acquire),\n use: node.use ? describeFlowNode(node.use) : undefined,\n release: describeFlowNode(node.release),\n };\n }\n\n case 'error-handler': {\n if (node.handlerType === 'catchTag' || node.handlerType === 'catchTags') {\n const errors = node.errorTags\n ? [...node.errorTags]\n : node.errorTag\n ? [node.errorTag]\n : [];\n return {\n stepId: node.id,\n name: node.name ?? node.handlerType,\n callee: `Effect.${node.handlerType}`,\n outputType: 'void',\n outputTypeKind: 'unknown',\n outputTypeDisplay: 'void',\n outputTypeText: `error handler (${node.handlerType})`,\n errorTypeDisplay: errors.join(' | ') || 'unknown',\n errors,\n stepKind: 'error-handler',\n };\n }\n return null;\n }\n\n default:\n return null;\n }\n}\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Generate a showcase entry from an analyzed Effect IR.\n */\nexport function generateShowcase(\n ir: StaticEffectIR,\n options?: ShowcaseOptions,\n sourceCode?: string,\n): ShowcaseEntry {\n const mermaid = renderStaticMermaid(ir, {\n direction: options?.direction ?? 'TB',\n });\n\n const stepDetails: ShowcaseStepDetail[] = [];\n collectStepDetails(ir.root.children, stepDetails, {});\n\n return {\n title: ir.root.programName,\n code: sourceCode ?? '',\n mermaid,\n stepDetails,\n };\n}\n\n/**\n * Generate showcase entries for multiple programs.\n */\nexport function generateMultipleShowcase(\n irs: readonly StaticEffectIR[],\n options?: ShowcaseOptions,\n sourceCode?: string,\n): ShowcaseEntry[] {\n return irs.map((ir) => generateShowcase(ir, options, sourceCode));\n}\n","/**\n * Cross-Program Composition Resolver for Effect IR\n *\n * Builds a graph of Effect programs that reference other programs\n * (e.g. via identifier effects that match another program name).\n */\n\nimport type { StaticEffectIR, StaticFlowNode, ProjectServiceMap } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\nimport { calculateComplexity } from './complexity';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ProgramGraphNode {\n name: string;\n filePath: string;\n ir: StaticEffectIR;\n calls: ProgramCallEdge[];\n calledBy: string[];\n}\n\nexport interface ProgramCallEdge {\n targetProgram: string;\n callSite?: { line: number; column: number };\n resolved: boolean;\n}\n\nexport interface ProgramGraph {\n programs: Map<string, ProgramGraphNode>;\n entryProgram: string;\n circularDependencies: string[][];\n unresolvedReferences: UnresolvedProgramRef[];\n}\n\nexport interface UnresolvedProgramRef {\n programName: string;\n referencedFrom: string;\n reason: string;\n}\n\nexport interface CompositionResolverOptions {\n /** Entry program name when building from multiple IRs */\n entryProgramName?: string | undefined;\n}\n\n// =============================================================================\n// Finding program references in IR (identifier effect nodes + yield* calls)\n// =============================================================================\n\nexport interface YieldStarCall {\n callee: string;\n location?: { line: number; column: number } | undefined;\n isYieldStar: boolean;\n}\n\nfunction collectEffectCallees(\n nodes: readonly StaticFlowNode[],\n result: { callee: string; location?: { line: number; column: number } }[],\n): void {\n for (const node of nodes) {\n if (node.type === 'effect') {\n const eff = node;\n const callee = eff.callee.trim();\n if (callee && !callee.startsWith('Effect.') && !callee.includes('.')) {\n const location = eff.location\n ? { line: eff.location.line, column: eff.location.column }\n : undefined;\n if (location) {\n result.push({ callee, location });\n } else {\n result.push({ callee });\n }\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n collectEffectCallees(children, result);\n }\n }\n}\n\n/**\n * Collect yield* references from generator nodes.\n * These represent cross-generator composition (yield* otherGenerator()).\n */\nfunction collectYieldStarCalls(\n nodes: readonly StaticFlowNode[],\n result: YieldStarCall[],\n): void {\n for (const node of nodes) {\n if (node.type === 'generator') {\n for (const y of node.yields) {\n if (y.effect.type === 'effect') {\n const callee = y.effect.callee.trim();\n // Ignore Effect.* calls — we want generator-to-generator calls\n if (callee && !callee.startsWith('Effect.') && !callee.includes('.')) {\n const location = y.effect.location\n ? { line: y.effect.location.line, column: y.effect.location.column }\n : undefined;\n result.push({ callee, isYieldStar: true, location });\n }\n }\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n collectYieldStarCalls(children, result);\n }\n }\n}\n\n// =============================================================================\n// Build Graph from multiple IRs\n// =============================================================================\n\n/**\n * Build a program composition graph from a list of analyzed IRs (e.g. from one file).\n */\nexport function analyzeProgramGraph(\n irs: readonly StaticEffectIR[],\n filePath: string,\n options: CompositionResolverOptions = {},\n): ProgramGraph {\n const programNames = new Set(irs.map((ir) => ir.root.programName));\n const firstIr = irs.length > 0 ? irs[0] : undefined;\n const entryProgram =\n options.entryProgramName ?? (firstIr ? firstIr.root.programName : '');\n\n const graph: ProgramGraph = {\n programs: new Map(),\n entryProgram,\n circularDependencies: [],\n unresolvedReferences: [],\n };\n\n for (const ir of irs) {\n const name = ir.root.programName;\n const refs: { callee: string; location?: { line: number; column: number } }[] = [];\n collectEffectCallees(ir.root.children, refs);\n\n const calls: ProgramCallEdge[] = refs\n .filter((r) => programNames.has(r.callee) && r.callee !== name)\n .map((r) =>\n r.location\n ? { targetProgram: r.callee, callSite: r.location, resolved: true }\n : { targetProgram: r.callee, resolved: true },\n );\n\n for (const r of refs) {\n if (programNames.has(r.callee) && r.callee !== name) continue;\n if (r.callee.startsWith('Effect.') || r.callee.includes('.')) continue;\n graph.unresolvedReferences.push({\n programName: r.callee,\n referencedFrom: name,\n reason: 'Program not found in graph',\n });\n }\n\n const calledBy: string[] = [];\n for (const other of irs) {\n if (other.root.programName === name) continue;\n const otherRefs: { callee: string }[] = [];\n collectEffectCallees(other.root.children, otherRefs);\n if (otherRefs.some((r) => r.callee === name)) {\n calledBy.push(other.root.programName);\n }\n }\n\n graph.programs.set(name, {\n name,\n filePath,\n ir,\n calls,\n calledBy,\n });\n }\n\n // Detect cycles\n const stack: string[] = [];\n const visited = new Set<string>();\n function dfs(programName: string): void {\n if (stack.includes(programName)) {\n const start = stack.indexOf(programName);\n graph.circularDependencies.push([...stack.slice(start), programName]);\n return;\n }\n if (visited.has(programName)) return;\n visited.add(programName);\n stack.push(programName);\n const node = graph.programs.get(programName);\n if (node) {\n for (const call of node.calls) {\n if (call.resolved) dfs(call.targetProgram);\n }\n }\n stack.pop();\n }\n for (const name of graph.programs.keys()) {\n dfs(name);\n }\n\n return graph;\n}\n\n// =============================================================================\n// Graph Utilities\n// =============================================================================\n\nexport function getTopologicalOrder(graph: ProgramGraph): string[] {\n const result: string[] = [];\n const visited = new Set<string>();\n const temp = new Set<string>();\n\n function visit(name: string): void {\n if (visited.has(name)) return;\n if (temp.has(name)) return;\n temp.add(name);\n const node = graph.programs.get(name);\n if (node) {\n for (const call of node.calls) {\n if (call.resolved) visit(call.targetProgram);\n }\n }\n temp.delete(name);\n visited.add(name);\n result.push(name);\n }\n\n for (const name of graph.programs.keys()) {\n visit(name);\n }\n return result;\n}\n\nexport function getDependencies(\n graph: ProgramGraph,\n programName: string,\n): string[] {\n const deps = new Set<string>();\n const visited = new Set<string>();\n\n function collect(name: string): void {\n if (visited.has(name)) return;\n visited.add(name);\n const node = graph.programs.get(name);\n if (node) {\n for (const call of node.calls) {\n if (call.resolved) {\n deps.add(call.targetProgram);\n collect(call.targetProgram);\n }\n }\n }\n }\n collect(programName);\n return Array.from(deps);\n}\n\nexport function getDependents(\n graph: ProgramGraph,\n programName: string,\n): string[] {\n const dependents = new Set<string>();\n const visited = new Set<string>();\n\n function collect(name: string): void {\n if (visited.has(name)) return;\n visited.add(name);\n const node = graph.programs.get(name);\n if (node) {\n for (const caller of node.calledBy) {\n dependents.add(caller);\n collect(caller);\n }\n }\n }\n collect(programName);\n return Array.from(dependents);\n}\n\nexport function calculateGraphComplexity(\n graph: ProgramGraph,\n): {\n totalCyclomaticComplexity: number;\n totalPrograms: number;\n maxDepth: number;\n hasCircularDependencies: boolean;\n} {\n let totalCC = 0;\n let maxDepth = 0;\n\n for (const node of graph.programs.values()) {\n totalCC += calculateComplexity(node.ir).cyclomaticComplexity;\n }\n\n const order = getTopologicalOrder(graph);\n const depths = new Map<string, number>();\n\n for (const name of order) {\n const node = graph.programs.get(name);\n if (!node) continue;\n let depth = 0;\n for (const call of node.calls) {\n if (call.resolved) {\n depth = Math.max(\n depth,\n (depths.get(call.targetProgram) ?? 0) + 1,\n );\n }\n }\n depths.set(name, depth);\n maxDepth = Math.max(maxDepth, depth);\n }\n\n return {\n totalCyclomaticComplexity: totalCC,\n totalPrograms: graph.programs.size,\n maxDepth,\n hasCircularDependencies: graph.circularDependencies.length > 0,\n };\n}\n\nexport function renderGraphMermaid(graph: ProgramGraph): string {\n const lines: string[] = [];\n const sanitize = (s: string) => s.replace(/[^a-zA-Z0-9_]/g, '_');\n\n lines.push('flowchart TD');\n lines.push('');\n lines.push(' %% Program Composition Graph');\n lines.push('');\n\n for (const [name] of graph.programs) {\n const isEntry = name === graph.entryProgram;\n const shape = isEntry\n ? `${sanitize(name)}[[\"${name}\"]]\\n`\n : ` ${sanitize(name)}[\"${name}\"]`;\n lines.push(shape.startsWith(' ') ? shape : ` ${shape}`);\n }\n lines.push('');\n\n for (const [, node] of graph.programs) {\n for (const call of node.calls) {\n if (call.resolved) {\n const label = call.callSite\n ? `L${call.callSite.line}`\n : '';\n if (label) {\n lines.push(\n ` ${sanitize(node.name)} -->|${label}| ${sanitize(call.targetProgram)}`,\n );\n } else {\n lines.push(\n ` ${sanitize(node.name)} --> ${sanitize(call.targetProgram)}`,\n );\n }\n }\n }\n }\n\n // Style entry point and circular deps\n lines.push('');\n lines.push(' classDef entryPoint fill:#C8E6C9,stroke:#2E7D32,stroke-width:3px');\n lines.push(` class ${sanitize(graph.entryProgram)} entryPoint`);\n\n if (graph.circularDependencies.length > 0) {\n lines.push(' classDef cyclic fill:#FFCDD2,stroke:#C62828,stroke-width:2px');\n const cyclicNodes = new Set<string>();\n for (const cycle of graph.circularDependencies) {\n for (const n of cycle) cyclicNodes.add(n);\n }\n for (const n of cyclicNodes) {\n lines.push(` class ${sanitize(n)} cyclic`);\n }\n }\n\n return lines.join('\\n');\n}\n\n/**\n * Render a composition Mermaid diagram showing generator call relationships\n * with subgraphs grouping by file and yield* edge labels.\n */\nexport function renderCompositionMermaid(graph: ProgramGraph): string {\n const lines: string[] = [];\n const sanitize = (s: string) => s.replace(/[^a-zA-Z0-9_]/g, '_');\n\n lines.push('flowchart TD');\n lines.push('');\n\n // Group programs by file\n const byFile = new Map<string, ProgramGraphNode[]>();\n for (const [, node] of graph.programs) {\n const list = byFile.get(node.filePath) ?? [];\n list.push(node);\n byFile.set(node.filePath, list);\n }\n\n // Render subgraphs per file\n let fileIdx = 0;\n for (const [filePath, nodes] of byFile) {\n const fileName = filePath.split('/').pop() ?? filePath;\n lines.push(` subgraph file${fileIdx}[\"${fileName}\"]`);\n for (const node of nodes) {\n const isEntry = node.name === graph.entryProgram;\n if (isEntry) {\n lines.push(` ${sanitize(node.name)}[[\"${node.name}\"]]`);\n } else {\n lines.push(` ${sanitize(node.name)}[\"${node.name}\"]`);\n }\n }\n lines.push(' end');\n lines.push('');\n fileIdx++;\n }\n\n // Edges\n for (const [, node] of graph.programs) {\n for (const call of node.calls) {\n if (call.resolved) {\n const label = call.callSite ? `yield* L${call.callSite.line}` : 'yield*';\n lines.push(` ${sanitize(node.name)} -->|${label}| ${sanitize(call.targetProgram)}`);\n }\n }\n }\n\n // Unresolved references\n if (graph.unresolvedReferences.length > 0) {\n lines.push('');\n lines.push(' %% Unresolved references');\n for (const ref of graph.unresolvedReferences) {\n const refId = `unresolved_${sanitize(ref.programName)}`;\n lines.push(` ${refId}[\"? ${ref.programName}\"]`);\n lines.push(` ${sanitize(ref.referencedFrom)} -.-> ${refId}`);\n }\n lines.push(' classDef unresolved fill:#FFF3CD,stroke:#856404,stroke-dasharray:5');\n for (const ref of graph.unresolvedReferences) {\n lines.push(` class unresolved_${sanitize(ref.programName)} unresolved`);\n }\n }\n\n return lines.join('\\n');\n}\n\n// =============================================================================\n// Cross-File Composition Analysis\n// =============================================================================\n\nexport interface ProjectCompositionOptions {\n /** Entry program name */\n entryProgramName?: string | undefined;\n}\n\n/**\n * Build a composition graph from a project-wide analysis result (multi-file).\n * Merges IRs across files into a unified program graph with cross-file edges.\n */\nexport function analyzeProjectComposition(\n byFile: ReadonlyMap<string, readonly StaticEffectIR[]>,\n options: ProjectCompositionOptions = {},\n serviceMap?: ProjectServiceMap,\n): ProgramGraph {\n // Collect all programs across all files\n const allProgramNames = new Set<string>();\n const programToFile = new Map<string, string>();\n const programToIR = new Map<string, StaticEffectIR>();\n\n for (const [filePath, irs] of byFile) {\n for (const ir of irs) {\n const name = ir.root.programName;\n allProgramNames.add(name);\n programToFile.set(name, filePath);\n programToIR.set(name, ir);\n }\n }\n\n const firstProgram = allProgramNames.values().next().value;\n const entryProgram = options.entryProgramName ?? firstProgram ?? '';\n\n const graph: ProgramGraph = {\n programs: new Map(),\n entryProgram,\n circularDependencies: [],\n unresolvedReferences: [],\n };\n\n // Build nodes with cross-file edge resolution\n for (const [name, ir] of programToIR) {\n const filePath = programToFile.get(name) ?? '';\n const refs: { callee: string; location?: { line: number; column: number } }[] = [];\n collectEffectCallees(ir.root.children, refs);\n\n // Also collect yield* calls from generators\n const yieldRefs: YieldStarCall[] = [];\n collectYieldStarCalls(ir.root.children, yieldRefs);\n for (const yr of yieldRefs) {\n if (!refs.some(r => r.callee === yr.callee)) {\n const entry: { callee: string; location?: { line: number; column: number } } = { callee: yr.callee };\n if (yr.location) entry.location = yr.location;\n refs.push(entry);\n }\n }\n\n const calls: ProgramCallEdge[] = refs\n .filter((r) => allProgramNames.has(r.callee) && r.callee !== name)\n .map((r) =>\n r.location\n ? { targetProgram: r.callee, callSite: r.location, resolved: true }\n : { targetProgram: r.callee, resolved: true },\n );\n\n // Track unresolved references (service refs are resolved if serviceMap is provided)\n const knownServiceIds = serviceMap ? new Set(serviceMap.services.keys()) : new Set<string>();\n for (const r of refs) {\n if (allProgramNames.has(r.callee) && r.callee !== name) continue;\n if (r.callee.startsWith('Effect.') || r.callee.includes('.')) continue;\n if (r.callee === name) continue;\n if (knownServiceIds.has(r.callee)) continue; // resolved as service reference\n graph.unresolvedReferences.push({\n programName: r.callee,\n referencedFrom: name,\n reason: 'Program not found in project',\n });\n }\n\n // Build calledBy from all other programs\n const calledBy: string[] = [];\n for (const [otherName, otherIR] of programToIR) {\n if (otherName === name) continue;\n const otherRefs: { callee: string }[] = [];\n collectEffectCallees(otherIR.root.children, otherRefs);\n const otherYields: YieldStarCall[] = [];\n collectYieldStarCalls(otherIR.root.children, otherYields);\n if (\n otherRefs.some((r) => r.callee === name) ||\n otherYields.some((y) => y.callee === name)\n ) {\n calledBy.push(otherName);\n }\n }\n\n graph.programs.set(name, {\n name,\n filePath,\n ir,\n calls,\n calledBy,\n });\n }\n\n // Detect cycles\n const stack: string[] = [];\n const visited = new Set<string>();\n function dfs(programName: string): void {\n if (stack.includes(programName)) {\n const start = stack.indexOf(programName);\n graph.circularDependencies.push([...stack.slice(start), programName]);\n return;\n }\n if (visited.has(programName)) return;\n visited.add(programName);\n stack.push(programName);\n const node = graph.programs.get(programName);\n if (node) {\n for (const call of node.calls) {\n if (call.resolved) dfs(call.targetProgram);\n }\n }\n stack.pop();\n }\n for (const name of graph.programs.keys()) {\n dfs(name);\n }\n\n return graph;\n}\n\n// =============================================================================\n// Service-Aware Composition Rendering\n// =============================================================================\n\n/**\n * Render a composition Mermaid diagram that includes service nodes from the service map.\n * Programs are rectangular, services are hexagonal.\n */\nexport function renderCompositionWithServicesMermaid(\n graph: ProgramGraph,\n projectServiceMap: ProjectServiceMap,\n): string {\n const compLines: string[] = [];\n const sanitize = (s: string) => s.replace(/[^a-zA-Z0-9_]/g, '_');\n\n compLines.push('flowchart TD');\n compLines.push('');\n\n // Program nodes\n compLines.push(' %% Programs');\n for (const [name] of graph.programs) {\n const isEntry = name === graph.entryProgram;\n if (isEntry) {\n compLines.push(` ${sanitize(name)}[[\"${name}\"]]`);\n } else {\n compLines.push(` ${sanitize(name)}[\"${name}\"]`);\n }\n }\n compLines.push('');\n\n // Service nodes (hexagon shape)\n compLines.push(' %% Services');\n for (const [serviceId] of projectServiceMap.services) {\n compLines.push(` svc_${sanitize(serviceId)}{{{\"${serviceId}\"}}}`);\n }\n compLines.push('');\n\n // Program-to-program edges\n compLines.push(' %% Program calls');\n for (const [, node] of graph.programs) {\n for (const call of node.calls) {\n if (call.resolved) {\n const label = call.callSite ? `yield* L${call.callSite.line}` : 'yield*';\n compLines.push(` ${sanitize(node.name)} -->|${label}| ${sanitize(call.targetProgram)}`);\n }\n }\n }\n compLines.push('');\n\n // Program-to-service edges (yield* ServiceTag)\n compLines.push(' %% Service dependencies');\n for (const [serviceId, artifact] of projectServiceMap.services) {\n for (const consumer of artifact.consumers) {\n if (graph.programs.has(consumer.programName)) {\n compLines.push(` ${sanitize(consumer.programName)} -.->|yield*| svc_${sanitize(serviceId)}`);\n }\n }\n }\n compLines.push('');\n\n // Service-to-service edges\n compLines.push(' %% Service layer dependencies');\n for (const [serviceId, artifact] of projectServiceMap.services) {\n for (const dep of artifact.dependencies) {\n if (projectServiceMap.services.has(dep)) {\n compLines.push(` svc_${sanitize(serviceId)} -.-> svc_${sanitize(dep)}`);\n }\n }\n }\n compLines.push('');\n\n // Styling\n compLines.push(' classDef entryPoint fill:#C8E6C9,stroke:#2E7D32,stroke-width:3px');\n compLines.push(' classDef service fill:#E3F2FD,stroke:#1565C0,stroke-width:2px');\n compLines.push(` class ${sanitize(graph.entryProgram)} entryPoint`);\n for (const serviceId of projectServiceMap.services.keys()) {\n compLines.push(` class svc_${sanitize(serviceId)} service`);\n }\n\n return compLines.join('\\n');\n}\n","/**\n * Ref / State Management Analysis (GAP 7)\n *\n * Detects Ref, FiberRef, SynchronizedRef usage and potential race conditions.\n */\n\nimport type { StaticEffectIR, StaticFlowNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface RefInfo {\n refId: string;\n operation: 'make' | 'get' | 'set' | 'update' | 'modify' | 'getAndSet' | 'getAndUpdate';\n nodeId: string;\n location?: { line: number; column: number };\n}\n\nexport interface RefMutation {\n refId: string;\n nodeId: string;\n operation: 'set' | 'update' | 'modify' | 'getAndSet' | 'getAndUpdate';\n}\n\nexport interface RaceCondition {\n refId: string;\n readerIds: string[];\n writerIds: string[];\n message: string;\n}\n\nexport interface StateFlowAnalysis {\n refs: RefInfo[];\n mutations: RefMutation[];\n potentialRaces: RaceCondition[];\n stateGraph: {\n refId: string;\n readers: string[];\n writers: string[];\n }[];\n}\n\n// =============================================================================\n// Detection\n// =============================================================================\n\nfunction isRefCallee(callee: string): boolean {\n return (\n callee.startsWith('Ref.') ||\n callee.startsWith('FiberRef.') ||\n callee.startsWith('SynchronizedRef.')\n );\n}\n\nfunction getRefOperation(callee: string): RefInfo['operation'] {\n if (callee.includes('getAndUpdate')) return 'getAndUpdate';\n if (callee.includes('getAndSet')) return 'getAndSet';\n if (callee.includes('modify')) return 'modify';\n if (callee.includes('update')) return 'update';\n if (callee.includes('.set')) return 'set';\n if (callee.includes('.get')) return 'get';\n if (callee.includes('make') || callee.includes('unsafeMake')) return 'make';\n return 'get';\n}\n\nfunction getRefId(callee: string): string {\n if (callee.startsWith('Ref.')) return 'Ref';\n if (callee.startsWith('FiberRef.')) return 'FiberRef';\n if (callee.startsWith('SynchronizedRef.')) return 'SynchronizedRef';\n return 'Ref';\n}\n\nconst WRITE_OPS = new Set<RefInfo['operation']>(['set', 'update', 'modify', 'getAndSet', 'getAndUpdate']);\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport function analyzeStateFlow(ir: StaticEffectIR): StateFlowAnalysis {\n const refs: RefInfo[] = [];\n const mutations: RefMutation[] = [];\n const readersByRef = new Map<string, string[]>();\n const writersByRef = new Map<string, string[]>();\n\n function visit(nodes: readonly StaticFlowNode[]) {\n for (const node of nodes) {\n if (node.type === 'effect') {\n const eff = node;\n const callee = eff.callee;\n if (isRefCallee(callee)) {\n const refId = getRefId(callee);\n const operation = getRefOperation(callee);\n const info: RefInfo = {\n refId,\n operation,\n nodeId: eff.id,\n };\n if (eff.location) info.location = { line: eff.location.line, column: eff.location.column };\n refs.push(info);\n if (WRITE_OPS.has(operation)) {\n mutations.push({\n refId,\n nodeId: eff.id,\n operation: operation as RefMutation['operation'],\n });\n const w = writersByRef.get(refId) ?? [];\n w.push(eff.id);\n writersByRef.set(refId, w);\n } else if (operation === 'get') {\n const r = readersByRef.get(refId) ?? [];\n r.push(eff.id);\n readersByRef.set(refId, r);\n }\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) visit(children);\n }\n }\n visit(ir.root.children);\n\n const stateGraph = Array.from(\n new Set([...readersByRef.keys(), ...writersByRef.keys()]),\n ).map((refId) => ({\n refId,\n readers: readersByRef.get(refId) ?? [],\n writers: writersByRef.get(refId) ?? [],\n }));\n\n const potentialRaces: RaceCondition[] = [];\n for (const { refId, readers, writers } of stateGraph) {\n if (readers.length > 0 && writers.length > 0) {\n potentialRaces.push({\n refId,\n readerIds: readers,\n writerIds: writers,\n message: `Ref \"${refId}\" has concurrent readers and writers - consider Ref.modify for atomic updates`,\n });\n }\n }\n\n return {\n refs,\n mutations,\n potentialRaces,\n stateGraph,\n };\n}\n","/**\n * Scope & Resource Lifecycle Analysis (GAP 10)\n *\n * Detects acquireRelease, Scope.*, Pool.*, Effect.scoped and tracks\n * resource ordering and potential leaks.\n */\n\nimport type { StaticEffectIR, StaticFlowNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ResourceAcquisition {\n nodeId: string;\n type: 'acquireRelease' | 'acquireUseRelease' | 'scoped' | 'pool' | 'keyedPool';\n acquireNodeId?: string;\n releaseNodeId?: string;\n location?: { line: number; column: number };\n}\n\nexport interface ScopeBoundary {\n nodeId: string;\n type: 'scoped' | 'scopeMake' | 'scopeUse' | 'scopeFork' | 'scopeAddFinalizer' | 'scopeExtend';\n location?: { line: number; column: number };\n}\n\nexport interface ScopeResourceAnalysis {\n acquisitions: ResourceAcquisition[];\n scopeBoundaries: ScopeBoundary[];\n poolCreations: string[];\n potentialLeaks: string[];\n}\n\n// =============================================================================\n// Detection\n// =============================================================================\n\nfunction _isResourceCallee(callee: string): boolean {\n return (\n callee.includes('acquireRelease') ||\n callee.includes('acquireUseRelease') ||\n callee.includes('Effect.scoped') ||\n callee.startsWith('Scope.') ||\n callee.startsWith('Pool.') ||\n callee.startsWith('KeyedPool.')\n );\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport function analyzeScopeResource(ir: StaticEffectIR): ScopeResourceAnalysis {\n const acquisitions: ResourceAcquisition[] = [];\n const scopeBoundaries: ScopeBoundary[] = [];\n const poolCreations: string[] = [];\n const potentialLeaks: string[] = [];\n\n function visit(nodes: readonly StaticFlowNode[]) {\n for (const node of nodes) {\n if (node.type === 'effect') {\n const eff = node;\n const callee = eff.callee;\n if (callee.includes('acquireRelease') || callee.includes('acquireUseRelease')) {\n const acq: ResourceAcquisition = {\n nodeId: eff.id,\n type: callee.includes('acquireUseRelease') ? 'acquireUseRelease' : 'acquireRelease',\n };\n if (eff.location) acq.location = { line: eff.location.line, column: eff.location.column };\n acquisitions.push(acq);\n } else if (callee.includes('Effect.scoped')) {\n const sb: ScopeBoundary = { nodeId: eff.id, type: 'scoped' };\n if (eff.location) sb.location = { line: eff.location.line, column: eff.location.column };\n scopeBoundaries.push(sb);\n } else if (callee.startsWith('Scope.')) {\n if (callee.includes('make')) {\n const sb: ScopeBoundary = { nodeId: eff.id, type: 'scopeMake' };\n if (eff.location) sb.location = { line: eff.location.line, column: eff.location.column };\n scopeBoundaries.push(sb);\n } else if (callee.includes('use')) {\n const sb: ScopeBoundary = { nodeId: eff.id, type: 'scopeUse' };\n if (eff.location) sb.location = { line: eff.location.line, column: eff.location.column };\n scopeBoundaries.push(sb);\n } else if (callee.includes('fork')) {\n const sb: ScopeBoundary = { nodeId: eff.id, type: 'scopeFork' };\n if (eff.location) sb.location = { line: eff.location.line, column: eff.location.column };\n scopeBoundaries.push(sb);\n } else if (callee.includes('addFinalizer')) {\n const sb: ScopeBoundary = { nodeId: eff.id, type: 'scopeAddFinalizer' };\n if (eff.location) sb.location = { line: eff.location.line, column: eff.location.column };\n scopeBoundaries.push(sb);\n } else if (callee.includes('extend')) {\n const sb: ScopeBoundary = { nodeId: eff.id, type: 'scopeExtend' };\n if (eff.location) sb.location = { line: eff.location.line, column: eff.location.column };\n scopeBoundaries.push(sb);\n }\n } else if (callee.startsWith('Pool.') || callee.startsWith('KeyedPool.')) {\n poolCreations.push(eff.id);\n }\n } else if (node.type === 'resource') {\n const res = node;\n const acq: ResourceAcquisition = {\n nodeId: node.id,\n type: 'acquireRelease',\n acquireNodeId: res.acquire.id,\n releaseNodeId: res.release.id,\n };\n if (node.location) acq.location = { line: node.location.line, column: node.location.column };\n acquisitions.push(acq);\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) visit(children);\n }\n }\n visit(ir.root.children);\n\n return {\n acquisitions,\n scopeBoundaries,\n poolCreations,\n potentialLeaks,\n };\n}\n","/**\n * Observability Analysis (GAP 11)\n *\n * Detects Effect.withSpan, Effect.log*, Metric.*, Logger usage.\n */\n\nimport type { StaticEffectIR, StaticFlowNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface SpanInfo {\n nodeId: string;\n name?: string;\n location?: { line: number; column: number };\n}\n\nexport interface LogPointInfo {\n nodeId: string;\n level: 'debug' | 'info' | 'warning' | 'error';\n location?: { line: number; column: number };\n}\n\nexport interface MetricInfo {\n nodeId: string;\n type: 'counter' | 'gauge' | 'histogram' | 'summary' | 'timer';\n /** Whether this metric uses Metric.tagged / taggedWithLabels */\n isTagged?: boolean;\n location?: { line: number; column: number };\n}\n\nexport interface ObservabilityAnalysis {\n spans: SpanInfo[];\n logPoints: LogPointInfo[];\n metrics: MetricInfo[];\n coverage: {\n effectCount: number;\n effectsWithSpans: number;\n effectsWithMetrics: number;\n errorHandlersWithLogging: number;\n errorHandlerCount: number;\n };\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nfunction isSpanCallee(callee: string): boolean {\n return (\n callee.includes('withSpan') ||\n callee.includes('Tracer.span') ||\n callee.includes('annotateCurrentSpan') ||\n callee.includes('annotateSpans') ||\n callee.includes('makeSpan') ||\n callee.includes('makeSpanScoped') ||\n callee.includes('useSpan') ||\n callee.includes('withParentSpan') ||\n callee.includes('linkSpans') ||\n callee.includes('linkSpanCurrent') ||\n callee.includes('functionWithSpan') ||\n callee.includes('currentSpan') ||\n callee.includes('currentParentSpan') ||\n callee.includes('withTracerEnabled') ||\n callee.includes('withTracerTiming') ||\n callee.includes('span(')\n );\n}\n\nfunction isLogCallee(callee: string): boolean {\n return (\n callee.includes('Effect.log') ||\n callee.includes('Logger.add') ||\n callee.includes('Logger.replace') ||\n callee.includes('Logger.batched') ||\n callee.includes('Logger.withLeveledConsole') ||\n callee.includes('Logger.json') ||\n callee.includes('Logger.logFmt') ||\n callee.includes('Logger.pretty') ||\n callee.includes('Logger.structured')\n );\n}\n\nfunction getLogLevel(callee: string): LogPointInfo['level'] {\n if (callee.includes('logDebug') || callee.includes('Debug')) return 'debug';\n if (callee.includes('logWarning') || callee.includes('Warning')) return 'warning';\n if (callee.includes('logError') || callee.includes('Error')) return 'error';\n return 'info';\n}\n\nfunction isMetricCallee(callee: string): boolean {\n return callee.startsWith('Metric.') || callee.includes('.track');\n}\n\nfunction getMetricType(callee: string): MetricInfo['type'] {\n if (callee.includes('counter') || callee.includes('increment')) return 'counter';\n if (callee.includes('frequency')) return 'counter';\n if (callee.includes('gauge') || callee.includes('.set')) return 'gauge';\n if (callee.includes('histogram')) return 'histogram';\n if (callee.includes('summary')) return 'summary';\n if (callee.includes('timer') || callee.includes('trackDuration')) return 'timer';\n // Metric combinators — type unknown, default to counter\n // tagged, taggedWithLabels, trackAll, trackDefect, withConstantInput, map, mapInput\n return 'counter';\n}\n\nexport function analyzeObservability(ir: StaticEffectIR): ObservabilityAnalysis {\n const spans: SpanInfo[] = [];\n const logPoints: LogPointInfo[] = [];\n const metrics: MetricInfo[] = [];\n let effectCount = 0;\n let effectsWithSpans = 0;\n let effectsWithMetrics = 0;\n let errorHandlersWithLogging = 0;\n let errorHandlerCount = 0;\n\n function visit(nodes: readonly StaticFlowNode[], underSpan: boolean, underMetric: boolean) {\n for (const node of nodes) {\n if (node.type === 'effect') {\n const eff = node;\n const callee = eff.callee ?? '';\n effectCount++;\n if (isSpanCallee(callee)) {\n const s: SpanInfo = { nodeId: eff.id };\n if (eff.location) s.location = { line: eff.location.line, column: eff.location.column };\n spans.push(s);\n }\n if (underSpan) effectsWithSpans++;\n if (isLogCallee(callee)) {\n const lp: LogPointInfo = { nodeId: eff.id, level: getLogLevel(callee) };\n if (eff.location) lp.location = { line: eff.location.line, column: eff.location.column };\n logPoints.push(lp);\n }\n if (isMetricCallee(callee)) {\n const isTagged = callee.includes('tagged') || callee.includes('taggedWith');\n const m: MetricInfo = {\n nodeId: eff.id,\n type: getMetricType(callee),\n ...(isTagged ? { isTagged: true } : {}),\n };\n if (eff.location) m.location = { line: eff.location.line, column: eff.location.column };\n metrics.push(m);\n }\n if (underMetric) effectsWithMetrics++;\n }\n if (node.type === 'error-handler') {\n errorHandlerCount++;\n const handler = node;\n if (handler.handler) {\n let hasLog = false;\n const checkLog = (n: StaticFlowNode) => {\n if (n.type === 'effect') {\n const c = (n).callee ?? '';\n if (isLogCallee(c)) hasLog = true;\n }\n const ch = Option.getOrElse(getStaticChildren(n), () => []);\n ch.forEach(checkLog);\n };\n checkLog(handler.handler);\n if (hasLog) errorHandlersWithLogging++;\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n const thisIsSpan = node.type === 'effect' && isSpanCallee((node).callee ?? '');\n const thisIsMetric = node.type === 'effect' && isMetricCallee((node).callee ?? '');\n const nextUnderSpan = underSpan || thisIsSpan;\n const nextUnderMetric = underMetric || thisIsMetric;\n if (children.length > 0) visit(children, nextUnderSpan, nextUnderMetric);\n }\n }\n visit(ir.root.children, false, false);\n\n return {\n spans,\n logPoints,\n metrics,\n coverage: {\n effectCount,\n effectsWithSpans,\n effectsWithMetrics,\n errorHandlersWithLogging,\n errorHandlerCount,\n },\n };\n}\n","/**\n * Dependency Injection Completeness Checker (GAP 27)\n *\n * Verifies that all service requirements are satisfied (layers provide required services).\n */\n\nimport type { StaticEffectIR, StaticFlowNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\nimport { buildLayerDependencyGraph } from './layer-graph';\nimport type { ServiceFlowAnalysis } from './service-flow';\nimport { analyzeServiceFlow } from './service-flow';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ServiceCompletenessEntry {\n serviceId: string;\n status: 'ok' | 'missing' | 'missing-dependency';\n providedBy?: string;\n message: string;\n}\n\nexport interface DICompletenessReport {\n programName: string;\n requiredServices: string[];\n providedByLayer: Map<string, string>;\n entries: ServiceCompletenessEntry[];\n layerGraphAcyclic: boolean;\n valid: boolean;\n readonly layerConflicts?: { serviceId: string; providers: import('./types').SourceLocation[] }[];\n}\n\nfunction detectLayerCycles(layerGraph: ReturnType<typeof buildLayerDependencyGraph>): boolean {\n const adjacency = new Map<string, string[]>();\n const providerByService = new Map<string, string[]>();\n\n for (const layer of layerGraph.layers) {\n for (const svc of layer.provides) {\n const providers = providerByService.get(svc) ?? [];\n providers.push(layer.id);\n providerByService.set(svc, providers);\n }\n }\n\n for (const layer of layerGraph.layers) {\n const deps: string[] = [];\n for (const req of layer.requires) {\n for (const provider of providerByService.get(req) ?? []) {\n if (provider !== layer.id) deps.push(provider);\n }\n }\n adjacency.set(layer.id, deps);\n }\n\n const visiting = new Set<string>();\n const visited = new Set<string>();\n\n const hasCycle = (node: string): boolean => {\n if (visiting.has(node)) return true;\n if (visited.has(node)) return false;\n visiting.add(node);\n for (const next of adjacency.get(node) ?? []) {\n if (hasCycle(next)) return true;\n }\n visiting.delete(node);\n visited.add(node);\n return false;\n };\n\n for (const layerId of adjacency.keys()) {\n if (hasCycle(layerId)) return false;\n }\n return true;\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nfunction _collectLayerProvides(nodes: readonly StaticFlowNode[]): Map<string, string> {\n const map = new Map<string, string>();\n function visit(list: readonly StaticFlowNode[]) {\n for (const node of list) {\n if (node.type === 'layer') {\n const layer = node;\n const layerId = layer.id;\n for (const svc of layer.provides ?? []) {\n map.set(svc, layerId);\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) visit(children);\n }\n }\n visit(nodes);\n return map;\n}\n\n/**\n * Check DI completeness for a single program IR: required services vs what layers provide.\n */\nexport function checkDICompleteness(ir: StaticEffectIR): DICompletenessReport {\n const serviceFlow: ServiceFlowAnalysis = analyzeServiceFlow(ir);\n const layerGraph = buildLayerDependencyGraph(ir);\n const providedByLayer = new Map<string, string>();\n for (const layer of layerGraph.layers) {\n for (const svc of layer.provides) {\n providedByLayer.set(svc, layer.id);\n }\n }\n const requiredIds = serviceFlow.requiredServices.map((r) => r.serviceId);\n const entries: ServiceCompletenessEntry[] = [];\n let valid = true;\n for (const serviceId of requiredIds) {\n const provider = providedByLayer.get(serviceId);\n if (provider) {\n entries.push({\n serviceId,\n status: 'ok',\n providedBy: provider,\n message: `provided by ${provider}`,\n });\n } else {\n valid = false;\n entries.push({\n serviceId,\n status: 'missing',\n message: 'NO PROVIDER FOUND',\n });\n }\n }\n const layerGraphAcyclic = detectLayerCycles(layerGraph);\n\n // Detect layer conflicts: multiple layers providing the same service\n const serviceProviderIds = new Map<string, string[]>();\n for (const layer of layerGraph.layers) {\n for (const svc of layer.provides) {\n const providers = serviceProviderIds.get(svc) ?? [];\n providers.push(layer.id);\n serviceProviderIds.set(svc, providers);\n }\n }\n // Find matching source locations from IR tree\n const layerLocMap = new Map<string, import('./types').SourceLocation>();\n const collectLayerLocations = (nodes: readonly StaticFlowNode[]) => {\n for (const node of nodes) {\n if (node.type === 'layer' && node.location) layerLocMap.set(node.id, node.location);\n const ch = Option.getOrElse(getStaticChildren(node), () => []);\n if (ch.length > 0) collectLayerLocations(ch);\n }\n };\n collectLayerLocations(ir.root.children);\n const layerConflicts: { serviceId: string; providers: import('./types').SourceLocation[] }[] = [];\n for (const [serviceId, providerLayerIds] of serviceProviderIds) {\n if (providerLayerIds.length > 1) {\n const locs = providerLayerIds.map(id => layerLocMap.get(id)).filter((l): l is import('./types').SourceLocation => l !== undefined);\n layerConflicts.push({ serviceId, providers: locs });\n }\n }\n\n return {\n programName: ir.root.programName,\n requiredServices: requiredIds,\n providedByLayer,\n entries,\n layerGraphAcyclic,\n valid,\n ...(layerConflicts.length > 0 ? { layerConflicts } : {}),\n };\n}\n\n/**\n * Format a DI completeness report as text.\n */\nexport function formatDICompletenessReport(report: DICompletenessReport): string {\n const lines: string[] = [];\n lines.push(`Service Completeness Report for ${report.programName}:`);\n for (const e of report.entries) {\n const icon = e.status === 'ok' ? '✓' : '✗';\n const provider = e.providedBy ? ` → provided by ${e.providedBy}` : '';\n lines.push(` ${icon} ${e.serviceId}${provider} ${e.status === 'missing' ? e.message : ''}`);\n }\n lines.push('');\n lines.push(report.valid ? 'All required services have providers.' : 'Some required services have no provider.');\n return lines.join('\\n');\n}\n","/**\n * Strict Mode Diagnostics for Effect IR\n *\n * Validates Effect programs against strict rules: error type declarations,\n * parallel/race error handling, and optional labelling.\n */\n\nimport type {\n StaticEffectIR,\n StaticFlowNode,\n StaticEffectNode,\n SourceLocation,\n} from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\nimport { buildLayerDependencyGraph } from './layer-graph';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface StrictDiagnostic {\n rule: StrictRule;\n severity: 'error' | 'warning';\n message: string;\n fix?: string | undefined;\n location?: SourceLocation | undefined;\n nodeId?: string | undefined;\n}\n\nexport type StrictRule =\n | 'missing-error-type'\n | 'unknown-error-type'\n | 'parallel-missing-errors'\n | 'race-missing-errors'\n | 'effect-without-handler'\n | 'fiber-potential-leak'\n | 'resource-missing-scope'\n | 'unbounded-concurrency'\n | 'unused-service'\n | 'dead-code-path';\n\nexport interface StrictValidationResult {\n valid: boolean;\n diagnostics: StrictDiagnostic[];\n errors: StrictDiagnostic[];\n warnings: StrictDiagnostic[];\n}\n\nexport interface StrictValidationOptions {\n /** Require effect nodes to have a declared error type (not unknown/never when they can fail) */\n requireErrors?: boolean | undefined;\n /** Require effects in parallel/race to have error type */\n requireParallelErrors?: boolean | undefined;\n warningsAsErrors?: boolean | undefined;\n}\n\nconst DEFAULT_OPTIONS: Required<\n Omit<StrictValidationOptions, 'warningsAsErrors'>\n> & { warningsAsErrors: boolean } = {\n requireErrors: true,\n requireParallelErrors: true,\n warningsAsErrors: false,\n};\n\n// =============================================================================\n// Validation\n// =============================================================================\n\nexport function validateStrict(\n ir: StaticEffectIR,\n options: StrictValidationOptions = {},\n): StrictValidationResult {\n const opts = {\n ...DEFAULT_OPTIONS,\n ...options,\n requireErrors: options.requireErrors ?? true,\n requireParallelErrors: options.requireParallelErrors ?? true,\n warningsAsErrors: options.warningsAsErrors ?? false,\n };\n const diagnostics: StrictDiagnostic[] = [];\n\n validateNodes(ir.root.children, opts, diagnostics, false);\n\n // Extended validators (Phase 9)\n validateFiberLeaks(ir.root.children, diagnostics, new Set());\n validateResourceScopes(ir.root.children, diagnostics, false);\n validateConcurrencyBounds(ir.root.children, diagnostics);\n validateDeadCodePaths(ir.root.children, diagnostics);\n validateUnusedServices(ir, diagnostics);\n\n const errors = diagnostics.filter(\n (d) =>\n d.severity === 'error' ||\n (opts.warningsAsErrors && d.severity === 'warning'),\n );\n const warnings = diagnostics.filter(\n (d) => d.severity === 'warning' && !opts.warningsAsErrors,\n );\n\n return {\n valid: errors.length === 0,\n diagnostics,\n errors,\n warnings,\n };\n}\n\nfunction validateNodes(\n nodes: readonly StaticFlowNode[],\n opts: typeof DEFAULT_OPTIONS,\n diagnostics: StrictDiagnostic[],\n hasAncestorErrorHandler = false,\n): void {\n for (const node of nodes) {\n const currentHasErrorHandler =\n hasAncestorErrorHandler || node.type === 'error-handler';\n\n if (node.type === 'effect') {\n const eff = node;\n validateEffectNode(eff, opts, diagnostics);\n // effect-without-handler: effect can fail but no handler on path from root\n const errorType = eff.typeSignature?.errorType?.trim();\n const canFail = errorType && errorType !== 'never';\n if (canFail && !hasAncestorErrorHandler) {\n diagnostics.push({\n rule: 'effect-without-handler',\n severity: 'warning',\n message: `Effect \"${eff.callee}\" can fail with \"${errorType}\" but has no error handler (catchAll/catchTag/orElse) on this path`,\n fix: 'Wrap in .pipe(Effect.catchAll(...)) or handle errors before this point',\n location: eff.location,\n nodeId: eff.id,\n });\n }\n }\n if (node.type === 'parallel' && opts.requireParallelErrors) {\n for (const child of node.children) {\n if (child.type === 'effect') {\n const eff = child;\n const errorType = eff.typeSignature?.errorType;\n if (\n !errorType ||\n errorType === 'unknown' ||\n errorType.trim() === ''\n ) {\n diagnostics.push({\n rule: 'parallel-missing-errors',\n severity: 'warning',\n message: `Parallel branch effect \"${eff.callee}\" does not declare error type`,\n fix: 'Add type signature or use Effect.mapError/catchTag to narrow errors',\n location: eff.location,\n nodeId: eff.id,\n });\n }\n }\n }\n }\n if (node.type === 'race' && opts.requireParallelErrors) {\n for (const child of node.children) {\n if (child.type === 'effect') {\n const eff = child;\n const errorType = eff.typeSignature?.errorType;\n if (\n !errorType ||\n errorType === 'unknown' ||\n errorType.trim() === ''\n ) {\n diagnostics.push({\n rule: 'race-missing-errors',\n severity: 'warning',\n message: `Race branch effect \"${eff.callee}\" does not declare error type`,\n fix: 'Add type signature or use Effect.mapError/catchTag to narrow errors',\n location: eff.location,\n nodeId: eff.id,\n });\n }\n }\n }\n }\n\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n validateNodes(children, opts, diagnostics, currentHasErrorHandler);\n }\n }\n}\n\n// =============================================================================\n// Extended Rule Validators (Phase 9)\n// =============================================================================\n\n/**\n * Detect fiber forks without join/interrupt in scope.\n */\nfunction validateFiberLeaks(\n nodes: readonly StaticFlowNode[],\n diagnostics: StrictDiagnostic[],\n joinPointsInScope: Set<string>,\n): void {\n for (const node of nodes) {\n if (node.type === 'fiber') {\n const fiber = node;\n if (\n (fiber.operation === 'fork' || fiber.operation === 'forkAll') &&\n !fiber.isScoped &&\n !fiber.isDaemon\n ) {\n // Check if any join/interrupt exists in scope\n if (!joinPointsInScope.has('join') && !joinPointsInScope.has('interrupt') && !joinPointsInScope.has('await')) {\n diagnostics.push({\n rule: 'fiber-potential-leak',\n severity: 'warning',\n message: `Fiber.${fiber.operation} without join/interrupt in scope — potential fiber leak`,\n fix: 'Use Fiber.join, Fiber.interrupt, or forkScoped instead',\n location: fiber.location,\n nodeId: fiber.id,\n });\n }\n }\n // Track join points for scope\n if (fiber.operation === 'join' || fiber.operation === 'interrupt' || fiber.operation === 'await') {\n joinPointsInScope.add(fiber.operation);\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n validateFiberLeaks(children, diagnostics, joinPointsInScope);\n }\n }\n}\n\n/**\n * Detect resource acquisitions without proper scoping.\n */\nfunction validateResourceScopes(\n nodes: readonly StaticFlowNode[],\n diagnostics: StrictDiagnostic[],\n inScope: boolean,\n): void {\n for (const node of nodes) {\n if (node.type === 'resource' && !inScope) {\n diagnostics.push({\n rule: 'resource-missing-scope',\n severity: 'warning',\n message: 'acquireRelease without visible Effect.scoped in scope',\n fix: 'Wrap resource usage in Effect.scoped',\n location: node.location,\n nodeId: node.id,\n });\n }\n\n // Track scope entry\n const isScope = node.type === 'effect' && node.callee === 'Effect.scoped';\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n validateResourceScopes(children, diagnostics, inScope || isScope);\n }\n }\n}\n\n/**\n * Detect unbounded concurrency: Effect.all/forEach without concurrency option.\n */\nfunction validateConcurrencyBounds(\n nodes: readonly StaticFlowNode[],\n diagnostics: StrictDiagnostic[],\n): void {\n for (const node of nodes) {\n if (node.type === 'parallel' && node.children.length > 5) {\n // Large parallel collections without explicit concurrency control\n const callee = node.callee || '';\n if (callee.includes('all') || callee.includes('forEach')) {\n diagnostics.push({\n rule: 'unbounded-concurrency',\n severity: 'warning',\n message: `${callee} with ${node.children.length} children — consider adding { concurrency } option`,\n fix: 'Add { concurrency: N } to limit concurrent execution',\n location: node.location,\n nodeId: node.id,\n });\n }\n }\n if (node.type === 'loop' && (node.loopType === 'forEach' || node.loopType === 'validate')) {\n // Large collection loops\n diagnostics.push({\n rule: 'unbounded-concurrency',\n severity: 'warning',\n message: `Effect.${node.loopType} may run unbounded — consider concurrency control`,\n fix: 'Add { concurrency: N } option',\n location: node.location,\n nodeId: node.id,\n });\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n validateConcurrencyBounds(children, diagnostics);\n }\n }\n}\n\n/**\n * Detect decision branches with const-resolvable conditions that always go one way.\n */\nfunction validateDeadCodePaths(\n nodes: readonly StaticFlowNode[],\n diagnostics: StrictDiagnostic[],\n): void {\n for (const node of nodes) {\n if (node.type === 'decision') {\n const label = node.label.trim();\n // If the label resolved to a literal boolean, it's a dead code path\n if (label === 'true' || label === 'false') {\n diagnostics.push({\n rule: 'dead-code-path',\n severity: 'warning',\n message: `Decision \"${node.condition}\" always resolves to ${label} — ${label === 'true' ? 'false' : 'true'} branch is dead code`,\n fix: 'Remove the dead branch or fix the condition',\n location: node.location,\n nodeId: node.id,\n });\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n validateDeadCodePaths(children, diagnostics);\n }\n }\n}\n\n/**\n * Detect services provided by layers but never consumed by any effect.\n */\nfunction validateUnusedServices(\n ir: StaticEffectIR,\n diagnostics: StrictDiagnostic[],\n): void {\n const layerGraph = buildLayerDependencyGraph(ir);\n if (layerGraph.layers.length === 0) return;\n\n // Collect all services that are consumed (required) by any layer\n const consumedServices = new Set<string>();\n for (const layer of layerGraph.layers) {\n for (const req of layer.requires) {\n consumedServices.add(req);\n }\n }\n\n // Also collect services required by effects in the IR\n collectConsumedServicesFromNodes(ir.root.children, consumedServices);\n\n // Check which provided services are never consumed\n for (const layer of layerGraph.layers) {\n for (const svc of layer.provides) {\n if (!consumedServices.has(svc)) {\n diagnostics.push({\n rule: 'unused-service',\n severity: 'warning',\n message: `Service \"${svc}\" is provided by layer \"${layer.name ?? layer.id}\" but never consumed`,\n fix: 'Remove unused service provision or add a consumer',\n nodeId: layer.id,\n });\n }\n }\n }\n}\n\nfunction collectConsumedServicesFromNodes(\n nodes: readonly StaticFlowNode[],\n consumed: Set<string>,\n): void {\n for (const node of nodes) {\n if (node.type === 'effect') {\n const reqs = node.requiredServices ?? [];\n for (const r of reqs) {\n consumed.add(r.serviceId);\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) {\n collectConsumedServicesFromNodes(children, consumed);\n }\n }\n}\n\nfunction validateEffectNode(\n node: StaticEffectNode,\n opts: typeof DEFAULT_OPTIONS,\n diagnostics: StrictDiagnostic[],\n): void {\n if (!opts.requireErrors) return;\n\n const errorType = node.typeSignature?.errorType;\n if (!errorType) {\n diagnostics.push({\n rule: 'missing-error-type',\n severity: 'warning',\n message: `Effect \"${node.callee}\" has no extracted error type`,\n fix: 'Ensure type checker can infer Effect<A, E, R> or add explicit type',\n location: node.location,\n nodeId: node.id,\n });\n return;\n }\n\n const t = errorType.trim();\n if (t === 'unknown') {\n diagnostics.push({\n rule: 'unknown-error-type',\n severity: 'warning',\n message: `Effect \"${node.callee}\" has error type \"unknown\"`,\n fix: 'Use a concrete error type or branded errors for better validation',\n location: node.location,\n nodeId: node.id,\n });\n }\n}\n\n// =============================================================================\n// Formatting\n// =============================================================================\n\nexport function formatDiagnostics(result: StrictValidationResult): string {\n const lines: string[] = [];\n\n if (result.valid) {\n lines.push('All strict mode checks passed');\n if (result.warnings.length > 0) {\n lines.push(\n ` (${result.warnings.length} warning${result.warnings.length === 1 ? '' : 's'})`,\n );\n }\n } else {\n lines.push(\n `Strict validation failed: ${result.errors.length} error(s)`,\n );\n }\n\n lines.push('');\n\n for (const diag of result.diagnostics) {\n const icon = diag.severity === 'error' ? 'x' : '!';\n const loc = diag.location\n ? `:${diag.location.line}:${diag.location.column}`\n : '';\n lines.push(`[${icon}] [${diag.rule}]${loc}`);\n lines.push(` ${diag.message}`);\n if (diag.fix) {\n lines.push(` Fix: ${diag.fix}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n\nexport function formatDiagnosticsJSON(\n result: StrictValidationResult,\n): string {\n return JSON.stringify(\n {\n valid: result.valid,\n errorCount: result.errors.length,\n warningCount: result.warnings.length,\n diagnostics: result.diagnostics.map((d) => ({\n rule: d.rule,\n severity: d.severity,\n message: d.message,\n fix: d.fix,\n location: d.location\n ? {\n line: d.location.line,\n column: d.location.column,\n }\n : undefined,\n nodeId: d.nodeId,\n })),\n },\n null,\n 2,\n );\n}\n\nexport function getSummary(result: StrictValidationResult): string {\n if (result.valid && result.warnings.length === 0) {\n return 'All strict mode checks passed';\n }\n if (result.valid) {\n return `Passed with ${result.warnings.length} warning(s)`;\n }\n return `${result.errors.length} error(s), ${result.warnings.length} warning(s)`;\n}\n","/**\n * Test Coverage Matrix Generator\n *\n * Generates a test coverage matrix from Effect paths, helping developers\n * ensure all paths through an Effect program are tested.\n */\n\nimport type {\n EffectPath,\n TestMatrix,\n TestPath,\n TestCondition,\n TestMatrixSummary,\n} from '../types';\n\n// =============================================================================\n// Options\n// =============================================================================\n\nexport interface TestMatrixOptions {\n /** Prefix for generated test names */\n testNamePrefix?: string;\n /** Function to customize test name generation */\n testNameGenerator?: (path: EffectPath) => string;\n /** Whether to include paths with loops (they may need special handling) */\n includeLoopPaths?: boolean;\n}\n\nconst DEFAULT_OPTIONS: Required<TestMatrixOptions> = {\n testNamePrefix: 'should',\n testNameGenerator: defaultTestNameGenerator,\n includeLoopPaths: true,\n};\n\n// =============================================================================\n// Main Generator\n// =============================================================================\n\nexport function generateTestMatrix(\n paths: EffectPath[],\n options: TestMatrixOptions = {},\n): TestMatrix {\n const opts = { ...DEFAULT_OPTIONS, ...options };\n\n let filteredPaths = paths;\n if (!opts.includeLoopPaths) {\n filteredPaths = paths.filter((p) => !p.hasLoops);\n }\n\n const testPaths = filteredPaths.map((path) => generateTestPath(path, opts));\n const conditions = extractConditions(filteredPaths);\n const summary = calculateSummary(testPaths, conditions);\n\n return {\n paths: testPaths,\n conditions,\n summary,\n };\n}\n\n// =============================================================================\n// Test Path Generation\n// =============================================================================\n\nfunction generateTestPath(\n path: EffectPath,\n opts: Required<TestMatrixOptions>,\n): TestPath {\n const testName = opts.testNameGenerator(path);\n const priority = determinePriority(path);\n\n const setupConditions = path.conditions.map((c) => {\n const verb = c.mustBe ? 'be truthy' : 'be falsy';\n return `Set up ${c.expression} to ${verb}`;\n });\n\n const expectedSteps = path.steps.map((s) => {\n const name = s.name ?? s.nodeId;\n return s.repeated ? `${name} (may repeat)` : name;\n });\n\n return {\n id: path.id,\n suggestedTestName: testName,\n description: path.description,\n setupConditions,\n expectedSteps,\n priority,\n };\n}\n\nfunction determinePriority(path: EffectPath): 'high' | 'medium' | 'low' {\n if (path.conditions.length === 0 && !path.hasLoops) {\n return 'high';\n }\n if (path.hasLoops && path.conditions.length > 2) {\n return 'low';\n }\n return 'medium';\n}\n\nfunction defaultTestNameGenerator(path: EffectPath): string {\n const parts: string[] = ['should'];\n\n if (path.steps.length > 0) {\n const mainSteps = path.steps.filter((s) => !s.repeated).slice(0, 3);\n if (mainSteps.length > 0) {\n const stepNames = mainSteps.map((s) =>\n camelToSpaces(s.name ?? s.nodeId),\n );\n parts.push(stepNames.join(' then '));\n }\n }\n\n if (path.conditions.length > 0) {\n parts.push('when');\n const conditionDescriptions = path.conditions.slice(0, 2).map((c) => {\n const simplified = simplifyCondition(c.expression);\n return c.mustBe ? simplified : `not ${simplified}`;\n });\n parts.push(conditionDescriptions.join(' and '));\n }\n\n if (path.hasLoops) {\n parts.push('(with iteration)');\n }\n\n return parts.join(' ');\n}\n\nfunction camelToSpaces(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1 $2')\n .toLowerCase();\n}\n\nfunction simplifyCondition(expression: string): string {\n return expression\n .replace(/\\s*===\\s*true/g, '')\n .replace(/\\s*===\\s*false/g, ' is false')\n .replace(/\\s*===\\s*/g, ' is ')\n .replace(/\\s*!==\\s*/g, ' is not ')\n .replace(/\\s*>\\s*/g, ' greater than ')\n .replace(/\\s*<\\s*/g, ' less than ')\n .replace(/\\s*>=\\s*/g, ' at least ')\n .replace(/\\s*<=\\s*/g, ' at most ')\n .replace(/&&/g, ' and ')\n .replace(/\\|\\|/g, ' or ')\n .trim();\n}\n\n// =============================================================================\n// Condition Extraction\n// =============================================================================\n\nfunction extractConditions(paths: EffectPath[]): TestCondition[] {\n const conditionMap = new Map<\n string,\n { whenTrue: string[]; whenFalse: string[] }\n >();\n\n for (const path of paths) {\n for (const condition of path.conditions) {\n const key = condition.expression;\n\n if (!conditionMap.has(key)) {\n conditionMap.set(key, { whenTrue: [], whenFalse: [] });\n }\n\n const entry = conditionMap.get(key);\n if (entry) {\n if (condition.mustBe) {\n entry.whenTrue.push(path.id);\n } else {\n entry.whenFalse.push(path.id);\n }\n }\n }\n }\n\n return Array.from(conditionMap.entries()).map(([expression, affected]) => ({\n expression,\n affectedPathsWhenTrue: affected.whenTrue,\n affectedPathsWhenFalse: affected.whenFalse,\n }));\n}\n\n// =============================================================================\n// Summary\n// =============================================================================\n\nfunction calculateSummary(\n paths: TestPath[],\n conditions: TestCondition[],\n): TestMatrixSummary {\n const highPriorityPaths = paths.filter((p) => p.priority === 'high').length;\n const minTestsForCoverage = Math.max(\n 1,\n conditions.length * 2,\n );\n\n return {\n totalPaths: paths.length,\n highPriorityPaths,\n totalConditions: conditions.length,\n minTestsForCoverage,\n };\n}\n\n// =============================================================================\n// Output Formatting\n// =============================================================================\n\nexport function formatTestMatrixMarkdown(matrix: TestMatrix): string {\n const lines: string[] = [];\n\n lines.push('# Test Coverage Matrix');\n lines.push('');\n lines.push('## Summary');\n lines.push('');\n lines.push(`- **Total Paths:** ${matrix.summary.totalPaths}`);\n lines.push(`- **High Priority Paths:** ${matrix.summary.highPriorityPaths}`);\n lines.push(`- **Conditions to Test:** ${matrix.summary.totalConditions}`);\n lines.push(\n `- **Minimum Tests for Coverage:** ${matrix.summary.minTestsForCoverage}`,\n );\n lines.push('');\n\n lines.push('## Test Cases');\n lines.push('');\n\n const highPriority = matrix.paths.filter((p) => p.priority === 'high');\n const mediumPriority = matrix.paths.filter((p) => p.priority === 'medium');\n const lowPriority = matrix.paths.filter((p) => p.priority === 'low');\n\n if (highPriority.length > 0) {\n lines.push('### High Priority');\n lines.push('');\n for (const path of highPriority) {\n lines.push(...formatTestPathLines(path));\n }\n lines.push('');\n }\n\n if (mediumPriority.length > 0) {\n lines.push('### Medium Priority');\n lines.push('');\n for (const path of mediumPriority) {\n lines.push(...formatTestPathLines(path));\n }\n lines.push('');\n }\n\n if (lowPriority.length > 0) {\n lines.push('### Low Priority');\n lines.push('');\n for (const path of lowPriority) {\n lines.push(...formatTestPathLines(path));\n }\n lines.push('');\n }\n\n if (matrix.conditions.length > 0) {\n lines.push('## Conditions Coverage');\n lines.push('');\n lines.push('| Condition | Paths When True | Paths When False |');\n lines.push('|-----------|-----------------|------------------|');\n\n for (const condition of matrix.conditions) {\n const truncatedExpr =\n condition.expression.length > 40\n ? condition.expression.slice(0, 40) + '...'\n : condition.expression;\n const trueCount = condition.affectedPathsWhenTrue.length;\n const falseCount = condition.affectedPathsWhenFalse.length;\n lines.push(`| \\`${truncatedExpr}\\` | ${trueCount} | ${falseCount} |`);\n }\n lines.push('');\n }\n\n lines.push('## Test Checklist');\n lines.push('');\n for (const path of matrix.paths) {\n const priority =\n path.priority === 'high'\n ? 'HIGH'\n : path.priority === 'medium'\n ? 'MED'\n : 'LOW';\n lines.push(`- [ ] [${priority}] ${path.suggestedTestName}`);\n }\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction formatTestPathLines(path: TestPath): string[] {\n const lines: string[] = [];\n lines.push(`#### ${path.suggestedTestName}`);\n lines.push('');\n\n if (path.setupConditions.length > 0) {\n lines.push('**Setup:**');\n for (const condition of path.setupConditions) {\n lines.push(`- ${condition}`);\n }\n lines.push('');\n }\n\n lines.push('**Expected Steps:**');\n for (let i = 0; i < path.expectedSteps.length; i++) {\n lines.push(`${i + 1}. ${path.expectedSteps[i]}`);\n }\n lines.push('');\n\n return lines;\n}\n\nexport function formatTestMatrixAsCode(\n matrix: TestMatrix,\n options: {\n testRunner?: 'vitest' | 'jest' | 'mocha';\n programName?: string;\n } = {},\n): string {\n const runner = options.testRunner ?? 'vitest';\n const programName = options.programName ?? 'program';\n\n const lines: string[] = [];\n\n if (runner === 'vitest') {\n lines.push(\"import { describe, it, expect } from 'vitest';\");\n } else if (runner === 'jest') {\n lines.push('// Jest test file');\n } else {\n lines.push(\"import { describe, it } from 'mocha';\");\n lines.push(\"import { expect } from 'chai';\");\n }\n\n lines.push('');\n lines.push(`describe('${programName}', () => {`);\n\n for (const path of matrix.paths) {\n lines.push('');\n lines.push(` it('${escapeString(path.suggestedTestName)}', async () => {`);\n lines.push(' // Setup');\n for (const condition of path.setupConditions) {\n lines.push(` // TODO: ${condition}`);\n }\n lines.push('');\n lines.push(' // Execute effect program');\n lines.push(` // const result = await Effect.runPromise(${programName});`);\n lines.push('');\n lines.push(' // Verify expected steps executed');\n for (const step of path.expectedSteps) {\n lines.push(` // TODO: Verify ${step} was executed`);\n }\n lines.push(' });');\n }\n\n lines.push('});');\n lines.push('');\n\n return lines.join('\\n');\n}\n\nfunction escapeString(str: string): string {\n return str.replace(/'/g, \"\\\\'\").replace(/\"/g, '\\\\\"');\n}\n\nexport function formatTestChecklist(matrix: TestMatrix): string {\n const lines: string[] = [];\n\n lines.push('Test Coverage Checklist');\n lines.push('=======================');\n lines.push('');\n lines.push(`Total: ${matrix.summary.totalPaths} tests needed`);\n lines.push(`High Priority: ${matrix.summary.highPriorityPaths}`);\n lines.push('');\n\n for (const path of matrix.paths) {\n const marker =\n path.priority === 'high'\n ? '***'\n : path.priority === 'medium'\n ? '**'\n : '*';\n lines.push(`[ ] ${marker} ${path.suggestedTestName}`);\n if (path.setupConditions.length > 0) {\n lines.push(` Conditions: ${path.setupConditions.join(', ')}`);\n }\n }\n\n return lines.join('\\n');\n}\n","/**\n * Config Module Analysis (GAP 9)\n *\n * Detects Effect Config / ConfigProvider usage.\n */\n\nimport { Project, SyntaxKind } from 'ts-morph';\nimport type { SourceLocation } from './types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface ConfigItem {\n readonly key: string;\n readonly type:\n | 'string'\n | 'number'\n | 'integer'\n | 'boolean'\n | 'date'\n | 'duration'\n | 'url'\n | 'port'\n | 'logLevel'\n | 'literal'\n | 'array'\n | 'map'\n | 'nested'\n | 'secret'\n | 'unknown';\n readonly required: boolean;\n readonly hasDefault: boolean;\n readonly location?: SourceLocation;\n}\n\nexport interface ConfigCombinator {\n readonly kind:\n | 'map'\n | 'mapAttempt'\n | 'mapOrFail'\n | 'orElse'\n | 'orElseIf'\n | 'withDefault'\n | 'withDescription'\n | 'validate'\n | 'repeat'\n | 'option';\n readonly location?: SourceLocation;\n}\n\nexport interface ConfigAnalysis {\n readonly requiredConfigs: ConfigItem[];\n readonly optionalConfigs: ConfigItem[];\n readonly secretConfigs: ConfigItem[];\n readonly providerOverrides: string[];\n readonly envVarHints: Map<string, string>;\n readonly combinators: ConfigCombinator[];\n}\n\n// =============================================================================\n// Detection\n// =============================================================================\n\nfunction getLocation(\n filePath: string,\n node: { getStart: () => number },\n sourceFile: { getLineAndColumnAtPos: (p: number) => { line: number; column: number } },\n): SourceLocation {\n const { line, column } = sourceFile.getLineAndColumnAtPos(node.getStart());\n return { filePath, line: line + 1, column };\n}\n\n/**\n * Analyze a TypeScript file for Effect Config usage.\n */\nexport function analyzeConfig(\n filePath: string,\n source?: string,\n): ConfigAnalysis {\n const project = new Project({ useInMemoryFileSystem: true });\n const sourceFile = source\n ? project.createSourceFile(filePath, source)\n : project.addSourceFileAtPath(filePath);\n\n const requiredConfigs: ConfigItem[] = [];\n const optionalConfigs: ConfigItem[] = [];\n const secretConfigs: ConfigItem[] = [];\n const providerOverrides: string[] = [];\n const envVarHints = new Map<string, string>();\n const combinators: ConfigCombinator[] = [];\n\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n const loc = getLocation(filePath, node, sourceFile);\n const args = node.getArguments();\n const keyArg = args[0];\n const key = keyArg?.getText().replace(/[\"'`]/g, '').trim() ?? 'unknown';\n const parentText = node.getParent()?.getText() ?? '';\n const hasDefault = parentText.includes('withDefault');\n const envKey = key.toUpperCase().replace(/[^A-Z0-9]/g, '_');\n envVarHints.set(key, envKey);\n\n const configType = (\n text.includes('Config.nonEmptyString') ? 'string' :\n text.includes('Config.string') ? 'string' :\n text.includes('Config.integer') ? 'integer' :\n text.includes('Config.number') ? 'number' :\n text.includes('Config.boolean') ? 'boolean' :\n text.includes('Config.date') ? 'date' :\n text.includes('Config.duration') ? 'duration' :\n text.includes('Config.url') ? 'url' :\n text.includes('Config.port') ? 'port' :\n text.includes('Config.logLevel') ? 'logLevel' :\n text.includes('Config.literal') ? 'literal' :\n text.includes('Config.array') || text.includes('Config.chunk') ? 'array' :\n text.includes('Config.hashSet') || text.includes('Config.hashMap') ? 'map' :\n text.includes('Config.nested') || text.includes('Config.all') ? 'nested' :\n undefined\n );\n\n if (configType !== undefined) {\n const item: ConfigItem = {\n key,\n type: configType,\n required: !hasDefault,\n hasDefault,\n location: loc,\n };\n if (hasDefault || parentText.includes('Config.option')) optionalConfigs.push(item);\n else requiredConfigs.push(item);\n } else if (text === 'Config.secret' || text === 'Config.redacted' || (text.includes('Config.secret') || text.includes('Config.redacted'))) {\n secretConfigs.push({ key, type: 'secret', required: true, hasDefault: false, location: loc });\n }\n\n if (\n text.includes('Effect.withConfigProvider') ||\n text.includes('Layer.setConfigProvider')\n ) {\n providerOverrides.push(text);\n }\n\n // Detect Config combinators (wrapping transforms / fallbacks)\n const COMBINATOR_MAP: [string, ConfigCombinator['kind']][] = [\n ['Config.mapOrFail', 'mapOrFail'],\n ['Config.mapAttempt', 'mapAttempt'],\n ['Config.map', 'map'],\n ['Config.orElseIf', 'orElseIf'],\n ['Config.orElse', 'orElse'],\n ['Config.withDefault', 'withDefault'],\n ['Config.withDescription', 'withDescription'],\n ['Config.validate', 'validate'],\n ['Config.repeat', 'repeat'],\n ['Config.option', 'option'],\n ];\n for (const [pattern, kind] of COMBINATOR_MAP) {\n if (text === pattern || text.startsWith(pattern + '(') || text.startsWith(pattern + '<')) {\n combinators.push({ kind, location: loc });\n break;\n }\n }\n }\n\n return {\n requiredConfigs,\n optionalConfigs,\n secretConfigs,\n providerOverrides: [...new Set(providerOverrides)],\n envVarHints,\n combinators,\n };\n}\n\n/**\n * Format config analysis as a markdown table.\n */\nexport function formatConfigReport(analysis: ConfigAnalysis): string {\n const lines: string[] = ['| Config Key | Type | Required | Default | Secret |', '|------------|------|----------|---------|--------|'];\n const all = [\n ...analysis.requiredConfigs,\n ...analysis.optionalConfigs,\n ...analysis.secretConfigs,\n ];\n const seen = new Set<string>();\n for (const c of all) {\n if (seen.has(c.key)) continue;\n seen.add(c.key);\n const req = c.required ? 'yes' : 'no';\n const def = c.hasDefault ? 'yes' : '-';\n const secret = analysis.secretConfigs.some((s) => s.key === c.key) ? 'yes' : 'no';\n lines.push(`| ${c.key} | ${c.type} | ${req} | ${def} | ${secret} |`);\n }\n lines.push('');\n lines.push(`Total: ${seen.size} config key(s)`);\n if (analysis.providerOverrides.length > 0) {\n lines.push(`Config providers: ${analysis.providerOverrides.length}`);\n }\n if (analysis.combinators.length > 0) {\n const byKind = new Map<string, number>();\n for (const c of analysis.combinators) {\n byKind.set(c.kind, (byKind.get(c.kind) ?? 0) + 1);\n }\n const combSummary = Array.from(byKind.entries())\n .map(([k, n]) => `${k}(×${n})`)\n .join(', ');\n lines.push(`Config combinators: ${combSummary}`);\n }\n return lines.join('\\n');\n}\n","/**\n * Pattern Matching (Match) Analysis (GAP 12)\n *\n * Detects Effect Match module usage and non-exhaustive matches.\n */\n\nimport { Project, SyntaxKind } from 'ts-morph';\nimport type { SourceLocation } from './types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface MatchArmInfo {\n readonly kind: 'tag' | 'when' | 'not' | 'orElse' | 'exhaustive';\n readonly tag?: string;\n readonly location?: SourceLocation;\n}\n\nexport interface MatchAnalysis {\n readonly matchSites: MatchSiteInfo[];\n readonly nonExhaustive: MatchSiteInfo[];\n}\n\nexport interface MatchSiteInfo {\n readonly location?: SourceLocation;\n readonly arms: MatchArmInfo[];\n readonly hasExhaustive: boolean;\n readonly hasOrElse: boolean;\n}\n\nfunction getLoc(\n filePath: string,\n node: { getStart: () => number },\n sf: { getLineAndColumnAtPos: (p: number) => { line: number; column: number } },\n): SourceLocation {\n const { line, column } = sf.getLineAndColumnAtPos(node.getStart());\n return { filePath, line: line + 1, column };\n}\n\n/**\n * Analyze a file for Effect Match usage.\n */\nexport function analyzeMatch(filePath: string, source?: string): MatchAnalysis {\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = source ? project.createSourceFile(filePath, source) : project.addSourceFileAtPath(filePath);\n const matchSites: MatchSiteInfo[] = [];\n const nonExhaustive: MatchSiteInfo[] = [];\n\n for (const node of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression();\n const text = expr.getText();\n if (!text.includes('Match')) continue;\n if (text.includes('Match.type') || text.includes('Match.tag') || text.includes('Match.value')) {\n const chain = node.getParent();\n const full = chain?.getText() ?? '';\n const arms: MatchArmInfo[] = [];\n const hasExhaustive = full.includes('.exhaustive(');\n const hasOrElse = full.includes('.orElse(');\n if (full.includes('Match.tag(')) {\n const tagMatch = /Match\\.tag\\s*\\(\\s*[\"'](\\w+)[\"']/.exec(full);\n if (tagMatch) {\n const tag = tagMatch[1];\n const arm: MatchArmInfo = tag !== undefined\n ? { kind: 'tag', tag, location: getLoc(filePath, node, sf) }\n : { kind: 'tag', location: getLoc(filePath, node, sf) };\n arms.push(arm);\n }\n }\n if (hasExhaustive) arms.push({ kind: 'exhaustive' });\n if (hasOrElse) arms.push({ kind: 'orElse' });\n const site: MatchSiteInfo = {\n location: getLoc(filePath, node, sf),\n arms,\n hasExhaustive,\n hasOrElse,\n };\n matchSites.push(site);\n if (!hasExhaustive && !hasOrElse) nonExhaustive.push(site);\n }\n }\n\n return { matchSites, nonExhaustive };\n}\n","/**\n * Platform Integration Detection (GAP 14)\n *\n * Detects which Effect platform modules are in use (HTTP, FileSystem, etc.).\n */\n\nimport { Project, SyntaxKind, type Node, type CallExpression, type TaggedTemplateExpression } from 'ts-morph';\nimport type { SourceLocation } from './types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface PlatformUsageAnalysis {\n readonly platforms: ('node' | 'bun' | 'browser')[];\n readonly modules: {\n readonly http: {\n client: boolean;\n server: boolean;\n routes: string[];\n api: boolean;\n apiBuilder: boolean;\n endpoint: boolean;\n security: boolean;\n middleware: boolean;\n };\n readonly filesystem: { reads: string[]; writes: string[] };\n readonly sockets: boolean;\n readonly terminal: boolean;\n readonly workers: boolean;\n readonly commands: string[];\n readonly keyValueStore: boolean;\n readonly multipart: boolean;\n readonly codecs: string[];\n readonly openApi: boolean;\n };\n readonly locations: Map<string, SourceLocation>;\n readonly fileSystemOps?: { op: string; location: SourceLocation }[];\n readonly commandOps?: { op: string; location: SourceLocation }[];\n readonly routeDefinitions?: {\n readonly method: string;\n readonly name: string;\n readonly path: string;\n readonly location: SourceLocation;\n readonly apiId?: string;\n readonly groupName?: string;\n }[];\n readonly middlewareChain?: { name: string; location: SourceLocation }[];\n readonly cliCommands?: { name: string; hasSchema: boolean; location: SourceLocation }[];\n}\n\nfunction getLoc(\n filePath: string,\n node: { getStart: () => number },\n sf: { getLineAndColumnAtPos: (p: number) => { line: number; column: number } },\n): SourceLocation {\n const { line, column } = sf.getLineAndColumnAtPos(node.getStart());\n return { filePath, line: line + 1, column };\n}\n\n/** Extract path from template literal; use :param for ${HttpApiSchema.param(\"x\", s)} or ${x} */\nfunction extractPathFromTemplate(\n template: import('ts-morph').TemplateLiteral,\n): string {\n const rawText = template.getText();\n const withParams = rawText.replace(\n /\\$\\{HttpApiSchema\\.param\\s*\\(\\s*[\"'](\\w+)[\"'][^}]*\\)\\}/g,\n ':$1',\n ).replace(/\\$\\{[^}]*\\}/g, ':param');\n const path = withParams.replace(/^`|`$/g, '').trim();\n return path.startsWith('/') ? path : `/${path}`;\n}\n\n/** Walk up .add() chain to find HttpApi.make(id) and HttpApiGroup.make(name) */\nfunction walkAddChainForApiContext(\n node: Node,\n): { apiId?: string; groupName?: string } {\n let apiId: string | undefined;\n let groupName: string | undefined;\n let current: Node = node;\n for (let i = 0; i < 20; i++) {\n const parent = current.getParent();\n if (!parent) break;\n if (parent.getKind() === SyntaxKind.CallExpression) {\n const call = parent as CallExpression;\n const callee = call.getExpression().getText();\n if (callee.endsWith('.add')) {\n const args = call.getArguments();\n if (args.length > 0) {\n const receiver = callee.slice(0, -4);\n const makeMatch = /HttpApi\\.make\\s*\\(\\s*[\"']([^\"']+)[\"']/.exec(receiver);\n if (makeMatch) apiId = makeMatch[1];\n const groupMatch = /HttpApiGroup\\.make\\s*\\(\\s*[\"']([^\"']+)[\"']/.exec(receiver);\n if (groupMatch) groupName = groupMatch[1];\n }\n }\n }\n current = parent;\n }\n const result: { apiId?: string; groupName?: string } = {};\n if (apiId !== undefined) result.apiId = apiId;\n if (groupName !== undefined) result.groupName = groupName;\n return result;\n}\n\n/**\n * Analyze a file for Effect platform usage.\n */\nexport function analyzePlatformUsage(\n filePath: string,\n source?: string,\n): PlatformUsageAnalysis {\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = source\n ? project.createSourceFile(filePath, source)\n : project.addSourceFileAtPath(filePath);\n const locations = new Map<string, SourceLocation>();\n const http = {\n client: false,\n server: false,\n routes: [] as string[],\n api: false,\n apiBuilder: false,\n endpoint: false,\n security: false,\n middleware: false,\n };\n const filesystem = { reads: [] as string[], writes: [] as string[] };\n let sockets = false;\n let terminal = false;\n let workers = false;\n const commands: string[] = [];\n let keyValueStore = false;\n let multipart = false;\n const codecs: string[] = [];\n let openApi = false;\n const platforms: ('node' | 'bun' | 'browser')[] = [];\n const fileSystemOps: { op: string; location: SourceLocation }[] = [];\n const commandOps: { op: string; location: SourceLocation }[] = [];\n const routeDefinitions: {\n method: string;\n name: string;\n path: string;\n location: SourceLocation;\n apiId?: string;\n groupName?: string;\n }[] = [];\n const middlewareChain: { name: string; location: SourceLocation }[] = [];\n const cliCommands: { name: string; hasSchema: boolean; location: SourceLocation }[] = [];\n\n for (const node of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression().getText();\n if (\n expr.includes('HttpClient') ||\n expr.includes('HttpServer') ||\n expr.includes('HttpRouter') ||\n expr.includes('HttpApi') ||\n expr.includes('HttpApiBuilder') ||\n expr.includes('HttpApiEndpoint') ||\n expr.includes('HttpApiGroup') ||\n expr.includes('HttpApiSecurity') ||\n expr.includes('HttpApiClient')\n ) {\n if (expr.includes('HttpClient') || expr.includes('HttpApiClient')) http.client = true;\n http.server = http.server || expr.includes('HttpServer') || expr.includes('HttpRouter');\n http.api = http.api || (expr.includes('HttpApi') && !expr.includes('HttpApiBuilder') && !expr.includes('HttpApiEndpoint') && !expr.includes('HttpApiGroup') && !expr.includes('HttpApiSecurity') && !expr.includes('HttpApiClient'));\n http.apiBuilder = http.apiBuilder || expr.includes('HttpApiBuilder');\n http.endpoint = http.endpoint || expr.includes('HttpApiEndpoint') || expr.includes('HttpApiGroup');\n http.security = http.security || expr.includes('HttpApiSecurity');\n http.middleware = http.middleware || expr.includes('middleware') || expr.includes('Middleware');\n if (expr.includes('route') || expr.includes('.get') || expr.includes('.post') || expr.includes('.put') || expr.includes('.delete') || expr.includes('.patch')) {\n http.routes.push(expr);\n }\n locations.set('http', getLoc(filePath, node, sf));\n }\n if (expr.includes('FileSystem')) {\n if (expr.includes('read')) filesystem.reads.push(expr);\n if (expr.includes('write')) filesystem.writes.push(expr);\n locations.set('filesystem', getLoc(filePath, node, sf));\n const fsOps: Record<string, string> = { readFile: 'read', readFileString: 'read', writeFile: 'write', writeFileString: 'write', remove: 'delete', mkdir: 'mkdir', stat: 'stat', copy: 'copy', rename: 'rename', readDirectory: 'readDir' };\n for (const [method, op] of Object.entries(fsOps)) {\n if (expr.includes(method)) { fileSystemOps.push({ op, location: getLoc(filePath, node, sf) }); break; }\n }\n }\n if (expr.includes('Socket') || expr.includes('fromNetServer')) sockets = true;\n if (expr.includes('Terminal')) terminal = true;\n if (expr.includes('Worker')) workers = true;\n if (expr.includes('Command.')) {\n commands.push(expr);\n const cmdOps: Record<string, string> = { make: 'make', start: 'start', stdin: 'stdin', stdout: 'stdout', stderr: 'stderr', exitCode: 'exitCode' };\n for (const [method, op] of Object.entries(cmdOps)) {\n if (expr.includes(method)) { commandOps.push({ op, location: getLoc(filePath, node, sf) }); break; }\n }\n }\n if (expr.includes('KeyValueStore')) keyValueStore = true;\n if (expr.includes('Multipart')) multipart = true;\n if (\n expr.includes('Ndjson') ||\n expr.includes('MsgPack') ||\n expr.includes('Effectify')\n ) {\n codecs.push(expr);\n }\n if (expr.includes('OpenApi') || expr.includes('OpenApiJsonSchema')) {\n openApi = true;\n }\n // Route definitions from HttpApiEndpoint\n if (expr.includes('HttpApiEndpoint')) {\n const methods = ['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as const;\n for (const m of methods) {\n if (expr.includes(`.${m}`)) {\n const args = node.getArguments();\n const nameArg = args.length > 0 ? args[0]?.getText().replace(/[\"'`]/g, '') : 'unnamed';\n const name = nameArg ?? 'unnamed';\n let path = '/';\n if (args.length >= 2) {\n path = args[1]?.getText().replace(/[\"'`]/g, '') ?? '/';\n } else {\n const parent = node.getParent();\n if (parent?.getKind() === SyntaxKind.TaggedTemplateExpression) {\n const template = (parent as TaggedTemplateExpression).getTemplate();\n path = extractPathFromTemplate(template);\n }\n }\n const ctx = walkAddChainForApiContext(node);\n routeDefinitions.push({\n method: m.toUpperCase(),\n name,\n path: path || '/',\n location: getLoc(filePath, node, sf),\n ...(ctx.apiId !== undefined ? { apiId: ctx.apiId } : {}),\n ...(ctx.groupName !== undefined ? { groupName: ctx.groupName } : {}),\n });\n break;\n }\n }\n }\n // Middleware detection\n if (expr.includes('middleware') || expr.includes('Middleware')) {\n const mwName = expr.replace(/.*\\./, '').replace(/\\(.*/, '');\n if (mwName) middlewareChain.push({ name: mwName, location: getLoc(filePath, node, sf) });\n }\n // CLI commands\n if (expr.includes('Command.make') || expr.includes('Prompt.')) {\n const args = node.getArguments();\n const nameArg = args.length > 0 ? args[0]?.getText().replace(/[\"'`]/g, '') : 'unnamed';\n const hasSchema = args.some(a => a.getText().includes('Schema'));\n cliCommands.push({ name: nameArg ?? 'unnamed', hasSchema, location: getLoc(filePath, node, sf) });\n }\n }\n\n if (\n http.client ||\n http.server ||\n http.api ||\n filesystem.reads.length > 0 ||\n filesystem.writes.length > 0\n ) {\n if (!platforms.includes('node')) platforms.push('node');\n }\n if (workers || multipart) {\n if (!platforms.includes('browser')) platforms.push('browser');\n }\n\n return {\n platforms,\n modules: {\n http: { ...http, routes: [...new Set(http.routes)] },\n filesystem: { reads: [...new Set(filesystem.reads)], writes: [...new Set(filesystem.writes)] },\n sockets,\n terminal,\n workers,\n commands: [...new Set(commands)],\n keyValueStore,\n multipart,\n codecs: [...new Set(codecs)],\n openApi,\n },\n locations,\n ...(fileSystemOps.length > 0 ? { fileSystemOps } : {}),\n ...(commandOps.length > 0 ? { commandOps } : {}),\n ...(routeDefinitions.length > 0 ? { routeDefinitions } : {}),\n ...(middlewareChain.length > 0 ? { middlewareChain } : {}),\n ...(cliCommands.length > 0 ? { cliCommands } : {}),\n };\n}\n","/**\n * HttpApi Structure Extractor\n *\n * Extracts HttpApi, HttpApiGroup, and HttpApiEndpoint structure from @effect/platform\n * source code for API documentation generation.\n */\n\nimport {\n SyntaxKind,\n type SourceFile,\n type Node,\n type CallExpression,\n type TemplateLiteral,\n type TaggedTemplateExpression,\n type PropertyAccessExpression,\n type Identifier,\n type VariableDeclaration,\n type ObjectLiteralExpression,\n type PropertyAssignment,\n} from 'ts-morph';\nimport type { SourceLocation } from './types';\nimport { schemaToJsonSchema, type JsonSchemaObject } from './schema-to-json-schema';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface HttpApiEndpointInfo {\n readonly name: string;\n readonly method: string;\n readonly path: string;\n readonly location: SourceLocation;\n readonly description?: string;\n readonly summary?: string;\n readonly deprecated?: boolean;\n readonly excluded?: boolean;\n /** Request body schema (from .setPayload) as OpenAPI JSON Schema */\n readonly requestSchema?: JsonSchemaObject;\n /** Success response schema (from .addSuccess) as OpenAPI JSON Schema */\n readonly responseSchema?: JsonSchemaObject;\n /** URL/query params schema (from .setUrlParams) as OpenAPI JSON Schema */\n readonly urlParamsSchema?: JsonSchemaObject;\n}\n\nexport interface HttpApiGroupInfo {\n readonly name: string;\n readonly endpoints: readonly HttpApiEndpointInfo[];\n readonly description?: string;\n readonly topLevel?: boolean;\n readonly prefix?: string;\n}\n\nexport interface HttpApiStructure {\n readonly apiId: string;\n readonly filePath: string;\n readonly groups: readonly HttpApiGroupInfo[];\n readonly prefix?: string;\n}\n\n// =============================================================================\n// Helpers\n// =============================================================================\n\nfunction getLoc(\n filePath: string,\n node: { getStart: () => number },\n sf: { getLineAndColumnAtPos: (p: number) => { line: number; column: number } },\n): SourceLocation {\n const { line, column } = sf.getLineAndColumnAtPos(node.getStart());\n return { filePath, line: line + 1, column };\n}\n\nfunction extractPathFromTemplate(\n template: TemplateLiteral,\n): string {\n const rawText = template.getText();\n const withParams = rawText\n .replace(/\\$\\{HttpApiSchema\\.param\\s*\\(\\s*[\"'](\\w+)[\"'][^}]*\\)\\}/g, ':$1')\n .replace(/\\$\\{[^}]*\\}/g, ':param');\n const path = withParams.replace(/^`|`$/g, '').trim();\n return path.startsWith('/') ? path : `/${path}`;\n}\n\nfunction extractAnnotations(node: CallExpression, _sf: SourceFile, _filePath: string): {\n description?: string;\n summary?: string;\n deprecated?: boolean;\n excluded?: boolean;\n} {\n const result: { description?: string; summary?: string; deprecated?: boolean; excluded?: boolean } = {};\n let current: Node | undefined = node;\n for (let i = 0; i < 30 && current; i++) {\n const parent = current.getParent();\n if (parent?.getKind() !== SyntaxKind.CallExpression) {\n current = parent;\n continue;\n }\n const call = parent as CallExpression;\n const callee = call.getExpression().getText();\n const args = call.getArguments();\n if (args.length < 2) {\n current = parent;\n continue;\n }\n const tagArg = args[0]?.getText();\n const valueArg = args[1]?.getText();\n if (callee.endsWith('.annotate') || callee.endsWith('.annotateContext')) {\n if (tagArg?.includes('OpenApi.Description') || tagArg?.includes('Description')) {\n const v = valueArg?.replace(/^[\"']|[\"']$/g, '');\n if (v) result.description = v;\n } else if (tagArg?.includes('OpenApi.Summary') || tagArg?.includes('Summary')) {\n const v = valueArg?.replace(/^[\"']|[\"']$/g, '');\n if (v) result.summary = v;\n } else if (tagArg?.includes('OpenApi.Deprecated') || tagArg?.includes('Deprecated')) {\n result.deprecated = valueArg === 'true';\n } else if (tagArg?.includes('OpenApi.Exclude') || tagArg?.includes('Exclude')) {\n result.excluded = valueArg === 'true';\n }\n }\n current = parent;\n }\n return result;\n}\n\nfunction extractEndpointSchemas(\n endpointBase: CallExpression,\n sf: SourceFile,\n): { requestSchema?: JsonSchemaObject; responseSchema?: JsonSchemaObject; urlParamsSchema?: JsonSchemaObject } {\n const result: {\n requestSchema?: JsonSchemaObject;\n responseSchema?: JsonSchemaObject;\n urlParamsSchema?: JsonSchemaObject;\n } = {};\n const project = sf.getProject();\n let current: Node | undefined = endpointBase;\n for (let i = 0; i < 40 && current; i++) {\n const parent = current.getParent();\n if (parent?.getKind() !== SyntaxKind.CallExpression) {\n current = parent;\n continue;\n }\n const call = parent as CallExpression;\n const callee = call.getExpression().getText();\n const args = call.getArguments();\n if (args.length < 1) {\n current = parent;\n continue;\n }\n const schemaArg = args[0];\n if (callee.endsWith('.addSuccess') && schemaArg && !result.responseSchema) {\n const json = schemaToJsonSchema(schemaArg, sf, project);\n if (json) result.responseSchema = json;\n } else if (callee.endsWith('.setPayload') && schemaArg && !result.requestSchema) {\n const json = schemaToJsonSchema(schemaArg, sf, project);\n if (json) result.requestSchema = json;\n } else if (\n (callee.endsWith('.setUrlParams') || callee.endsWith('.setQueryParams')) &&\n schemaArg &&\n !result.urlParamsSchema\n ) {\n const json = schemaToJsonSchema(schemaArg, sf, project);\n if (json) result.urlParamsSchema = json;\n }\n current = parent;\n }\n return result;\n}\n\nfunction extractEndpoint(\n node: CallExpression,\n method: string,\n sf: SourceFile,\n filePath: string,\n): HttpApiEndpointInfo | null {\n const args = node.getArguments();\n const nameArg = args.length > 0 ? args[0]?.getText().replace(/[\"'`]/g, '') : 'unnamed';\n const name = nameArg ?? 'unnamed';\n let path = '/';\n if (args.length >= 2) {\n path = args[1]?.getText().replace(/[\"'`]/g, '') ?? '/';\n } else {\n const parent = node.getParent();\n if (parent?.getKind() === SyntaxKind.TaggedTemplateExpression) {\n const template = (parent as TaggedTemplateExpression).getTemplate();\n path = extractPathFromTemplate(template);\n }\n }\n const annotations = extractAnnotations(node, sf, filePath);\n if (annotations.excluded) return null;\n const schemas = extractEndpointSchemas(node, sf);\n return {\n name,\n method: method.toUpperCase(),\n path: path || '/',\n location: getLoc(filePath, node, sf),\n ...(annotations.description ? { description: annotations.description } : {}),\n ...(annotations.summary ? { summary: annotations.summary } : {}),\n ...(annotations.deprecated ? { deprecated: true } : {}),\n ...(schemas.requestSchema ? { requestSchema: schemas.requestSchema } : {}),\n ...(schemas.responseSchema ? { responseSchema: schemas.responseSchema } : {}),\n ...(schemas.urlParamsSchema ? { urlParamsSchema: schemas.urlParamsSchema } : {}),\n };\n}\n\nfunction collectEndpointsFromGroup(groupMakeNode: CallExpression, sf: SourceFile, filePath: string): HttpApiEndpointInfo[] {\n const endpoints: HttpApiEndpointInfo[] = [];\n const methods = ['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as const;\n const seen = new Set<string>();\n\n const addArgs = collectAddArgsFromChain(groupMakeNode);\n\n function findEndpointBase(call: CallExpression): CallExpression | undefined {\n let current: Node = call;\n const schemaMethods = ['.annotate', '.addSuccess', '.setPayload', '.setUrlParams', '.setQueryParams', '.addFailure'];\n for (let i = 0; i < 15; i++) {\n if (current.getKind() !== SyntaxKind.CallExpression) return undefined;\n const c = current as CallExpression;\n const expr = c.getExpression().getText();\n for (const m of methods) {\n const hasMethod = expr.includes(`HttpApiEndpoint.${m}`) || expr.includes(`HttpApiEndpoint.${m}(`);\n const notChained = !schemaMethods.some((s) => expr.endsWith(s) || expr.includes(s));\n if (hasMethod && !expr.includes('.annotate') && notChained) {\n return c;\n }\n }\n const isChained = schemaMethods.some((s) => expr.endsWith(s) || expr.includes(s));\n if (isChained) {\n const receiver = c.getExpression();\n if (receiver.getKind() === SyntaxKind.CallExpression) {\n current = receiver as CallExpression;\n } else {\n current = (receiver as PropertyAccessExpression).getExpression();\n }\n continue;\n }\n return undefined;\n }\n return undefined;\n }\n\n function resolveToEndpointOrAdd(n: Node): Node | undefined {\n if (n.getKind() === SyntaxKind.CallExpression) return n;\n if (n.getKind() === SyntaxKind.Identifier) {\n const name = (n as Identifier).getText();\n const symbol = (n as Identifier).getSymbol();\n const decls = symbol?.getDeclarations() ?? symbol?.getAliasedSymbol()?.getDeclarations() ?? [];\n for (const decl of decls) {\n if (decl.getKind() === SyntaxKind.VariableDeclaration) {\n const init = (decl as VariableDeclaration).getInitializer();\n if (init) return init;\n }\n }\n const vars = sf.getVariableDeclarations();\n for (const v of vars) {\n if (v.getName() === name) {\n const init = v.getInitializer();\n if (init) return init;\n }\n }\n }\n return undefined;\n }\n\n function visit(n: Node) {\n const resolved = resolveToEndpointOrAdd(n);\n if (resolved?.getKind() !== SyntaxKind.CallExpression) return;\n const call = resolved as CallExpression;\n const base = findEndpointBase(call);\n if (base) {\n const expr = base.getExpression().getText();\n for (const m of methods) {\n if (expr.includes(`HttpApiEndpoint.${m}`)) {\n const ep = extractEndpoint(base, m, sf, filePath);\n if (ep && !seen.has(`${ep.method}:${ep.path}:${ep.name}`)) {\n seen.add(`${ep.method}:${ep.path}:${ep.name}`);\n endpoints.push(ep);\n }\n return;\n }\n }\n }\n const expr = call.getExpression().getText();\n if (expr.endsWith('.add')) {\n for (const arg of call.getArguments()) {\n visit(arg);\n }\n }\n }\n\n for (const arg of addArgs) {\n visit(arg);\n }\n return endpoints;\n}\n\nfunction extractGroupInfo(\n groupCall: CallExpression,\n sf: SourceFile,\n filePath: string,\n groupPrefix?: string,\n): HttpApiGroupInfo | null {\n const args = groupCall.getArguments();\n const nameArg = args.length > 0 ? args[0]?.getText().replace(/[\"'`]/g, '') : 'group';\n const name = nameArg ?? 'group';\n const optsArg = args[1];\n let topLevel = false;\n if (optsArg?.getKind() === SyntaxKind.ObjectLiteralExpression) {\n const obj = optsArg as ObjectLiteralExpression;\n const topLevelProp = obj.getProperty('topLevel');\n if (topLevelProp?.getKind() === SyntaxKind.PropertyAssignment) {\n const init = (topLevelProp as PropertyAssignment).getInitializer();\n topLevel = init?.getText() === 'true';\n }\n }\n const endpoints = collectEndpointsFromGroup(groupCall, sf, filePath);\n const annotations = extractAnnotations(groupCall, sf, filePath);\n return {\n name,\n endpoints,\n ...(annotations.description ? { description: annotations.description } : {}),\n ...(topLevel ? { topLevel: true } : {}),\n ...(groupPrefix ? { prefix: groupPrefix } : {}),\n };\n}\n\nfunction extractPrefixFromChain(call: CallExpression): string | undefined {\n let current: Node | undefined = call;\n for (let i = 0; i < 25; i++) {\n if (current.getKind() !== SyntaxKind.CallExpression) break;\n const c = current as CallExpression;\n const expr = c.getExpression().getText();\n if (expr.endsWith('.prefix')) {\n const args = c.getArguments();\n if (args.length >= 1) {\n const path = args[0]?.getText().replace(/[\"'`]/g, '');\n if (path) return path.startsWith('/') ? path : `/${path}`;\n }\n break;\n }\n const receiver = c.getExpression();\n if (receiver.getKind() === SyntaxKind.PropertyAccessExpression) {\n current = (receiver as PropertyAccessExpression).getExpression();\n } else {\n break;\n }\n }\n return undefined;\n}\n\n/** Find the topmost .add() in the chain that contains the make, then collect all add args. */\nfunction collectAddArgsFromChain(makeNode: CallExpression): Node[] {\n const args: Node[] = [];\n let topAdd: CallExpression | undefined;\n let current: Node = makeNode;\n const makeExpr = makeNode.getExpression().getText();\n const isApiMake = makeExpr.includes('HttpApi.make');\n const isGroupMake = makeExpr.includes('HttpApiGroup.make');\n for (let i = 0; i < 20; i++) {\n let parent: Node | undefined = current.getParent();\n if (!parent) break;\n if (parent.getKind() === SyntaxKind.PropertyAccessExpression) {\n parent = parent.getParent();\n }\n if (parent?.getKind() !== SyntaxKind.CallExpression) break;\n const call = parent as CallExpression;\n const callee = call.getExpression().getText();\n if (callee.endsWith('.add')) {\n if (isApiMake && callee.includes('HttpApiGroup.make')) break;\n if (isGroupMake && callee.includes('HttpApi.make') && !callee.includes('HttpApiGroup')) break;\n topAdd = call;\n current = parent;\n continue;\n }\n break;\n }\n if (!topAdd) return args;\n current = topAdd;\n for (let i = 0; i < 50; i++) {\n if (current.getKind() === SyntaxKind.CallExpression) {\n const call = current as CallExpression;\n const callee = call.getExpression().getText();\n if (callee.endsWith('.add')) {\n for (const arg of call.getArguments()) {\n args.push(arg);\n }\n const receiver = call.getExpression();\n if (receiver.getKind() === SyntaxKind.CallExpression) {\n current = receiver as CallExpression;\n continue;\n }\n if (receiver.getKind() === SyntaxKind.PropertyAccessExpression) {\n const inner = (receiver as PropertyAccessExpression).getExpression();\n if (inner.getKind() === SyntaxKind.CallExpression) {\n current = inner as CallExpression;\n continue;\n }\n }\n }\n }\n break;\n }\n return args;\n}\n\nfunction collectGroupsFromApiRoot(\n makeNode: CallExpression,\n sf: SourceFile,\n filePath: string,\n): HttpApiGroupInfo[] {\n const groups: HttpApiGroupInfo[] = [];\n const seen = new Set<string>();\n\n const addArgs = collectAddArgsFromChain(makeNode);\n\n const chainMethods = ['.add', '.prefix', '.annotate'];\n function getMakeFromAddChain(call: CallExpression): CallExpression | undefined {\n let current: Node = call;\n for (let i = 0; i < 20; i++) {\n if (current.getKind() !== SyntaxKind.CallExpression) return undefined;\n const c = current as CallExpression;\n const expr = c.getExpression().getText();\n if (expr.includes('HttpApiGroup.make') && !chainMethods.some((m) => expr.endsWith(m))) return c;\n if (expr.includes('HttpApi.make') && !chainMethods.some((m) => expr.endsWith(m))) return c;\n if (chainMethods.some((m) => expr.endsWith(m))) {\n const receiver = c.getExpression();\n if (receiver.getKind() === SyntaxKind.CallExpression) {\n current = receiver as CallExpression;\n continue;\n }\n if (receiver.getKind() === SyntaxKind.PropertyAccessExpression) {\n const inner = (receiver as PropertyAccessExpression).getExpression();\n if (inner.getKind() === SyntaxKind.CallExpression) {\n current = inner as CallExpression;\n continue;\n }\n }\n return undefined;\n }\n return undefined;\n }\n return undefined;\n }\n\n function resolveToGroupOrApi(arg: Node): CallExpression | undefined {\n if (arg.getKind() === SyntaxKind.CallExpression) return arg as CallExpression;\n if (arg.getKind() === SyntaxKind.Identifier) {\n const name = (arg as Identifier).getText();\n const symbol = (arg as Identifier).getSymbol();\n const decls = symbol?.getDeclarations() ?? symbol?.getAliasedSymbol()?.getDeclarations() ?? [];\n for (const decl of decls) {\n if (decl.getKind() === SyntaxKind.VariableDeclaration) {\n const init = (decl as VariableDeclaration).getInitializer();\n if (init?.getKind() === SyntaxKind.CallExpression) return init as CallExpression;\n }\n }\n const vars = sf.getVariableDeclarations();\n for (const v of vars) {\n if (v.getName() === name) {\n const init = v.getInitializer();\n if (init?.getKind() === SyntaxKind.CallExpression) return init as CallExpression;\n }\n }\n }\n return undefined;\n }\n\n function processArg(arg: Node) {\n const call = resolveToGroupOrApi(arg);\n if (!call) return;\n const expr = call.getExpression().getText();\n if (expr.includes('HttpApiGroup.make')) {\n const makeNode = getMakeFromAddChain(call);\n if (makeNode) {\n const groupPrefix = extractPrefixFromChain(call);\n const group = extractGroupInfo(makeNode, sf, filePath, groupPrefix);\n if (group && !seen.has(group.name)) {\n seen.add(group.name);\n groups.push(group);\n }\n }\n return;\n }\n if (expr.includes('HttpApi.make')) {\n const makeNode = getMakeFromAddChain(call);\n if (makeNode) {\n for (const a of collectAddArgsFromChain(makeNode)) {\n processArg(a);\n }\n }\n }\n }\n\n for (const arg of addArgs) {\n processArg(arg);\n }\n return groups;\n}\n\nfunction findApiRootFromMake(makeNode: CallExpression): CallExpression {\n let current: Node | undefined = makeNode;\n for (let i = 0; i < 50; i++) {\n const parent = current.getParent();\n if (parent?.getKind() !== SyntaxKind.CallExpression) return makeNode;\n const call = parent as CallExpression;\n const callee = call.getExpression().getText();\n if (callee.endsWith('.add')) {\n const receiver = call.getExpression();\n if (receiver.getKind() === SyntaxKind.CallExpression) {\n const recCall = receiver as CallExpression;\n const recExpr = recCall.getExpression().getText();\n if (recExpr.includes('HttpApi.make')) {\n current = recCall;\n continue;\n }\n }\n }\n break;\n }\n return current as CallExpression;\n}\n\n// =============================================================================\n// Main API\n// =============================================================================\n\n/**\n * Extract HttpApi structure from a source file.\n * Returns all HttpApi.make(...) declarations with their groups and endpoints.\n */\nexport function extractHttpApiStructure(\n sourceFile: SourceFile,\n filePath: string,\n): HttpApiStructure[] {\n const results: HttpApiStructure[] = [];\n const filePathResolved = filePath || sourceFile.getFilePath();\n const seenApiIds = new Set<string>();\n\n for (const node of sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression().getText();\n if (!expr.includes('HttpApi.make') || expr.includes('HttpApiBuilder')) continue;\n if (expr.includes('.add')) continue;\n const args = (node).getArguments();\n const apiId = args.length > 0 ? args[0]?.getText().replace(/[\"'`]/g, '') : undefined;\n if (!apiId) continue;\n if (seenApiIds.has(apiId)) continue;\n const root = findApiRootFromMake(node);\n const groups = collectGroupsFromApiRoot(root, sourceFile, filePathResolved);\n seenApiIds.add(apiId);\n results.push({ apiId, filePath: filePathResolved, groups });\n }\n\n return results;\n}\n","/**\n * Effect Schema AST → OpenAPI JSON Schema\n *\n * Walks Effect Schema expressions in the AST and produces OpenAPI-compatible\n * JSON Schema (no $schema, suitable for OpenAPI components.schemas).\n */\n\nimport {\n SyntaxKind,\n type SourceFile,\n type Node,\n type CallExpression,\n type ObjectLiteralExpression,\n type Project,\n type Identifier,\n type VariableDeclaration,\n type PropertyAssignment,\n type ImportSpecifier,\n} from 'ts-morph';\nimport { resolveModulePath } from './alias-resolution';\n\nexport type JsonSchemaObject = Record<string, unknown>;\n\n/**\n * Resolve a node (identifier or expression) to the Schema definition.\n * Handles: Schema.Struct(...), variable references, imported names.\n */\nfunction resolveSchemaNode(\n node: Node,\n sf: SourceFile,\n project: Project,\n): Node | undefined {\n const text = node.getText();\n // Direct Schema.* call\n if (text.includes('Schema.')) return node;\n // Identifier - resolve to declaration (handles local vars and imports)\n if (node.getKind() === SyntaxKind.Identifier) {\n const ident = node as Identifier;\n const symbol = ident.getSymbol();\n const aliased = symbol?.getAliasedSymbol() ?? symbol;\n const decls = aliased?.getDeclarations() ?? [];\n for (const decl of decls) {\n if (decl.getKind() === SyntaxKind.VariableDeclaration) {\n const init = (decl as VariableDeclaration).getInitializer();\n if (init?.getText().includes('Schema.')) return init;\n }\n if (decl.getKind() === SyntaxKind.ImportSpecifier) {\n const exportName = (decl as ImportSpecifier).getName();\n const importDecl = decl.getFirstAncestorByKind(SyntaxKind.ImportDeclaration);\n if (importDecl) {\n const spec = importDecl.getModuleSpecifierValue();\n const currentPath = sf.getFilePath();\n const resolvedPath = spec.startsWith('.') ? resolveModulePath(currentPath, spec) : undefined;\n const targetSf = resolvedPath ? project.getSourceFile(resolvedPath) : undefined;\n if (targetSf) {\n const expDecls = targetSf.getExportedDeclarations().get(exportName) ?? [];\n for (const ed of expDecls) {\n if (ed.getKind() === SyntaxKind.VariableDeclaration) {\n const init = (ed as VariableDeclaration).getInitializer();\n if (init?.getText().includes('Schema.')) return init;\n }\n }\n }\n }\n }\n }\n // Fallback: search in same file for const/export const\n const name = ident.getText();\n const vars = sf.getVariableDeclarations();\n for (const v of vars) {\n if (v.getName() === name) {\n const init = v.getInitializer();\n if (init?.getText().includes('Schema.')) return init;\n }\n }\n }\n return node.getText().includes('Schema.') ? node : undefined;\n}\n\n/**\n * Extract OpenAPI JSON Schema from an Effect Schema AST node.\n */\nexport function schemaToJsonSchema(\n node: Node,\n sf: SourceFile,\n project: Project,\n defs?: Map<string, JsonSchemaObject>,\n): JsonSchemaObject | undefined {\n const resolved = resolveSchemaNode(node, sf, project);\n if (!resolved) return undefined;\n return walkSchema(resolved, sf, project, defs ?? new Map<string, JsonSchemaObject>());\n}\n\nfunction walkSchema(\n node: Node,\n sf: SourceFile,\n project: Project,\n defs: Map<string, JsonSchemaObject>,\n): JsonSchemaObject | undefined {\n const text = node.getText();\n\n // Check composite types first (they contain primitive names)\n // Schema.Array\n if (text.includes('Schema.Array')) {\n const call =\n node.getKind() === SyntaxKind.CallExpression\n ? (node as CallExpression)\n : node.getFirstDescendantByKind(SyntaxKind.CallExpression);\n if (call) {\n const args = call.getArguments();\n const itemSchema = args[0] ? walkSchema(args[0], sf, project, defs) : undefined;\n return {\n type: 'array',\n items: itemSchema ?? {},\n };\n }\n }\n\n // Schema.Struct\n if (text.includes('Schema.Struct')) {\n const call =\n node.getKind() === SyntaxKind.CallExpression\n ? (node as CallExpression)\n : node.getFirstDescendantByKind(SyntaxKind.CallExpression);\n if (!call) return { type: 'object' };\n const args = call.getArguments();\n const objArg = args[0];\n if (objArg?.getKind() !== SyntaxKind.ObjectLiteralExpression) {\n return { type: 'object' };\n }\n const obj = objArg as ObjectLiteralExpression;\n const properties: Record<string, JsonSchemaObject> = {};\n const required: string[] = [];\n for (const prop of obj.getProperties()) {\n if (prop.getKind() !== SyntaxKind.PropertyAssignment) continue;\n const pa = prop as PropertyAssignment;\n const name = (pa.getNameNode() as Identifier).getText();\n const init = pa.getInitializer();\n if (!init) continue;\n const propText = init.getText();\n const isOptional = propText.includes('Schema.optional') || propText.includes('.optional');\n if (!isOptional) required.push(name);\n const propSchema = walkSchema(init, sf, project, defs);\n if (propSchema) properties[name] = propSchema;\n }\n const result: JsonSchemaObject = {\n type: 'object',\n properties: Object.keys(properties).length ? properties : undefined,\n additionalProperties: false,\n };\n if (required.length) result.required = required;\n return result;\n }\n\n // Schema.Union\n if (text.includes('Schema.Union')) {\n const call =\n node.getKind() === SyntaxKind.CallExpression\n ? (node as CallExpression)\n : node.getFirstDescendantByKind(SyntaxKind.CallExpression);\n if (call) {\n const args = call.getArguments();\n const oneOf = args\n .map((a) => walkSchema(a, sf, project, defs))\n .filter((s): s is JsonSchemaObject => s !== undefined);\n if (oneOf.length) return { oneOf };\n }\n }\n\n // Schema.optional\n if (text.includes('Schema.optional') || text.includes('.pipe(Schema.optional')) {\n const call =\n node.getKind() === SyntaxKind.CallExpression\n ? (node as CallExpression)\n : node.getFirstDescendantByKind(SyntaxKind.CallExpression);\n if (call) {\n const args = call.getArguments();\n const inner = args[0] ? walkSchema(args[0], sf, project, defs) : undefined;\n if (inner) return { ...inner, nullable: true };\n }\n }\n\n // Schema.Record\n if (text.includes('Schema.Record')) {\n const call =\n node.getKind() === SyntaxKind.CallExpression\n ? (node as CallExpression)\n : node.getFirstDescendantByKind(SyntaxKind.CallExpression);\n if (call) {\n const args = call.getArguments();\n const valueSchema = args[1] ? walkSchema(args[1], sf, project, defs) : undefined;\n return {\n type: 'object',\n additionalProperties: valueSchema ?? true,\n };\n }\n }\n\n // Schema.Tuple\n if (text.includes('Schema.Tuple')) {\n const call =\n node.getKind() === SyntaxKind.CallExpression\n ? (node as CallExpression)\n : node.getFirstDescendantByKind(SyntaxKind.CallExpression);\n if (call) {\n const args = call.getArguments();\n const items = args.map((a) => walkSchema(a, sf, project, defs)).filter(Boolean);\n return { type: 'array', items: items as JsonSchemaObject[] };\n }\n }\n\n // Schema.DateFromString, Schema.DateTimeUtc, etc.\n if (\n text.includes('Schema.Date') ||\n text.includes('Schema.DateTimeUtc') ||\n text.includes('Schema.Instant')\n ) {\n return { type: 'string', format: 'date-time' };\n }\n\n // Primitives (check after composites)\n if (text.includes('Schema.String') && !text.includes('Schema.Struct')) {\n return { type: 'string' };\n }\n if (\n text.includes('Schema.Number') ||\n text.includes('Schema.Int') ||\n text.includes('Schema.Positive') ||\n text.includes('Schema.NonNegative') ||\n text.includes('Schema.Finite')\n ) {\n return { type: 'number' };\n }\n if (text.includes('Schema.Boolean')) return { type: 'boolean' };\n if (text.includes('Schema.Null')) return { type: 'null' };\n const literalMatch = /Schema\\.Literal\\s*\\(\\s*([\"'])([^\"']*)\\1\\s*\\)/.exec(text);\n if (literalMatch) return { type: 'string', enum: [literalMatch[2]] };\n const literalNumMatch = /Schema\\.Literal\\s*\\(\\s*(\\d+)\\s*\\)/.exec(text);\n if (literalNumMatch) return { type: 'number', enum: [Number(literalNumMatch[1])] };\n const literalBoolMatch = /Schema\\.Literal\\s*\\(\\s*(true|false)\\s*\\)/.exec(text);\n if (literalBoolMatch) return { type: 'boolean', enum: [literalBoolMatch[1] === 'true'] };\n\n // Variable reference - already resolved by resolveSchemaNode, recurse\n if (node.getKind() === SyntaxKind.Identifier) {\n const symbol = (node as Identifier).getSymbol();\n const decl = symbol?.getDeclarations()[0];\n const init = (decl as VariableDeclaration).getInitializer();\n if (init) return walkSchema(init, sf, project, defs);\n }\n\n return undefined;\n}\n","/**\n * API Documentation Output\n *\n * Renders HttpApi structure as markdown and OpenAPI paths.\n */\n\nimport type { HttpApiStructure } from '../http-api-extractor';\n\n/**\n * Render API docs as markdown with H1 per API, H2 per group, and endpoint table.\n */\nexport function renderApiDocsMarkdown(structures: readonly HttpApiStructure[]): string {\n const lines: string[] = [];\n for (const api of structures) {\n lines.push(`# API: ${api.apiId}`);\n lines.push('');\n const apiPrefix = api.prefix ?? '';\n for (const group of api.groups) {\n lines.push(`## ${group.name}`);\n if (group.description) {\n lines.push('');\n lines.push(group.description);\n lines.push('');\n }\n lines.push('');\n lines.push('| Method | Path | Name | Description |');\n lines.push('|--------|------|------|-------------|');\n const groupPrefix = group.prefix ?? '';\n for (const ep of group.endpoints) {\n const fullPath = apiPrefix + groupPrefix + ep.path;\n const desc = ep.description ?? ep.summary ?? '-';\n const dep = ep.deprecated ? ' (deprecated)' : '';\n lines.push(`| ${ep.method} | ${fullPath} | ${ep.name}${dep} | ${desc} |`);\n }\n lines.push('');\n }\n lines.push('');\n }\n return lines.join('\\n').trim();\n}\n\n/**\n * Render API structure as Mermaid flowchart (API -> groups -> endpoints).\n */\nexport function renderApiDocsMermaid(structures: readonly HttpApiStructure[]): string {\n const lines: string[] = ['flowchart TB'];\n let nodeId = 0;\n const ids = new Map<string, string>();\n const id = (prefix: string) => {\n const n = `${prefix}${nodeId++}`;\n ids.set(n, n);\n return n;\n };\n for (const api of structures) {\n const apiNode = id('api');\n lines.push(` ${apiNode}[\"${api.apiId}\"]`);\n for (const group of api.groups) {\n const groupNode = id('group');\n lines.push(` ${groupNode}[\"${group.name}\"]`);\n lines.push(` ${apiNode} --> ${groupNode}`);\n const apiPrefix = api.prefix ?? '';\n const groupPrefix = group.prefix ?? '';\n for (const ep of group.endpoints) {\n const epNode = id('ep');\n const fullPath = apiPrefix + groupPrefix + ep.path;\n lines.push(` ${epNode}[\"${ep.method} ${fullPath}\"]`);\n lines.push(` ${groupNode} --> ${epNode}`);\n }\n }\n }\n return lines.join('\\n');\n}\n\n/**\n * Render minimal OpenAPI paths object for merging into full spec.\n * Includes request/response schemas when extracted from Effect Schema.\n */\nexport function renderOpenApiPaths(structures: readonly HttpApiStructure[]): {\n paths: Record<\n string,\n Record<\n string,\n {\n operationId: string;\n summary?: string;\n deprecated?: boolean;\n requestBody?: { content: { 'application/json': { schema: unknown } } };\n responses?: Record<string, { content?: { 'application/json': { schema: unknown } }; description?: string }>;\n parameters?: { name: string; in: string; schema: unknown }[];\n }\n >\n >;\n} {\n const paths: Record<string, Record<string, unknown>> = {};\n for (const api of structures) {\n const apiPrefix = api.prefix ?? '';\n for (const group of api.groups) {\n const groupPrefix = group.prefix ?? '';\n for (const ep of group.endpoints) {\n const path = apiPrefix + groupPrefix + ep.path;\n paths[path] ??= {};\n const op = ep.method.toLowerCase();\n const pathOp: Record<string, unknown> = {\n operationId: `${group.name}.${ep.name}`,\n ...(ep.summary ? { summary: ep.summary } : {}),\n ...(ep.deprecated ? { deprecated: true } : {}),\n };\n if (ep.requestSchema) {\n pathOp.requestBody = {\n content: { 'application/json': { schema: ep.requestSchema } },\n };\n }\n if (ep.responseSchema) {\n pathOp.responses = {\n '200': {\n description: ep.summary ?? ep.description ?? 'Success',\n content: { 'application/json': { schema: ep.responseSchema } },\n },\n };\n }\n if (ep.urlParamsSchema?.properties) {\n const params = Object.entries(ep.urlParamsSchema.properties as Record<string, unknown>).map(\n ([name, schema]) => ({ name, in: 'path' as const, schema }),\n );\n if (params.length) pathOp.parameters = params;\n }\n paths[path][op] = pathOp;\n }\n }\n }\n return { paths } as ReturnType<typeof renderOpenApiPaths>;\n}\n","/**\n * Testing Pattern Analysis (GAP 16)\n *\n * Detects TestClock, TestContext, mock layers, and test entry points.\n */\n\nimport { Project, SyntaxKind } from 'ts-morph';\nimport type { SourceLocation } from './types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface TestingPatternAnalysis {\n readonly testClockUsed: boolean;\n readonly testContextUsed: boolean;\n readonly mockLayers: string[];\n readonly runInTests: boolean;\n readonly effectVitestUsed: boolean;\n readonly effectVitestImported: boolean;\n readonly sharedLayerUsed: boolean;\n readonly testAnnotationsUsed: boolean;\n readonly flakyTestUsed: boolean;\n readonly exitAssertionsUsed: boolean;\n readonly testServicesUsed: boolean;\n readonly fastCheckUsed: boolean;\n readonly propertyTestUsed: boolean;\n readonly locations: Map<string, SourceLocation>;\n}\n\nfunction getLoc(\n filePath: string,\n node: { getStart: () => number },\n sf: { getLineAndColumnAtPos: (p: number) => { line: number; column: number } },\n): SourceLocation {\n const { line, column } = sf.getLineAndColumnAtPos(node.getStart());\n return { filePath, line: line + 1, column };\n}\n\n/**\n * Analyze a file for Effect testing patterns.\n */\nexport function analyzeTestingPatterns(\n filePath: string,\n source?: string,\n): TestingPatternAnalysis {\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = source\n ? project.createSourceFile(filePath, source)\n : project.addSourceFileAtPath(filePath);\n const locations = new Map<string, SourceLocation>();\n let testClockUsed = false;\n let testContextUsed = false;\n const mockLayers: string[] = [];\n let runInTests = false;\n let effectVitestUsed = false;\n let effectVitestImported = false;\n let sharedLayerUsed = false;\n let testAnnotationsUsed = false;\n let flakyTestUsed = false;\n let exitAssertionsUsed = false;\n let testServicesUsed = false;\n let fastCheckUsed = false;\n let propertyTestUsed = false;\n\n // Check for @effect/vitest import and fast-check/fc imports\n for (const decl of sf.getImportDeclarations()) {\n const specifier = decl.getModuleSpecifierValue();\n if (specifier === '@effect/vitest' || specifier.includes('@effect/vitest')) {\n effectVitestImported = true;\n }\n if (specifier === 'fast-check' || specifier === 'fc' || specifier.includes('fast-check')) {\n fastCheckUsed = true;\n locations.set('fast-check', { filePath, line: 1, column: 0 });\n }\n }\n\n for (const node of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression().getText();\n const loc = getLoc(filePath, node, sf);\n if (expr.includes('TestClock') || expr.includes('TestContext')) {\n if (expr.includes('TestClock')) testClockUsed = true;\n if (expr.includes('TestContext')) testContextUsed = true;\n locations.set('test-context', getLoc(filePath, node, sf));\n }\n if (\n (expr.includes('Layer.succeed') || expr.includes('Layer.mock')) &&\n (node.getParent()?.getText().includes('test') || sf.getFilePath().includes('.test.'))\n ) {\n mockLayers.push(expr.slice(0, 60));\n locations.set('mock-layer', getLoc(filePath, node, sf));\n }\n if (\n expr.includes('Effect.runPromise') ||\n expr.includes('Effect.runSync') ||\n expr.includes('Effect.runPromiseExit') ||\n expr.includes('Effect.runSyncExit') ||\n expr.includes('runPromise') ||\n expr.includes('runSync')\n ) {\n if (sf.getFilePath().includes('.test.') || sf.getFilePath().includes('spec.')) runInTests = true;\n }\n if (\n expr.includes('it.effect') ||\n expr.includes('it.scoped') ||\n expr.includes('it.live') ||\n expr.includes('it.scopedLive') ||\n expr.includes('it.prop')\n ) {\n effectVitestUsed = true;\n if (expr.includes('it.prop')) propertyTestUsed = true;\n locations.set('effect-vitest', loc);\n }\n if (expr.includes('TestAnnotations')) {\n testAnnotationsUsed = true;\n locations.set('test-annotations', loc);\n }\n if (expr.includes('flakyTest')) {\n flakyTestUsed = true;\n locations.set('flaky-test', loc);\n }\n if (expr.includes('Exit.match') || expr.includes('Exit.isSuccess') || expr.includes('Exit.isFailure') || expr.includes('Exit.isInterrupted')) {\n exitAssertionsUsed = true;\n locations.set('exit-assertions', loc);\n }\n // Detect shared layer pattern: layer(MyLayer)(\"suite\", fn)\n if (\n (expr === 'layer' || expr.endsWith('.layer')) &&\n node.getParent()?.getText().includes('(')\n ) {\n sharedLayerUsed = true;\n locations.set('shared-layer', loc);\n }\n // TestServices.* — live/sized/annotations service overrides\n if (expr.includes('TestServices') || expr.includes('TestSized') || expr.includes('TestLive')) {\n testServicesUsed = true;\n locations.set('test-services', loc);\n }\n // FastCheck / Arbitrary usage\n if (\n expr.includes('fc.') ||\n expr.includes('FastCheck') ||\n expr.includes('Arbitrary.make') ||\n expr.includes('Arbitrary.filter') ||\n expr.includes('Arbitrary.from')\n ) {\n fastCheckUsed = true;\n locations.set('fast-check', loc);\n }\n // Property-based tests via it.prop or fc.property\n if (expr.includes('fc.property') || expr.includes('fc.asyncProperty')) {\n propertyTestUsed = true;\n locations.set('property-test', loc);\n }\n }\n\n return {\n testClockUsed,\n testContextUsed,\n mockLayers: [...new Set(mockLayers)],\n runInTests,\n effectVitestUsed,\n effectVitestImported,\n sharedLayerUsed,\n testAnnotationsUsed,\n flakyTestUsed,\n exitAssertionsUsed,\n testServicesUsed,\n fastCheckUsed,\n propertyTestUsed,\n locations,\n };\n}\n","/**\n * Effect Version Compatibility (GAP 25)\n *\n * Reads package.json for Effect version and flags deprecated API usage.\n */\n\nimport { readFile } from 'fs/promises';\nimport { join } from 'path';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface EffectVersionInfo {\n readonly version: string;\n readonly major: number;\n readonly minor: number;\n readonly patch: number;\n readonly isPrerelease: boolean;\n}\n\nexport interface VersionCompatReport {\n readonly effectVersion: EffectVersionInfo | null;\n readonly deprecationWarnings: string[];\n readonly suggestion: string | null;\n}\n\nconst VERSION_RE = /^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(.+))?$/;\n\nfunction parseVersion(version: string): EffectVersionInfo | null {\n const m = VERSION_RE.exec(version);\n if (m?.[1] === undefined || m[2] === undefined || m[3] === undefined) return null;\n return {\n version,\n major: parseInt(m[1], 10),\n minor: parseInt(m[2], 10),\n patch: parseInt(m[3], 10),\n isPrerelease: !!m[4],\n };\n}\n\n/**\n * Read Effect version from package.json at dir (or cwd).\n */\nexport async function getEffectVersion(\n dir: string = process.cwd(),\n): Promise<EffectVersionInfo | null> {\n try {\n const pkgPath = join(dir, 'package.json');\n const raw = await readFile(pkgPath, 'utf-8');\n const pkg = JSON.parse(raw) as { dependencies?: Record<string, string>; devDependencies?: Record<string, string> };\n const deps = { ...pkg.dependencies, ...pkg.devDependencies };\n const effectVersion = deps.effect;\n if (typeof effectVersion !== 'string') return null;\n const clean = effectVersion.replace(/^[\\^~]/, '');\n return parseVersion(clean);\n } catch {\n return null;\n }\n}\n\n/**\n * Produce a minimal compatibility report (version + any known deprecations).\n */\nexport async function checkVersionCompat(\n projectRoot: string = process.cwd(),\n): Promise<VersionCompatReport> {\n const effectVersion = await getEffectVersion(projectRoot);\n const deprecationWarnings: string[] = [];\n let suggestion: string | null = null;\n if (effectVersion) {\n if (effectVersion.major < 3) {\n deprecationWarnings.push('Effect v2 is deprecated; upgrade to Effect v3');\n suggestion = 'pnpm add effect@^3';\n }\n } else {\n suggestion = 'Add \"effect\" to dependencies to enable version checks';\n }\n return { effectVersion, deprecationWarnings, suggestion };\n}\n","/**\n * Effect.gen Yield Analysis Enhancement (GAP 28)\n *\n * Tracks variable bindings from yields and data flow through generator.\n */\n\nimport type { StaticEffectIR, StaticFlowNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface YieldBinding {\n readonly yieldIndex: number;\n readonly variableName?: string;\n readonly effectCallee?: string;\n readonly nodeId: string;\n}\n\nexport interface GenYieldAnalysis {\n readonly bindings: YieldBinding[];\n readonly unusedYieldIndices: number[];\n readonly serviceYields: string[];\n}\n\nfunction collectBindings(\n nodes: readonly StaticFlowNode[],\n bindings: YieldBinding[],\n serviceYields: string[],\n index: { current: number },\n): void {\n for (const node of nodes) {\n if (node.type === 'generator') {\n const gen = node;\n for (const y of gen.yields) {\n const callee = y.effect.type === 'effect' ? (y.effect).callee : undefined;\n const binding: YieldBinding = {\n yieldIndex: index.current++,\n nodeId: y.effect.id,\n ...(y.variableName !== undefined && { variableName: y.variableName }),\n ...(callee !== undefined && { effectCallee: callee }),\n };\n bindings.push(binding);\n if (callee?.includes('service') || callee?.includes('Context')) {\n serviceYields.push(callee);\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n collectBindings(children, bindings, serviceYields, index);\n } else {\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n collectBindings(children, bindings, serviceYields, index);\n }\n }\n}\n\n/**\n * Analyze yield bindings and service usage in a generator program.\n */\nexport function analyzeGenYields(ir: StaticEffectIR): GenYieldAnalysis {\n const bindings: YieldBinding[] = [];\n const serviceYields: string[] = [];\n collectBindings(ir.root.children, bindings, serviceYields, { current: 0 });\n const usedIndices = new Set<number>();\n for (const b of bindings) {\n if (b.variableName && !b.variableName.startsWith('_')) usedIndices.add(b.yieldIndex);\n }\n const unusedYieldIndices = bindings.map((b) => b.yieldIndex).filter((i) => !usedIndices.has(i));\n return {\n bindings,\n unusedYieldIndices,\n serviceYields: [...new Set(serviceYields)],\n };\n}\n","/**\n * SQL / Database Pattern Detection (GAP 15)\n *\n * Detects SqlClient, SqlSchema, transactions, and N+1 patterns.\n */\n\nimport { Project, SyntaxKind } from 'ts-morph';\nimport type { SourceLocation } from './types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface SqlPatternAnalysis {\n readonly sqlClientUsed: boolean;\n readonly withTransaction: boolean;\n readonly schemaDefs: string[];\n readonly queryInLoop: boolean;\n readonly locations: Map<string, SourceLocation>;\n readonly resolvers?: { name: string; table?: string; location: SourceLocation }[];\n readonly migrations?: { name: string; location: SourceLocation }[];\n readonly queriesInLoops?: { query: string; location: SourceLocation }[];\n}\n\nfunction getLoc(\n filePath: string,\n node: { getStart: () => number },\n sf: { getLineAndColumnAtPos: (p: number) => { line: number; column: number } },\n): SourceLocation {\n const { line, column } = sf.getLineAndColumnAtPos(node.getStart());\n return { filePath, line: line + 1, column };\n}\n\n/**\n * Analyze a file for Effect SQL/database patterns.\n */\nexport function analyzeSqlPatterns(\n filePath: string,\n source?: string,\n): SqlPatternAnalysis {\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = source\n ? project.createSourceFile(filePath, source)\n : project.addSourceFileAtPath(filePath);\n const locations = new Map<string, SourceLocation>();\n let sqlClientUsed = false;\n let withTransaction = false;\n const schemaDefs: string[] = [];\n let queryInLoop = false;\n const resolvers: { name: string; table?: string; location: SourceLocation }[] = [];\n const migrations: { name: string; location: SourceLocation }[] = [];\n const queriesInLoops: { query: string; location: SourceLocation }[] = [];\n\n for (const node of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression().getText();\n const loc = getLoc(filePath, node, sf);\n if (expr.includes('SqlClient') || expr.includes('sqlClient') || expr.includes('Sql')) {\n sqlClientUsed = true;\n locations.set('sql', loc);\n }\n if (expr.includes('withTransaction')) {\n withTransaction = true;\n locations.set('transaction', loc);\n }\n if (expr.includes('SqlSchema') || expr.includes('sqlSchema')) {\n schemaDefs.push(expr.slice(0, 80));\n locations.set('schema', loc);\n }\n // SqlResolver extraction\n if (expr.includes('SqlResolver.make') || expr.includes('SqlResolver.grouped') || expr.includes('SqlResolver.void')) {\n const args = node.getArguments();\n const nameArg = args.length > 0 ? args[0]?.getText().replace(/[\"'`]/g, '') : 'unnamed';\n resolvers.push({ name: nameArg ?? 'unnamed', location: loc });\n }\n // SqlMigrator extraction\n if (expr.includes('SqlMigrator')) {\n const args = node.getArguments();\n const nameArg = args.length > 0 ? args[0]?.getText().replace(/[\"'`]/g, '') : 'unnamed';\n migrations.push({ name: nameArg ?? 'unnamed', location: loc });\n }\n }\n\n const loopKinds = [SyntaxKind.ForStatement, SyntaxKind.ForOfStatement, SyntaxKind.WhileStatement];\n for (const loopKind of loopKinds) {\n for (const loop of sf.getDescendantsOfKind(loopKind)) {\n const body = loop.getFirstChildByKind(SyntaxKind.Block);\n const text = body?.getText() ?? '';\n if (text.includes('Sql') || text.includes('execute') || text.includes('query')) {\n queryInLoop = true;\n const loopLoc = getLoc(filePath, loop, sf);\n locations.set('sql-in-loop', loopLoc);\n queriesInLoops.push({ query: text.slice(0, 80), location: loopLoc });\n }\n }\n }\n\n return {\n sqlClientUsed,\n withTransaction,\n schemaDefs: [...new Set(schemaDefs)],\n queryInLoop,\n locations,\n ...(resolvers.length > 0 ? { resolvers } : {}),\n ...(migrations.length > 0 ? { migrations } : {}),\n ...(queriesInLoops.length > 0 ? { queriesInLoops } : {}),\n };\n}\n","/**\n * RPC Pattern Detection (GAP 20)\n *\n * Detects @effect/rpc usage: Rpc.make, routers, client calls.\n */\n\nimport { Project, SyntaxKind } from 'ts-morph';\nimport type { SourceLocation } from './types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface RpcPatternAnalysis {\n readonly rpcDefined: boolean;\n readonly routers: string[];\n readonly clientCalls: string[];\n readonly locations: Map<string, SourceLocation>;\n readonly rpcDefinitions?: { name: string; isStreaming: boolean; location: SourceLocation }[];\n}\n\nfunction getLoc(\n filePath: string,\n node: { getStart: () => number },\n sf: { getLineAndColumnAtPos: (p: number) => { line: number; column: number } },\n): SourceLocation {\n const { line, column } = sf.getLineAndColumnAtPos(node.getStart());\n return { filePath, line: line + 1, column };\n}\n\n/**\n * Analyze a file for Effect RPC patterns.\n */\nexport function analyzeRpcPatterns(\n filePath: string,\n source?: string,\n): RpcPatternAnalysis {\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = source\n ? project.createSourceFile(filePath, source)\n : project.addSourceFileAtPath(filePath);\n const locations = new Map<string, SourceLocation>();\n let rpcDefined = false;\n const routers: string[] = [];\n const clientCalls: string[] = [];\n const rpcDefinitions: { name: string; isStreaming: boolean; location: SourceLocation }[] = [];\n\n for (const node of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression().getText();\n const loc = getLoc(filePath, node, sf);\n if (expr.includes('Rpc.make') || expr.includes('Rpc.router')) {\n rpcDefined = true;\n routers.push(expr.slice(0, 60));\n locations.set('rpc', loc);\n }\n if (expr.includes('RpcClient') || expr.includes('Rpc.call')) {\n clientCalls.push(expr.slice(0, 60));\n locations.set('rpc-client', loc);\n }\n // RPC definition detection with streaming\n if (expr.includes('Rpc.make') || expr.includes('RpcGroup')) {\n const args = node.getArguments();\n const nameArg = args.length > 0 ? args[0]?.getText().replace(/[\"'`]/g, '') : 'unnamed';\n const nodeText = node.getText();\n const isStreaming = nodeText.includes('Stream') || nodeText.includes('stream');\n rpcDefinitions.push({ name: nameArg ?? 'unnamed', isStreaming, location: loc });\n }\n }\n\n return {\n rpcDefined,\n routers: [...new Set(routers)],\n clientCalls: [...new Set(clientCalls)],\n locations,\n ...(rpcDefinitions.length > 0 ? { rpcDefinitions } : {}),\n };\n}\n","/**\n * Request Batching / DataLoader Pattern (GAP 19)\n *\n * Detects RequestResolver, Request.tagged, Effect.withRequestBatching.\n */\n\nimport { Project, SyntaxKind } from 'ts-morph';\nimport type { SourceLocation } from './types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface RequestBatchingAnalysis {\n readonly requestTagged: boolean;\n readonly resolverBatched: boolean;\n readonly withBatching: boolean;\n readonly withCaching: boolean;\n readonly locations: Map<string, SourceLocation>;\n}\n\nfunction getLoc(\n filePath: string,\n node: { getStart: () => number },\n sf: { getLineAndColumnAtPos: (p: number) => { line: number; column: number } },\n): SourceLocation {\n const { line, column } = sf.getLineAndColumnAtPos(node.getStart());\n return { filePath, line: line + 1, column };\n}\n\n/**\n * Analyze a file for Effect request batching patterns.\n */\nexport function analyzeRequestBatching(\n filePath: string,\n source?: string,\n): RequestBatchingAnalysis {\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = source\n ? project.createSourceFile(filePath, source)\n : project.addSourceFileAtPath(filePath);\n const locations = new Map<string, SourceLocation>();\n let requestTagged = false;\n let resolverBatched = false;\n let withBatching = false;\n let withCaching = false;\n\n for (const node of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression().getText();\n const loc = getLoc(filePath, node, sf);\n if (expr.includes('Request.tagged') || expr.includes('Request.of')) {\n requestTagged = true;\n locations.set('request', loc);\n }\n if (expr.includes('RequestResolver.makeBatched') || expr.includes('RequestResolver.fromEffect')) {\n resolverBatched = true;\n locations.set('resolver', loc);\n }\n if (expr.includes('withRequestBatching')) {\n withBatching = true;\n locations.set('batching', loc);\n }\n if (expr.includes('withRequestCaching')) {\n withCaching = true;\n locations.set('caching', loc);\n }\n }\n\n return {\n requestTagged,\n resolverBatched,\n withBatching,\n withCaching,\n locations,\n };\n}\n","/**\n * STM (Software Transactional Memory) Analysis (GAP 13)\n *\n * Detects STM.commit, TRef, TMap, TQueue, transactional refs.\n */\n\nimport { Project, SyntaxKind } from 'ts-morph';\nimport type { SourceLocation } from './types';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface StmAnalysis {\n readonly commitSites: SourceLocation[];\n readonly tRefs: string[];\n readonly tMaps: string[];\n readonly tQueues: string[];\n readonly retryUsed: boolean;\n readonly locations: Map<string, SourceLocation>;\n}\n\nfunction getLoc(\n filePath: string,\n node: { getStart: () => number },\n sf: { getLineAndColumnAtPos: (p: number) => { line: number; column: number } },\n): SourceLocation {\n const { line, column } = sf.getLineAndColumnAtPos(node.getStart());\n return { filePath, line: line + 1, column };\n}\n\n/**\n * Analyze a file for Effect STM usage.\n */\nexport function analyzeStm(\n filePath: string,\n source?: string,\n): StmAnalysis {\n const project = new Project({ useInMemoryFileSystem: true });\n const sf = source\n ? project.createSourceFile(filePath, source)\n : project.addSourceFileAtPath(filePath);\n const locations = new Map<string, SourceLocation>();\n const commitSites: SourceLocation[] = [];\n const tRefs: string[] = [];\n const tMaps: string[] = [];\n const tQueues: string[] = [];\n let retryUsed = false;\n\n for (const node of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) {\n const expr = node.getExpression().getText();\n const loc = getLoc(filePath, node, sf);\n if (expr.includes('STM.commit') || expr === 'STM.commit') {\n commitSites.push(loc);\n locations.set('commit', loc);\n }\n if (expr.includes('TRef.make') || expr.includes('TRef.unsafeMake')) {\n tRefs.push(expr.slice(0, 50));\n locations.set('tref', loc);\n }\n if (expr.includes('TMap.make') || expr.includes('TMap.empty')) {\n tMaps.push(expr.slice(0, 50));\n locations.set('tmap', loc);\n }\n if (expr.includes('TQueue.make') || expr.includes('TQueue.bounded')) {\n tQueues.push(expr.slice(0, 50));\n locations.set('tqueue', loc);\n }\n if (expr.includes('STM.retry') || expr === 'STM.retry') retryUsed = true;\n }\n\n return {\n commitSites,\n tRefs: [...new Set(tRefs)],\n tMaps: [...new Set(tMaps)],\n tQueues: [...new Set(tQueues)],\n retryUsed,\n locations,\n };\n}\n","/**\n * Effect Playground / REPL Integration (GAP 30 - minimal)\n *\n * Serializes IR + metadata for shareable or client-side exploration.\n */\n\nimport type { StaticEffectIR } from './types';\nimport { renderStaticMermaid } from './output/mermaid';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface PlaygroundPayload {\n readonly version: 1;\n readonly ir: StaticEffectIR;\n readonly mermaid: string;\n readonly programName: string;\n readonly exportedAt: string;\n}\n\n/**\n * Export IR and Mermaid as a JSON payload for sharing or embedding.\n */\nexport function exportForPlayground(ir: StaticEffectIR): PlaygroundPayload {\n const mermaid = renderStaticMermaid(ir);\n return {\n version: 1,\n ir,\n mermaid,\n programName: ir.root.programName,\n exportedAt: new Date().toISOString(),\n };\n}\n\n/**\n * Encode payload as a base64 JSON string (for URL-safe sharing).\n */\nexport function encodePlaygroundPayload(payload: PlaygroundPayload): string {\n return Buffer.from(JSON.stringify(payload), 'utf-8').toString('base64url');\n}\n\n/**\n * Decode a base64url string back to PlaygroundPayload.\n */\nexport function decodePlaygroundPayload(encoded: string): PlaygroundPayload {\n const json = Buffer.from(encoded, 'base64url').toString('utf-8');\n return JSON.parse(json) as PlaygroundPayload;\n}\n","/**\n * Disk cache for analysis results.\n * When --cache is used, IR is stored by file path + content hash for reuse.\n */\n\nimport { createHash } from 'crypto';\nimport { readFile, writeFile, mkdir } from 'fs/promises';\nimport { stat } from 'fs/promises';\nimport { join } from 'path';\nimport type { StaticEffectIR } from './types';\n\nconst CACHE_DIR = '.effect-analyzer-cache';\nconst CACHE_VERSION = 1;\n\ninterface CacheEntry {\n readonly version: number;\n readonly contentHash: string;\n readonly mtimeMs: number;\n readonly irs: readonly StaticEffectIR[];\n}\n\nfunction contentHash(content: string): string {\n return createHash('sha256').update(content, 'utf-8').digest('hex').slice(0, 16);\n}\n\nfunction cachePath(baseDir: string, filePath: string): string {\n const safe = filePath.replace(/[^a-zA-Z0-9._-]/g, '_');\n return join(baseDir, CACHE_DIR, `${safe}.json`);\n}\n\n/**\n * Read cached IRs if valid (same content hash and mtime).\n */\nexport async function getCached(\n filePath: string,\n content: string,\n baseDir: string = process.cwd(),\n): Promise<readonly StaticEffectIR[] | null> {\n try {\n const path = cachePath(baseDir, filePath);\n const hash = contentHash(content);\n const raw = await readFile(path, 'utf-8');\n const entry = JSON.parse(raw) as CacheEntry;\n if (entry.version === CACHE_VERSION && entry.contentHash === hash) {\n return entry.irs;\n }\n } catch {\n // Cache miss or invalid\n }\n return null;\n}\n\n/**\n * Write IRs to cache.\n */\nexport async function setCached(\n filePath: string,\n content: string,\n irs: readonly StaticEffectIR[],\n baseDir: string = process.cwd(),\n): Promise<void> {\n try {\n const dir = join(baseDir, CACHE_DIR);\n await mkdir(dir, { recursive: true });\n const s = await stat(filePath).catch(() => null);\n const entry: CacheEntry = {\n version: CACHE_VERSION,\n contentHash: contentHash(content),\n mtimeMs: s?.mtimeMs ?? 0,\n irs,\n };\n await writeFile(cachePath(baseDir, filePath), JSON.stringify(entry), 'utf-8');\n } catch {\n // Ignore cache write failures\n }\n}\n","/**\n * Const Inliner\n *\n * Resolves same-module const references for static analysis.\n * Handles patterns like:\n * const myErrors = tags('A', 'B');\n * await step('x', fn, { errors: myErrors });\n *\n * This is used by the analyzer to inline const values for full static extraction.\n */\n\nimport { loadTsMorph } from \"./ts-morph-loader\";\nimport { VariableDeclarationKind, type Node, type SourceFile } from \"ts-morph\";\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Result of resolving a const reference.\n */\nexport interface ConstResolution {\n /** Whether the resolution was successful */\n resolved: boolean;\n /** The resolved value (if successful) */\n value?: ConstValue;\n /** Reason for failure (if not resolved) */\n reason?: string;\n}\n\n/**\n * A resolved const value.\n */\nexport type ConstValue =\n | { type: \"string\"; value: string }\n | { type: \"number\"; value: number }\n | { type: \"boolean\"; value: boolean }\n | { type: \"array\"; value: ConstValue[] }\n | { type: \"object\"; value: Record<string, ConstValue> }\n | { type: \"null\"; value: null }\n | { type: \"undefined\"; value: undefined };\n\n/**\n * Cache for resolved const declarations in a source file.\n */\nexport interface ConstCache {\n /** Map of variable name to its resolved value */\n values: Map<string, ConstResolution>;\n /** Source file this cache is for */\n sourceFile: SourceFile;\n}\n\n// =============================================================================\n// Main API\n// =============================================================================\n\n/**\n * Create a const cache for a source file.\n */\nexport function createConstCache(sourceFile: SourceFile): ConstCache {\n return {\n values: new Map(),\n sourceFile,\n };\n}\n\n/**\n * Resolve a const reference by name.\n */\nexport function resolveConst(\n name: string,\n cache: ConstCache\n): ConstResolution {\n // Check cache first\n const cached = cache.values.get(name);\n if (cached !== undefined) {\n return cached;\n }\n\n // Find the variable declaration\n const sourceFile = cache.sourceFile;\n\n // Look for variable declarations\n const variableDeclarations = sourceFile.getVariableDeclarations();\n\n for (const decl of variableDeclarations) {\n if (decl.getName() === name) {\n // Guard against cyclic references: mark as resolving before descending\n const sentinel: ConstResolution = {\n resolved: false,\n reason: `Cyclic reference detected for \"${name}\"`,\n };\n cache.values.set(name, sentinel);\n\n // Check if it's a const\n const statement = decl.getVariableStatement();\n if (statement?.getDeclarationKind() !== VariableDeclarationKind.Const) {\n const result: ConstResolution = {\n resolved: false,\n reason: `\"${name}\" is not a const declaration`,\n };\n cache.values.set(name, result);\n return result;\n }\n\n // Get the initializer\n const initializer = decl.getInitializer();\n if (!initializer) {\n const result: ConstResolution = {\n resolved: false,\n reason: `\"${name}\" has no initializer`,\n };\n cache.values.set(name, result);\n return result;\n }\n\n // Try to resolve the value\n const result = resolveNode(initializer, cache);\n cache.values.set(name, result);\n return result;\n }\n }\n\n // Not found\n const result: ConstResolution = {\n resolved: false,\n reason: `\"${name}\" not found in current file`,\n };\n cache.values.set(name, result);\n return result;\n}\n\n/**\n * Resolve a node to a const value.\n */\nexport function resolveNode(node: Node, cache: ConstCache): ConstResolution {\n const { Node } = loadTsMorph();\n\n // String literal\n if (Node.isStringLiteral(node)) {\n return {\n resolved: true,\n value: { type: \"string\", value: node.getLiteralValue() },\n };\n }\n\n // Number literal\n if (Node.isNumericLiteral(node)) {\n return {\n resolved: true,\n value: { type: \"number\", value: node.getLiteralValue() },\n };\n }\n\n // Boolean literal\n if (Node.isTrueLiteral(node)) {\n return {\n resolved: true,\n value: { type: \"boolean\", value: true },\n };\n }\n if (Node.isFalseLiteral(node)) {\n return {\n resolved: true,\n value: { type: \"boolean\", value: false },\n };\n }\n\n // Null literal\n if (Node.isNullLiteral(node)) {\n return {\n resolved: true,\n value: { type: \"null\", value: null },\n };\n }\n\n // Array literal\n if (Node.isArrayLiteralExpression(node)) {\n const elements = node.getElements();\n const values: ConstValue[] = [];\n\n for (const element of elements) {\n // Skip spread elements - can't inline those\n if (Node.isSpreadElement(element)) {\n return {\n resolved: false,\n reason: \"Array contains spread element\",\n };\n }\n\n const elementResult = resolveNode(element, cache);\n if (!elementResult.resolved || !elementResult.value) {\n return {\n resolved: false,\n reason: `Could not resolve array element: ${elementResult.reason}`,\n };\n }\n values.push(elementResult.value);\n }\n\n return {\n resolved: true,\n value: { type: \"array\", value: values },\n };\n }\n\n // Object literal\n if (Node.isObjectLiteralExpression(node)) {\n const properties = node.getProperties();\n const obj: Record<string, ConstValue> = {};\n\n for (const prop of properties) {\n // Skip spread assignments\n if (Node.isSpreadAssignment(prop)) {\n return {\n resolved: false,\n reason: \"Object contains spread assignment\",\n };\n }\n\n // Skip shorthand/computed properties\n if (Node.isShorthandPropertyAssignment(prop)) {\n const name = prop.getName();\n const refResult = resolveConst(name, cache);\n if (!refResult.resolved || !refResult.value) {\n return {\n resolved: false,\n reason: `Could not resolve shorthand property \"${name}\"`,\n };\n }\n obj[name] = refResult.value;\n continue;\n }\n\n if (!Node.isPropertyAssignment(prop)) {\n return {\n resolved: false,\n reason: \"Object contains unsupported property type\",\n };\n }\n\n // Get property name\n const nameNode = prop.getNameNode();\n if (Node.isComputedPropertyName(nameNode)) {\n return {\n resolved: false,\n reason: \"Object contains computed property name\",\n };\n }\n\n const name = prop.getName();\n const initializer = prop.getInitializer();\n\n if (!initializer) {\n return {\n resolved: false,\n reason: `Property \"${name}\" has no initializer`,\n };\n }\n\n const valueResult = resolveNode(initializer, cache);\n if (!valueResult.resolved || !valueResult.value) {\n return {\n resolved: false,\n reason: `Could not resolve property \"${name}\": ${valueResult.reason}`,\n };\n }\n\n obj[name] = valueResult.value;\n }\n\n return {\n resolved: true,\n value: { type: \"object\", value: obj },\n };\n }\n\n // Identifier - reference to another const\n if (Node.isIdentifier(node)) {\n const name = node.getText();\n\n // Handle undefined\n if (name === \"undefined\") {\n return {\n resolved: true,\n value: { type: \"undefined\", value: undefined },\n };\n }\n\n return resolveConst(name, cache);\n }\n\n // Call expression - handle tags() and similar helpers\n if (Node.isCallExpression(node)) {\n const expression = node.getExpression();\n const callee = Node.isIdentifier(expression) ? expression.getText() : null;\n\n // Handle tags() / err() helper\n if (callee === \"tags\" || callee === \"err\") {\n const args = node.getArguments();\n const values: ConstValue[] = [];\n\n for (const arg of args) {\n const argResult = resolveNode(arg, cache);\n if (!argResult.resolved || !argResult.value) {\n return {\n resolved: false,\n reason: `Could not resolve ${callee}() argument: ${argResult.reason}`,\n };\n }\n values.push(argResult.value);\n }\n\n return {\n resolved: true,\n value: { type: \"array\", value: values },\n };\n }\n\n return {\n resolved: false,\n reason: `Cannot inline function call: ${callee ?? \"unknown\"}`,\n };\n }\n\n // Template literal without expressions\n if (Node.isNoSubstitutionTemplateLiteral(node)) {\n return {\n resolved: true,\n value: { type: \"string\", value: node.getLiteralValue() },\n };\n }\n\n // Template literal with expressions - can't inline\n if (Node.isTemplateExpression(node)) {\n return {\n resolved: false,\n reason: \"Cannot inline template literal with expressions\",\n };\n }\n\n // As expression - unwrap\n if (Node.isAsExpression(node)) {\n return resolveNode(node.getExpression(), cache);\n }\n\n // Satisfies expression - unwrap\n if (Node.isSatisfiesExpression(node)) {\n return resolveNode(node.getExpression(), cache);\n }\n\n // Parenthesized expression - unwrap\n if (Node.isParenthesizedExpression(node)) {\n return resolveNode(node.getExpression(), cache);\n }\n\n return {\n resolved: false,\n reason: `Unsupported node type: ${node.getKindName()}`,\n };\n}\n\n// =============================================================================\n// Utility Functions\n// =============================================================================\n\n/**\n * Convert a ConstValue to a plain JavaScript value.\n */\nexport function constValueToJS(value: ConstValue): unknown {\n switch (value.type) {\n case \"string\":\n case \"number\":\n case \"boolean\":\n case \"null\":\n case \"undefined\":\n return value.value;\n case \"array\":\n return value.value.map(constValueToJS);\n case \"object\": {\n const obj: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value.value)) {\n obj[k] = constValueToJS(v);\n }\n return obj;\n }\n }\n}\n\n/**\n * Extract string array from a ConstValue.\n * Returns undefined if the value is not a string array.\n */\nexport function extractStringArray(value: ConstValue): string[] | undefined {\n if (value.type !== \"array\") {\n return undefined;\n }\n\n const strings: string[] = [];\n for (const item of value.value) {\n if (item.type !== \"string\") {\n return undefined;\n }\n strings.push(item.value);\n }\n\n return strings;\n}\n\n/**\n * Extract a string from a ConstValue.\n * Returns undefined if the value is not a string.\n */\nexport function extractString(value: ConstValue): string | undefined {\n if (value.type !== \"string\") {\n return undefined;\n }\n return value.value;\n}\n","import { Option } from 'effect';\nimport {\n getStaticChildren,\n type StaticEffectIR,\n type StaticEffectProgram,\n type StaticFlowNode,\n} from '../types';\nimport type {\n ProgramDiff,\n DiffOptions,\n StepDiffEntry,\n StructuralChange,\n DiffSummary,\n} from './types';\n\n// ---------------------------------------------------------------------------\n// Internal types\n// ---------------------------------------------------------------------------\n\ninterface StepContext {\n stepId: string;\n callee: string;\n containerType: string;\n index: number;\n}\n\nconst CONTAINER_TYPES = new Set([\n 'parallel',\n 'race',\n 'conditional',\n 'decision',\n 'switch',\n 'loop',\n 'error-handler',\n 'retry',\n 'generator',\n 'pipe',\n 'stream',\n 'fiber',\n]);\n\n// ---------------------------------------------------------------------------\n// Tree walkers\n// ---------------------------------------------------------------------------\n\nfunction collectStepsWithContext(\n node: StaticFlowNode | StaticEffectProgram,\n containerType = 'root',\n index = 0,\n): StepContext[] {\n const results: StepContext[] = [];\n\n if (node.type === 'effect') {\n results.push({\n stepId: node.id,\n callee: node.callee,\n containerType,\n index,\n });\n // Still recurse into callbackBody via getStaticChildren\n }\n\n const children = Option.getOrElse(getStaticChildren(node), () => [] as readonly StaticFlowNode[]);\n const nextContainer = CONTAINER_TYPES.has(node.type) ? node.type : containerType;\n\n let childIdx = 0;\n for (const child of children) {\n // For effect nodes at this level, the container is the current node type\n const childResults = collectStepsWithContext(child, nextContainer, childIdx);\n results.push(...childResults);\n childIdx++;\n }\n\n return results;\n}\n\nfunction countContainerTypes(node: StaticFlowNode | StaticEffectProgram): Map<string, number> {\n const counts = new Map<string, number>();\n\n function walk(n: StaticFlowNode | StaticEffectProgram): void {\n if (CONTAINER_TYPES.has(n.type)) {\n counts.set(n.type, (counts.get(n.type) ?? 0) + 1);\n }\n const children = Option.getOrElse(getStaticChildren(n), () => [] as readonly StaticFlowNode[]);\n for (const child of children) {\n walk(child);\n }\n }\n\n walk(node);\n return counts;\n}\n\n// ---------------------------------------------------------------------------\n// Diff algorithm\n// ---------------------------------------------------------------------------\n\nexport function diffPrograms(\n before: StaticEffectIR,\n after: StaticEffectIR,\n options?: DiffOptions,\n): ProgramDiff {\n const detectRenames = options?.detectRenames ?? true;\n const regressionMode = options?.regressionMode ?? false;\n\n const beforeSteps = collectStepsWithContext(before.root);\n const afterSteps = collectStepsWithContext(after.root);\n\n const beforeMap = new Map<string, StepContext>();\n for (const s of beforeSteps) beforeMap.set(s.stepId, s);\n\n const afterMap = new Map<string, StepContext>();\n for (const s of afterSteps) afterMap.set(s.stepId, s);\n\n const matchedBefore = new Set<string>();\n const matchedAfter = new Set<string>();\n const entries: StepDiffEntry[] = [];\n\n // Pass 1: Match by stepId (node.id)\n for (const afterStep of afterSteps) {\n const beforeStep = beforeMap.get(afterStep.stepId);\n if (beforeStep) {\n matchedBefore.add(beforeStep.stepId);\n matchedAfter.add(afterStep.stepId);\n\n if (beforeStep.containerType !== afterStep.containerType) {\n entries.push({\n kind: 'moved',\n stepId: afterStep.stepId,\n callee: afterStep.callee,\n containerBefore: beforeStep.containerType,\n containerAfter: afterStep.containerType,\n });\n } else {\n entries.push({\n kind: 'unchanged',\n stepId: afterStep.stepId,\n callee: afterStep.callee,\n });\n }\n }\n }\n\n // Pass 2: Rename detection — match unmatched by callee + index position\n if (detectRenames) {\n const unmatchedBefore = beforeSteps.filter((s) => !matchedBefore.has(s.stepId));\n const unmatchedAfter = afterSteps.filter((s) => !matchedAfter.has(s.stepId));\n\n for (const afterStep of unmatchedAfter) {\n const candidate = unmatchedBefore.find(\n (bs) =>\n !matchedBefore.has(bs.stepId) &&\n bs.callee === afterStep.callee &&\n bs.index === afterStep.index,\n );\n if (candidate) {\n matchedBefore.add(candidate.stepId);\n matchedAfter.add(afterStep.stepId);\n entries.push({\n kind: 'renamed',\n stepId: afterStep.stepId,\n previousStepId: candidate.stepId,\n callee: afterStep.callee,\n });\n }\n }\n }\n\n // Pass 3: Remaining unmatched → removed / added\n for (const bs of beforeSteps) {\n if (!matchedBefore.has(bs.stepId)) {\n entries.push({\n kind: 'removed',\n stepId: bs.stepId,\n callee: bs.callee,\n });\n }\n }\n for (const as2 of afterSteps) {\n if (!matchedAfter.has(as2.stepId)) {\n entries.push({\n kind: 'added',\n stepId: as2.stepId,\n callee: as2.callee,\n });\n }\n }\n\n // Structural changes — compare container counts\n const structuralChanges: StructuralChange[] = [];\n const beforeContainers = countContainerTypes(before.root);\n const afterContainers = countContainerTypes(after.root);\n\n const allContainerKeys = new Set([...beforeContainers.keys(), ...afterContainers.keys()]);\n for (const key of allContainerKeys) {\n const bCount = beforeContainers.get(key) ?? 0;\n const aCount = afterContainers.get(key) ?? 0;\n if (aCount > bCount) {\n for (let i = 0; i < aCount - bCount; i++) {\n structuralChanges.push({\n kind: 'added',\n nodeType: key,\n description: `${key} block added`,\n });\n }\n } else if (bCount > aCount) {\n for (let i = 0; i < bCount - aCount; i++) {\n structuralChanges.push({\n kind: 'removed',\n nodeType: key,\n description: `${key} block removed`,\n });\n }\n }\n }\n\n // Summary\n const summary: DiffSummary = {\n stepsAdded: entries.filter((e) => e.kind === 'added').length,\n stepsRemoved: entries.filter((e) => e.kind === 'removed').length,\n stepsRenamed: entries.filter((e) => e.kind === 'renamed').length,\n stepsMoved: entries.filter((e) => e.kind === 'moved').length,\n stepsUnchanged: entries.filter((e) => e.kind === 'unchanged').length,\n structuralChanges: structuralChanges.length,\n hasRegressions: regressionMode\n ? entries.some((e) => e.kind === 'removed') || structuralChanges.some((sc) => sc.kind === 'removed')\n : false,\n };\n\n return {\n beforeName: before.root.programName,\n afterName: after.root.programName,\n diffedAt: Date.now(),\n steps: entries,\n structuralChanges,\n summary,\n };\n}\n","import type { ProgramDiff, DiffMarkdownOptions, StepDiffEntry } from './types';\n\nconst KIND_ICONS: Record<string, string> = {\n added: '+',\n removed: '-',\n unchanged: ' ',\n renamed: '~',\n moved: '>',\n};\n\nfunction formatStepLine(entry: StepDiffEntry): string {\n const icon = KIND_ICONS[entry.kind] ?? '?';\n const callee = entry.callee ?? entry.stepId;\n\n switch (entry.kind) {\n case 'renamed':\n return `${icon} **${callee}** (renamed from \\`${entry.previousStepId}\\` → \\`${entry.stepId}\\`)`;\n case 'moved':\n return `${icon} **${callee}** (moved from \\`${entry.containerBefore}\\` → \\`${entry.containerAfter}\\`)`;\n case 'added':\n return `${icon} **${callee}** (added, id: \\`${entry.stepId}\\`)`;\n case 'removed':\n return `${icon} **${callee}** (removed, id: \\`${entry.stepId}\\`)`;\n default:\n return `${icon} ${callee}`;\n }\n}\n\nexport function renderDiffMarkdown(\n diff: ProgramDiff,\n options?: DiffMarkdownOptions,\n): string {\n const showUnchanged = options?.showUnchanged ?? false;\n const title =\n options?.title ?? `Effect Program Diff: ${diff.beforeName} → ${diff.afterName}`;\n\n const lines: string[] = [];\n\n lines.push(`# ${title}`);\n lines.push('');\n\n // Summary table\n lines.push('## Summary');\n lines.push('');\n lines.push('| Metric | Count |');\n lines.push('|--------|-------|');\n lines.push(`| Added | ${diff.summary.stepsAdded} |`);\n lines.push(`| Removed | ${diff.summary.stepsRemoved} |`);\n lines.push(`| Renamed | ${diff.summary.stepsRenamed} |`);\n lines.push(`| Moved | ${diff.summary.stepsMoved} |`);\n lines.push(`| Unchanged | ${diff.summary.stepsUnchanged} |`);\n lines.push(`| Structural changes | ${diff.summary.structuralChanges} |`);\n if (diff.summary.hasRegressions) {\n lines.push(`| **Regressions** | **Yes** |`);\n }\n lines.push('');\n\n // Step changes\n const visibleSteps = showUnchanged\n ? diff.steps\n : diff.steps.filter((s) => s.kind !== 'unchanged');\n\n if (visibleSteps.length > 0) {\n lines.push('## Step Changes');\n lines.push('');\n lines.push('```diff');\n for (const entry of visibleSteps) {\n lines.push(formatStepLine(entry));\n }\n lines.push('```');\n lines.push('');\n }\n\n // Structural changes\n if (diff.structuralChanges.length > 0) {\n lines.push('## Structural Changes');\n lines.push('');\n for (const sc of diff.structuralChanges) {\n const prefix = sc.kind === 'added' ? '+' : '-';\n lines.push(`- ${prefix} ${sc.description}`);\n }\n lines.push('');\n }\n\n return lines.join('\\n');\n}\n","import type { ProgramDiff } from './types';\n\nexport function renderDiffJSON(\n diff: ProgramDiff,\n options?: { pretty?: boolean },\n): string {\n const pretty = options?.pretty ?? true;\n return pretty ? JSON.stringify(diff, null, 2) : JSON.stringify(diff);\n}\n","import type { StaticEffectIR } from '../types';\nimport { renderStaticMermaid } from '../output/mermaid';\nimport type { ProgramDiff, DiffMermaidOptions } from './types';\n\n/**\n * Build a mapping from step id → mermaid node id by parsing the rendered\n * mermaid output. The effect-analyzer renderer uses `n1`, `n2`, etc.\n */\nfunction buildStepIdMap(mermaidOutput: string): Map<string, string> {\n const map = new Map<string, string>();\n // Match lines like: n2[\"Effect.succeed\"]\n const nodePattern = /^\\s*(n\\d+)\\[\"[^\"]*\"\\]/gm;\n let match: RegExpExecArray | null;\n while ((match = nodePattern.exec(mermaidOutput)) !== null) {\n const id = match[1] ?? '';\n // The mermaid node id is e.g. \"n2\"\n // We store the raw mermaid id — callers will correlate via position\n map.set(id, id);\n }\n return map;\n}\n\n/**\n * Render a mermaid diagram of the \"after\" IR with diff annotations overlaid\n * (style classes for added, removed, moved, renamed steps).\n */\nexport function renderDiffMermaid(\n after: StaticEffectIR,\n diff: ProgramDiff,\n options?: DiffMermaidOptions,\n): string {\n const direction = options?.direction ?? 'TB';\n const showRemoved = options?.showRemovedSteps ?? false;\n\n // Render the base mermaid for the \"after\" IR\n const baseMermaid = renderStaticMermaid(after, { direction });\n\n const _stepIdMap = buildStepIdMap(baseMermaid);\n\n // Collect step ids by kind for styling\n const addedIds = new Set(diff.steps.filter((s) => s.kind === 'added').map((s) => s.stepId));\n const _removedIds = new Set(diff.steps.filter((s) => s.kind === 'removed').map((s) => s.stepId));\n const movedIds = new Set(diff.steps.filter((s) => s.kind === 'moved').map((s) => s.stepId));\n const renamedIds = new Set(diff.steps.filter((s) => s.kind === 'renamed').map((s) => s.stepId));\n\n // Walk the \"after\" IR to build ir-id → mermaid-id mapping\n // We parse the mermaid output to find which mermaid node id corresponds to which IR node id\n const irToMermaid = new Map<string, string>();\n const lines = baseMermaid.split('\\n');\n\n // The renderer assigns mermaid ids in traversal order. We need to correlate\n // them with IR node ids. The simplest approach: scan for node definitions\n // and use the rendered mermaid output's nodeIdMap if available, otherwise\n // try to match based on label content.\n // Since renderStaticMermaid doesn't expose the nodeIdMap, we annotate by\n // scanning each diff step's callee in the mermaid output.\n\n // Build annotation lines\n const styleLines: string[] = [];\n\n // For each line that defines a node, try to match it to a diff entry\n for (const line of lines) {\n const nodeMatch = /^\\s*(n\\d+)\\[\"([^\"]*)\"\\]/.exec(line);\n if (!nodeMatch) continue;\n const mermaidId = nodeMatch[1] ?? '';\n const label = nodeMatch[2] ?? '';\n\n // Try matching by callee or displayName in the label\n for (const step of diff.steps) {\n if (step.callee && label.includes(step.callee)) {\n irToMermaid.set(step.stepId, mermaidId);\n break;\n }\n }\n }\n\n // Apply style classes\n for (const [irId, mermaidId] of irToMermaid) {\n if (addedIds.has(irId)) {\n styleLines.push(` style ${mermaidId} fill:#d4edda,stroke:#28a745,stroke-width:2px`);\n } else if (movedIds.has(irId)) {\n styleLines.push(` style ${mermaidId} fill:#fff3cd,stroke:#ffc107,stroke-width:2px`);\n } else if (renamedIds.has(irId)) {\n styleLines.push(` style ${mermaidId} fill:#cce5ff,stroke:#007bff,stroke-width:2px`);\n }\n }\n\n // For removed steps, optionally add phantom nodes\n if (showRemoved) {\n for (const step of diff.steps) {\n if (step.kind === 'removed') {\n const phantomId = `removed_${step.stepId.replace(/[^a-zA-Z0-9]/g, '_')}`;\n styleLines.push(` ${phantomId}[\"❌ ${step.callee ?? step.stepId}\"]`);\n styleLines.push(\n ` style ${phantomId} fill:#f8d7da,stroke:#dc3545,stroke-width:2px,stroke-dasharray: 5 5`,\n );\n }\n }\n }\n\n if (styleLines.length === 0) {\n return baseMermaid;\n }\n\n // Insert style lines before the closing of the diagram\n // The base mermaid ends with classDef/class lines or just edges.\n // We append our style lines at the end.\n return baseMermaid.trimEnd() + '\\n' + styleLines.join('\\n') + '\\n';\n}\n","import { execSync } from 'node:child_process';\n\n/**\n * Parse a source argument that can be:\n * - A file path (./src/foo.ts)\n * - A git ref:path combo (HEAD~1:src/foo.ts or main:src/foo.ts)\n * - A PR URL (https://github.com/org/repo/pull/123)\n */\nexport function parseSourceArg(arg: string): {\n kind: 'file' | 'git-ref' | 'github-pr';\n filePath?: string;\n ref?: string;\n prUrl?: string;\n} {\n // GitHub PR URL\n if (/^https?:\\/\\/github\\.com\\/.+\\/pull\\/\\d+/.test(arg)) {\n return { kind: 'github-pr', prUrl: arg };\n }\n\n // Git ref:path format (e.g. HEAD~1:src/foo.ts, main:src/foo.ts)\n // Exclude Windows absolute paths (C:\\..., D:\\...) — single letter before colon followed by backslash\n const gitRefMatch = /^([^:]+):(.+)$/.exec(arg);\n if (gitRefMatch?.[1] && gitRefMatch[2] && !arg.startsWith('/') && !arg.startsWith('.')) {\n const isWindowsPath = /^[A-Za-z]$/.test(gitRefMatch[1]) && gitRefMatch[2].startsWith('\\\\');\n if (!isWindowsPath) {\n return { kind: 'git-ref', ref: gitRefMatch[1], filePath: gitRefMatch[2] };\n }\n }\n\n // Plain file path\n return { kind: 'file', filePath: arg };\n}\n\n/**\n * Resolve a git ref:path to the file contents from that commit.\n * Returns the source text of the file at the given ref.\n */\nexport function resolveGitSource(ref: string, filePath: string, cwd?: string): string {\n try {\n const result = execSync(`git show ${ref}:${filePath}`, {\n cwd: cwd ?? process.cwd(),\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n return result;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to resolve git source ${ref}:${filePath}: ${msg}`, { cause: error });\n }\n}\n\n/**\n * Resolve a GitHub PR URL to the base and head refs.\n * Requires `gh` CLI to be installed and authenticated.\n */\nexport function resolveGitHubPR(\n prUrl: string,\n): { baseRef: string; headRef: string; baseBranch: string; headBranch: string } {\n try {\n const result = execSync(\n `gh pr view \"${prUrl}\" --json baseRefName,headRefName,baseRefOid,headRefOid`,\n {\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n },\n );\n const data = JSON.parse(result) as {\n baseRefName: string;\n headRefName: string;\n baseRefOid: string;\n headRefOid: string;\n };\n return {\n baseRef: data.baseRefOid,\n headRef: data.headRefOid,\n baseBranch: data.baseRefName,\n headBranch: data.headRefName,\n };\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to resolve GitHub PR ${prUrl}: ${msg}`, { cause: error });\n }\n}\n","import { Option } from 'effect';\nimport { getStaticChildren, type StaticEffectIR, type StaticFlowNode } from '../types';\nimport { inferBestDiagramType } from './auto-diagram';\n\nexport type AutoFormat =\n | 'mermaid'\n | 'mermaid-railway'\n | 'mermaid-services'\n | 'mermaid-errors'\n | 'mermaid-concurrency'\n | 'mermaid-decisions'\n | 'mermaid-layers'\n | 'mermaid-retry'\n | 'mermaid-testability'\n | 'mermaid-dataflow'\n | 'mermaid-causes'\n | 'mermaid-timeline';\n\ninterface FormatScore {\n format: AutoFormat;\n score: number;\n}\n\nfunction hasCauseSignals(node: StaticFlowNode): boolean {\n if (node.type === 'cause' || node.type === 'exit') return true;\n if (node.type === 'effect' && (node.callee === 'Effect.cause' || node.callee === 'Effect.exit')) {\n return true;\n }\n\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n return children.some(hasCauseSignals);\n}\n\n/**\n * Analyzes the IR and returns the most relevant format names to render.\n * Includes `mermaid-railway` or `mermaid` as baseline (auto-detected),\n * plus up to 2 specialized formats based on what's interesting in the program.\n */\nexport function selectFormats(ir: StaticEffectIR): AutoFormat[] {\n const stats = ir.metadata.stats;\n const root = ir.root;\n\n const scores: FormatScore[] = [\n {\n format: 'mermaid-services',\n score: root.dependencies.length * 2 + (root.requiredServices?.length ?? 0),\n },\n {\n format: 'mermaid-concurrency',\n score: stats.parallelCount * 3 + stats.raceCount * 3,\n },\n {\n format: 'mermaid-errors',\n // Only select errors view if there are actual typed errors (not just error handlers)\n score: root.errorTypes.length > 0 ? root.errorTypes.length * 2 + stats.errorHandlerCount * 2 : 0,\n },\n {\n format: 'mermaid-retry',\n score: stats.retryCount * 4 + stats.timeoutCount * 3,\n },\n {\n format: 'mermaid-decisions',\n score: stats.conditionalCount + stats.decisionCount + stats.switchCount,\n },\n {\n format: 'mermaid-layers',\n score: stats.layerCount * 3,\n },\n {\n format: 'mermaid-dataflow',\n score: root.source === 'pipe' ? 5 : 0,\n },\n {\n format: 'mermaid-causes',\n score: root.children.some(hasCauseSignals) ? 4 : 0,\n },\n {\n format: 'mermaid-timeline',\n score: root.dependencies.length > 2 ? 3 : 0,\n },\n {\n format: 'mermaid-testability',\n score: (root.requiredServices?.length ?? 0) * 2,\n },\n ];\n\n const top = scores\n .filter((s) => s.score > 0)\n .sort((a, b) => b.score - a.score)\n .slice(0, 2)\n .map((s) => s.format);\n\n const baseline: AutoFormat = inferBestDiagramType(ir) === 'railway' ? 'mermaid-railway' : 'mermaid';\n return [baseline, ...top];\n}\n","/**\n * Fiber Lifecycle Analysis\n *\n * Detects fiber fork patterns and potential leaks:\n * - Unscoped forks (Effect.fork) without a corresponding join/await/interrupt\n * - Daemon forks (fire-and-forget) flagged as intentional\n * - Scoped forks (forkScoped) always safe within scope\n */\n\nimport type { StaticEffectIR, StaticFlowNode, StaticFiberNode } from './types';\nimport { getStaticChildren } from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport type FiberRisk = 'safe' | 'daemon' | 'potential-leak' | 'uncertain';\n\nexport interface FiberForkInfo {\n /** Node ID of the fork */\n nodeId: string;\n /** Fork variant */\n operation: StaticFiberNode['operation'];\n /** Whether this fork is scoped (forkScoped) */\n isScoped: boolean;\n /** Whether this fork is daemon (forkDaemon) — fire-and-forget intentional */\n isDaemon: boolean;\n /** Whether a join/await/interrupt is found in the same program tree */\n hasJoin: boolean;\n /** Risk classification */\n risk: FiberRisk;\n location?: { filePath: string; line: number; column: number };\n}\n\nexport interface FiberLeakAnalysis {\n /** All fork operations found */\n forks: FiberForkInfo[];\n /** Forks classified as potential leaks (unscoped, non-daemon, no join) */\n potentialLeaks: FiberForkInfo[];\n /** Daemon (fire-and-forget) forks */\n daemonForks: FiberForkInfo[];\n /** Safely scoped forks */\n safeForks: FiberForkInfo[];\n /** Summary counts */\n summary: {\n total: number;\n safe: number;\n daemon: number;\n potentialLeaks: number;\n uncertain: number;\n };\n}\n\n// =============================================================================\n// Collection\n// =============================================================================\n\ntype JoinSet = Set<string>;\n\nfunction collectForks(\n nodes: readonly StaticFlowNode[],\n forks: StaticFiberNode[],\n joinIds: JoinSet,\n): void {\n for (const node of nodes) {\n if (node.type === 'fiber') {\n const fiber = node;\n if (\n fiber.operation === 'fork' ||\n fiber.operation === 'forkScoped' ||\n fiber.operation === 'forkDaemon' ||\n fiber.operation === 'forkAll' ||\n fiber.operation === 'forkIn' ||\n fiber.operation === 'forkWithErrorHandler'\n ) {\n forks.push(fiber);\n }\n if (\n fiber.operation === 'join' ||\n fiber.operation === 'await' ||\n fiber.operation === 'awaitAll' ||\n fiber.operation === 'interrupt' ||\n fiber.operation === 'interruptFork'\n ) {\n if (fiber.joinPoint) joinIds.add(fiber.joinPoint);\n joinIds.add(fiber.id);\n }\n }\n const children = Option.getOrElse(getStaticChildren(node), () => []);\n if (children.length > 0) collectForks(children, forks, joinIds);\n }\n}\n\nfunction classifyFork(fork: StaticFiberNode, hasJoin: boolean): FiberRisk {\n if (fork.isScoped) return 'safe';\n if (fork.isDaemon) return 'daemon';\n if (hasJoin) return 'safe';\n if (fork.operation === 'forkAll') return 'uncertain';\n if (fork.operation === 'forkIn') return 'safe'; // supervised by parent scope\n return 'potential-leak';\n}\n\n// =============================================================================\n// Analysis\n// =============================================================================\n\nexport function analyzeFiberLeaks(ir: StaticEffectIR): FiberLeakAnalysis {\n const rawForks: StaticFiberNode[] = [];\n const joinIds: JoinSet = new Set();\n\n collectForks(ir.root.children, rawForks, joinIds);\n\n const forks: FiberForkInfo[] = rawForks.map((fork) => {\n // A join is \"associated\" if there's a joinPoint referencing this fork,\n // or if any join node appears in the same program tree (conservative heuristic)\n const hasJoin = joinIds.size > 0;\n const risk = classifyFork(fork, hasJoin);\n\n const info: FiberForkInfo = {\n nodeId: fork.id,\n operation: fork.operation,\n isScoped: fork.isScoped,\n isDaemon: fork.isDaemon,\n hasJoin,\n risk,\n };\n if (fork.location) info.location = fork.location;\n return info;\n });\n\n const potentialLeaks = forks.filter((f) => f.risk === 'potential-leak');\n const daemonForks = forks.filter((f) => f.risk === 'daemon');\n const safeForks = forks.filter((f) => f.risk === 'safe');\n const uncertain = forks.filter((f) => f.risk === 'uncertain');\n\n return {\n forks,\n potentialLeaks,\n daemonForks,\n safeForks,\n summary: {\n total: forks.length,\n safe: safeForks.length,\n daemon: daemonForks.length,\n potentialLeaks: potentialLeaks.length,\n uncertain: uncertain.length,\n },\n };\n}\n\n// =============================================================================\n// Formatting\n// =============================================================================\n\nexport function formatFiberLeakReport(analysis: FiberLeakAnalysis): string {\n const lines: string[] = [];\n lines.push('# Fiber Lifecycle Analysis');\n lines.push('');\n lines.push(`Total forks: ${analysis.summary.total}`);\n lines.push(` Safe (scoped/joined): ${analysis.summary.safe}`);\n lines.push(` Daemon (intentional): ${analysis.summary.daemon}`);\n lines.push(` Uncertain: ${analysis.summary.uncertain}`);\n lines.push(` Potential leaks: ${analysis.summary.potentialLeaks}`);\n\n if (analysis.potentialLeaks.length > 0) {\n lines.push('');\n lines.push('## ⚠️ Potential Fiber Leaks');\n lines.push('');\n lines.push('These forks are not scoped, not daemon, and no join/await was found in the same program:');\n lines.push('');\n for (const leak of analysis.potentialLeaks) {\n const loc = leak.location\n ? ` at ${leak.location.filePath}:${leak.location.line}`\n : '';\n lines.push(`- \\`${leak.operation}\\` (id: ${leak.nodeId})${loc}`);\n }\n lines.push('');\n lines.push('💡 **Suggestions**:');\n lines.push(' - Use `Effect.forkScoped` to tie fiber lifetime to a scope');\n lines.push(' - Use `Effect.forkDaemon` if fire-and-forget is intentional');\n lines.push(' - Add `Fiber.join(fiber)` / `Fiber.await(fiber)` to properly await the fiber');\n }\n\n if (analysis.daemonForks.length > 0) {\n lines.push('');\n lines.push('## ℹ️ Daemon Forks (fire-and-forget)');\n lines.push('');\n for (const df of analysis.daemonForks) {\n const loc = df.location\n ? ` at ${df.location.filePath}:${df.location.line}`\n : '';\n lines.push(`- \\`${df.operation}\\` (id: ${df.nodeId})${loc}`);\n }\n }\n\n return lines.join('\\n');\n}\n","/**\n * Effect-Specific Linter\n *\n * Detects common issues and anti-patterns in Effect code:\n * - Untagged yields (potential bugs)\n * - Missing error handlers\n * - Unhandled error types\n * - Complex Layer compositions that could be simplified\n * - Dead code (unused yields)\n */\n\nimport type { StaticEffectIR, StaticFlowNode, SourceLocation } from './types';\nimport {\n isStaticGeneratorNode,\n isStaticEffectNode,\n isStaticErrorHandlerNode,\n isStaticParallelNode,\n isStaticPipeNode,\n getStaticChildren,\n} from './types';\nimport { Option } from 'effect';\n\n// =============================================================================\n// Lint Rule Types\n// =============================================================================\n\nexport interface LintRule {\n readonly name: string;\n readonly description: string;\n readonly severity: 'error' | 'warning' | 'info';\n readonly check: (ir: StaticEffectIR) => readonly LintIssue[];\n}\n\nexport interface LintIssue {\n readonly rule: string;\n readonly message: string;\n readonly severity: 'error' | 'warning' | 'info';\n readonly location?: SourceLocation | undefined;\n readonly nodeId?: string | undefined;\n /** Human-readable suggestion (shown in diagnostics) */\n readonly suggestion?: string | undefined;\n /** Optional code replacement for quick-fix (must be valid replacement text) */\n readonly fix?: string | undefined;\n}\n\n// =============================================================================\n// Lint Rules\n// =============================================================================\n\n/**\n * Detect untagged yields in Effect.gen\n * A yield without storing the result is often a bug\n */\nexport const untaggedYieldRule: LintRule = {\n name: 'untagged-yield',\n description: 'Detects yields in Effect.gen that are not assigned to a variable',\n severity: 'warning',\n check: (ir) => {\n const issues: LintIssue[] = [];\n \n const checkNode = (node: StaticFlowNode, _parentId?: string) => {\n if (isStaticGeneratorNode(node)) {\n for (const yield_ of node.yields) {\n // Check if yield has no variable name\n if (!yield_.variableName && yield_.effect.type !== 'unknown') {\n issues.push({\n rule: 'untagged-yield',\n message: `Untagged yield detected: ${isStaticEffectNode(yield_.effect) ? yield_.effect.callee : 'Effect'}`,\n severity: 'warning',\n location: yield_.effect.location,\n nodeId: yield_.effect.id,\n suggestion: 'Assign yield result to a variable or use Effect.tap for side effects',\n });\n }\n }\n }\n \n // Recursively check children\n const childrenOpt = getStaticChildren(node);\n if (Option.isSome(childrenOpt)) {\n for (const child of childrenOpt.value) {\n checkNode(child, node.id);\n }\n }\n };\n \n for (const child of ir.root.children) {\n checkNode(child);\n }\n \n return issues;\n },\n};\n\n/**\n * Detect missing error handlers on Effects that can fail\n */\nexport const missingErrorHandlerRule: LintRule = {\n name: 'missing-error-handler',\n description: 'Detects Effect operations that can fail but have no error handling',\n severity: 'error',\n check: (ir) => {\n const issues: LintIssue[] = [];\n \n const checkNode = (node: StaticFlowNode, hasErrorHandler = false) => {\n // Track if this node has error handling\n const currentHasHandler = hasErrorHandler || isStaticErrorHandlerNode(node);\n \n if (isStaticEffectNode(node)) {\n // Check if effect can fail (error type is not 'never')\n const canFail = node.typeSignature && node.typeSignature.errorType !== 'never';\n \n if (canFail && !currentHasHandler) {\n // Check if it's a common error-throwing operation\n const errorProneOps = ['Effect.try', 'Effect.tryPromise', 'Effect.fail', 'Effect.catchAll'];\n const isErrorProne = errorProneOps.some(op => node.callee.includes(op));\n \n if (isErrorProne || node.typeSignature.errorType !== 'unknown') {\n issues.push({\n rule: 'missing-error-handler',\n message: `Effect \"${node.callee}\" can fail with error type \"${node.typeSignature.errorType}\" but has no error handler`,\n severity: 'error',\n location: node.location,\n nodeId: node.id,\n suggestion: 'Add .pipe(Effect.catchAll(...)) or handle the error appropriately',\n });\n }\n }\n }\n \n // Recursively check children\n const childrenOpt = getStaticChildren(node);\n if (Option.isSome(childrenOpt)) {\n for (const child of childrenOpt.value) {\n checkNode(child, currentHasHandler);\n }\n }\n };\n \n for (const child of ir.root.children) {\n checkNode(child);\n }\n \n return issues;\n },\n};\n\n/**\n * Collect identifier-like names that appear in a node subtree (callee or name).\n * Used as a heuristic for \"variable is used\" in dead-code detection.\n */\nfunction collectUsedNamesInSubtree(node: StaticFlowNode): Set<string> {\n const used = new Set<string>();\n const visit = (n: StaticFlowNode) => {\n if (isStaticEffectNode(n)) {\n const callee = n.callee;\n // Simple identifier: no dots, no parens (e.g. \"user\" or \"validateUser\" but not \"Effect.succeed\")\n if (callee && !/\\.|\\(/.test(callee) && /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(callee)) {\n used.add(callee);\n }\n if (n.name) used.add(n.name);\n }\n const childrenOpt = getStaticChildren(n);\n if (Option.isSome(childrenOpt)) {\n for (const c of childrenOpt.value) visit(c);\n }\n };\n visit(node);\n return used;\n}\n\n/**\n * Detect dead code - yields whose results are never used in later yields or return\n */\nexport const deadCodeRule: LintRule = {\n name: 'dead-code',\n description: 'Detects yields whose results are never used',\n severity: 'warning',\n check: (ir) => {\n const issues: LintIssue[] = [];\n\n const checkNode = (node: StaticFlowNode) => {\n if (isStaticGeneratorNode(node)) {\n const yields = node.yields;\n for (let i = 0; i < yields.length; i++) {\n const yield_ = yields[i];\n if (!yield_) continue;\n const varName = yield_.variableName;\n if (!varName) continue;\n\n // Collect names used in any later yield or in the return node\n const usedLater = new Set<string>();\n for (let j = i + 1; j < yields.length; j++) {\n const laterYield = yields[j];\n if (!laterYield) continue;\n for (const name of collectUsedNamesInSubtree(laterYield.effect)) {\n usedLater.add(name);\n }\n }\n if (node.returnNode) {\n for (const name of collectUsedNamesInSubtree(node.returnNode)) {\n usedLater.add(name);\n }\n }\n\n if (!usedLater.has(varName)) {\n issues.push({\n rule: 'dead-code',\n message: `Yield result \"${varName}\" is never used in later steps or return`,\n severity: 'warning',\n location: yield_.effect.location,\n nodeId: yield_.effect.id,\n suggestion: 'Remove the variable assignment if not needed, or use the result in a subsequent step',\n });\n }\n }\n }\n\n const childrenOpt = getStaticChildren(node);\n if (Option.isSome(childrenOpt)) {\n for (const child of childrenOpt.value) {\n checkNode(child);\n }\n }\n };\n\n for (const child of ir.root.children) {\n checkNode(child);\n }\n\n return issues;\n },\n};\n\n/**\n * Detect complex Layer compositions that could be simplified\n */\nexport const complexLayerRule: LintRule = {\n name: 'complex-layer',\n description: 'Detects Layer compositions that might be overly complex',\n severity: 'warning',\n check: (ir) => {\n const issues: LintIssue[] = [];\n \n // Count Layer operations in the program\n let layerCount = 0;\n let layerProvideCount = 0;\n \n const countLayers = (node: StaticFlowNode) => {\n if (isStaticEffectNode(node)) {\n // Check for Layer operations or Effect provide operations\n if (node.callee.includes('Layer.') || node.callee.includes('.provide')) {\n layerCount++;\n if (node.callee.includes('provide') || node.callee.includes('provideService')) {\n layerProvideCount++;\n }\n }\n }\n \n const childrenOpt = getStaticChildren(node);\n if (Option.isSome(childrenOpt)) {\n for (const child of childrenOpt.value) {\n countLayers(child);\n }\n }\n };\n\n for (const child of ir.root.children) {\n countLayers(child);\n }\n\n // Warn if there are too many layer operations\n if (layerCount > 10) {\n issues.push({\n rule: 'complex-layer',\n message: `Program has ${layerCount} Layer operations, which may be overly complex`,\n severity: 'warning',\n suggestion: 'Consider grouping related services into a single AppLayer, or using Layer.mergeAll for parallel composition',\n });\n }\n \n // Warn about deep Layer.provide chains\n if (layerProvideCount > 5) {\n issues.push({\n rule: 'complex-layer',\n message: `Program has ${layerProvideCount} Layer.provide calls, suggesting deep dependency nesting`,\n severity: 'warning',\n suggestion: 'Consider flattening your Layer hierarchy or using Layer.mergeAll instead of nested provides',\n });\n }\n \n return issues;\n },\n};\n\n/**\n * Detect catchAll when catchTag would be more appropriate\n */\nexport const catchAllVsCatchTagRule: LintRule = {\n name: 'catchAll-vs-catchTag',\n description: 'Suggests using catchTag instead of catchAll when error type is tagged',\n severity: 'info',\n check: (ir) => {\n const issues: LintIssue[] = [];\n \n const checkNode = (node: StaticFlowNode) => {\n if (isStaticErrorHandlerNode(node)) {\n if (node.handlerType === 'catchAll') {\n // Check if source has a tagged error type\n // This is a heuristic - we'd need type info to be certain\n issues.push({\n rule: 'catchAll-vs-catchTag',\n message: 'Using catchAll - consider catchTag if error type has _tag discriminator',\n severity: 'info',\n location: node.location,\n nodeId: node.id,\n suggestion: 'Use Effect.catchTag(\"ErrorTag\", handler) for better type safety',\n });\n }\n }\n \n const childrenOpt = getStaticChildren(node);\n if (Option.isSome(childrenOpt)) {\n for (const child of childrenOpt.value) {\n checkNode(child);\n }\n }\n };\n \n for (const child of ir.root.children) {\n checkNode(child);\n }\n \n return issues;\n },\n};\n\n// =============================================================================\n// Advanced Lint Rules (GAP 26)\n// =============================================================================\n\n/** Error channel is unknown or Error instead of tagged errors */\nexport const errorTypeTooWideRule: LintRule = {\n name: 'error-type-too-wide',\n description: 'Warns when error type is unknown or Error instead of tagged errors',\n severity: 'warning',\n check: (ir) => {\n const issues: LintIssue[] = [];\n const checkNode = (node: StaticFlowNode) => {\n if (isStaticEffectNode(node)) {\n const err = node.typeSignature?.errorType.trim();\n if (err === 'unknown' || err === 'Error') {\n issues.push({\n rule: 'error-type-too-wide',\n message: `Effect \"${node.callee}\" has wide error type \"${err}\"`,\n severity: 'warning',\n location: node.location,\n nodeId: node.id,\n suggestion: 'Use branded/tagged errors (e.g. { _tag: \"NotFound\" }) for better handling',\n });\n }\n }\n const childrenOpt = getStaticChildren(node);\n if (Option.isSome(childrenOpt)) {\n for (const child of childrenOpt.value) checkNode(child);\n }\n };\n for (const child of ir.root.children) checkNode(child);\n return issues;\n },\n};\n\n/** Effect.all with concurrency \"unbounded\" on potentially large collections */\nexport const unboundedParallelismRule: LintRule = {\n name: 'unbounded-parallelism',\n description: 'Warns when Effect.all uses unbounded concurrency',\n severity: 'warning',\n check: (ir) => {\n const issues: LintIssue[] = [];\n const checkNode = (node: StaticFlowNode) => {\n if (isStaticParallelNode(node) && node.concurrency === 'unbounded') {\n issues.push({\n rule: 'unbounded-parallelism',\n message: `Parallel effect uses unbounded concurrency (${node.children.length} branches)`,\n severity: 'warning',\n location: node.location,\n nodeId: node.id,\n suggestion: 'Consider { concurrency: N } to limit parallelism',\n });\n }\n const childrenOpt = getStaticChildren(node);\n if (Option.isSome(childrenOpt)) {\n for (const child of childrenOpt.value) checkNode(child);\n }\n };\n for (const child of ir.root.children) checkNode(child);\n return issues;\n },\n};\n\n/** .pipe() with only one transformation */\nexport const redundantPipeRule: LintRule = {\n name: 'redundant-pipe',\n description: 'pipe() with single transformation could be inlined',\n severity: 'info',\n check: (ir) => {\n const issues: LintIssue[] = [];\n const checkNode = (node: StaticFlowNode) => {\n if (isStaticPipeNode(node) && node.transformations.length === 0) {\n issues.push({\n rule: 'redundant-pipe',\n message: 'Pipe has no transformations (only initial effect)',\n severity: 'info',\n location: node.location,\n nodeId: node.id,\n suggestion: 'Use the effect directly or add transformations',\n });\n }\n const childrenOpt = getStaticChildren(node);\n if (Option.isSome(childrenOpt)) {\n for (const child of childrenOpt.value) checkNode(child);\n }\n };\n for (const child of ir.root.children) checkNode(child);\n return issues;\n },\n};\n\n/** orDie used - may convert recoverable errors to defects */\nexport const orDieWarningRule: LintRule = {\n name: 'ordie-on-recoverable',\n description: 'orDie converts errors to defects; ensure only used for unrecoverable cases',\n severity: 'info',\n check: (ir) => {\n const issues: LintIssue[] = [];\n const checkNode = (node: StaticFlowNode) => {\n if (isStaticErrorHandlerNode(node) && node.handlerType === 'orDie') {\n issues.push({\n rule: 'ordie-on-recoverable',\n message: 'orDie used - typed errors become defects',\n severity: 'info',\n location: node.location,\n nodeId: node.id,\n suggestion: 'Reserve orDie for truly unrecoverable cases; handle recoverable errors with catchTag/catchAll',\n });\n }\n const childrenOpt = getStaticChildren(node);\n if (Option.isSome(childrenOpt)) {\n for (const child of childrenOpt.value) checkNode(child);\n }\n };\n for (const child of ir.root.children) checkNode(child);\n return issues;\n },\n};\n\n// =============================================================================\n// Lint Runner\n// =============================================================================\n\nexport const DEFAULT_LINT_RULES: readonly LintRule[] = [\n untaggedYieldRule,\n missingErrorHandlerRule,\n deadCodeRule,\n complexLayerRule,\n catchAllVsCatchTagRule,\n errorTypeTooWideRule,\n unboundedParallelismRule,\n redundantPipeRule,\n orDieWarningRule,\n];\n\nexport interface LintResult {\n readonly issues: readonly LintIssue[];\n readonly summary: {\n readonly errors: number;\n readonly warnings: number;\n readonly infos: number;\n readonly total: number;\n };\n}\n\n/**\n * Run all lint rules on an Effect IR\n */\nexport const lintEffectProgram = (\n ir: StaticEffectIR,\n rules: readonly LintRule[] = DEFAULT_LINT_RULES,\n): LintResult => {\n const allIssues: LintIssue[] = [];\n \n for (const rule of rules) {\n const issues = rule.check(ir);\n allIssues.push(...issues);\n }\n \n const errors = allIssues.filter(i => i.severity === 'error').length;\n const warnings = allIssues.filter(i => i.severity === 'warning').length;\n const infos = allIssues.filter(i => i.severity === 'info').length;\n \n return {\n issues: allIssues,\n summary: {\n errors,\n warnings,\n infos,\n total: allIssues.length,\n },\n };\n};\n\n/**\n * Format lint issues as a readable report\n */\nexport const formatLintReport = (result: LintResult, programName: string): string => {\n const lines: string[] = [];\n \n lines.push(`# Lint Report: ${programName}`);\n lines.push('');\n \n // Summary\n lines.push(`## Summary`);\n lines.push(`- **Errors**: ${result.summary.errors}`);\n lines.push(`- **Warnings**: ${result.summary.warnings}`);\n lines.push(`- **Info**: ${result.summary.infos}`);\n lines.push(`- **Total Issues**: ${result.summary.total}`);\n lines.push('');\n \n // Issues by severity\n if (result.issues.length > 0) {\n lines.push(`## Issues`);\n lines.push('');\n \n for (const issue of result.issues) {\n const icon = issue.severity === 'error' ? '❌' : issue.severity === 'warning' ? '⚠️' : 'ℹ️';\n lines.push(`${icon} **${issue.rule}** (${issue.severity})`);\n lines.push(` ${issue.message}`);\n \n if (issue.location) {\n lines.push(` at ${issue.location.filePath}:${issue.location.line}`);\n }\n \n if (issue.suggestion) {\n lines.push(` 💡 ${issue.suggestion}`);\n }\n \n lines.push('');\n }\n } else {\n lines.push('## ✅ No Issues Found');\n lines.push('');\n }\n \n return lines.join('\\n');\n};\n"],"mappings":"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,aACA,kBACA,eACA,sBACA,gBACA,gBACA,SACA,cACA,eACA,oBACA,kBACA,UACA,gBACA,aACF,EAEaC,GAAuB,CAClC,MACA,QACA,cACA,gBACA,WACA,UACA,gBACA,UACA,UACA,QACA,gBACF,EAEaC,GAAoB,CAC/B,kBACA,qBACA,YACA,gBACA,UACA,WACA,sBACA,wBACA,kBACA,SACA,mBACF,EAEaC,GAAsB,CACjC,WACA,QACA,UACA,aACA,aACA,UACA,eACA,eACA,gBACA,aACA,aACA,aACA,aACA,SACA,UACA,aACA,QACA,YACA,aACA,mBACA,eACA,iBACA,YACA,eACF,EAEaC,GAAiB,CAC5B,cACA,QACA,WACA,UACA,wBACA,QACF,EAMaC,GAAsE,CACjF,aAAc,MACd,iBAAkB,UAClB,iBAAkB,UAClB,aAAc,MACd,iBAAkB,UAClB,kBAAmB,WACnB,qBAAsB,cACtB,uBAAwB,gBACxB,mBAAoB,YACpB,iBAAkB,UAClB,kBAAmB,WACnB,iBAAkB,UAClB,aAAc,MACd,YAAa,KACb,gBAAiB,SACjB,gBAAiB,SACjB,qBAAsB,cACtB,iBAAkB,UAClB,YAAa,KACb,gBAAiB,SACjB,eAAgB,OAClB,EACaC,GAAuB,IAAI,IAAI,CAAC,UAAW,UAAW,UAAW,WAAY,cAAe,gBAAiB,YAAa,UAAW,UAAW,WAAY,MAAO,KAAM,SAAS,CAAC,EACnLC,GAAmBC,GAA4BA,KAAUH,GAEzDI,GAA2D,CACtE,aAAc,OACd,YAAa,MACb,cAAe,QACf,aAAc,OACd,eAAgB,SAChB,gBAAiB,UACjB,YAAa,MACb,WAAY,KACZ,mBAAoB,aACpB,eAAgB,SAChB,eAAgB,SAChB,eAAgB,SAChB,sBAAuB,gBACvB,iCAAkC,2BAClC,aAAc,OACd,uBAAwB,iBACxB,uBAAwB,iBACxB,YAAa,KACf,EACaC,GAAiB,IAAI,IAAI,CAAC,aAAc,2BAA4B,gBAAgB,CAAC,EACrFC,GAAeH,GAC1BA,EAAO,WAAW,QAAQ,GAAKA,KAAUC,GAE9BG,GAA2D,CACtE,aAAc,OACd,YAAa,MACb,kBAAmB,YACnB,iBAAkB,WAClB,mBAAoB,aACpB,cAAe,QACf,iBAAkB,WAClB,gBAAiB,UACjB,qBAAsB,eACtB,eAAgB,SAChB,mBAAoB,aACpB,eAAgB,SAChB,gBAAiB,UACjB,cAAe,QACf,kBAAmB,YACnB,sBAAuB,gBACvB,gBAAiB,UACjB,YAAa,MACb,eAAgB,QAClB,EACaC,GAAqB,IAAI,IAAI,CAAC,OAAQ,MAAO,YAAa,WAAY,aAAc,OAAO,CAAC,EAC5FC,GAAeN,GAC1BA,EAAO,WAAW,QAAQ,GAAKA,KAAUI,GAE9BG,GAAwD,CACnE,eAAgB,UAChB,YAAa,OACb,WAAY,MACZ,iBAAkB,YAClB,YAAa,OACb,YAAa,OACb,aAAc,QACd,iBAAkB,YAClB,iBAAkB,YAClB,qBAAsB,gBACtB,YAAa,OACb,kBAAmB,aACnB,cAAe,SACf,gBAAiB,WACjB,eAAgB,UAChB,WAAY,MACZ,eAAgB,UAChB,gBAAiB,WACjB,eAAgB,UAChB,eAAgB,UAChB,WAAY,MACZ,eAAgB,UAChB,gBAAiB,UACnB,EACaC,GAAoB,IAAI,IAAI,CAAC,UAAW,OAAQ,MAAO,YAAa,OAAQ,MAAM,CAAC,EACnFC,GAAcT,GACzBA,EAAO,WAAW,OAAO,IAAMA,KAAUO,IAAe,cAAc,KAAKP,CAAM,GAEtEU,GAAoE,CAC/E,uBAAwB,cACxB,qBAAsB,YACtB,kBAAmB,SACnB,iBAAkB,QAClB,kBAAmB,SACnB,gBAAiB,OACjB,oBAAqB,WACrB,oBAAqB,WACrB,mBAAoB,UACpB,kBAAmB,SACnB,gBAAiB,OACjB,gBAAiB,OACjB,iBAAkB,QAClB,mBAAoB,UACpB,oBAAqB,WACrB,mBAAoB,UACpB,qBAAsB,YACtB,iBAAkB,QAClB,mBAAoB,UACpB,mBAAoB,UACpB,oBAAqB,WACrB,uBAAwB,cACxB,iBAAkB,QAClB,sBAAuB,aACvB,qBAAsB,YACtB,kBAAmB,SACnB,kBAAmB,SACnB,oBAAqB,UACvB,EACaC,GAAkBX,GAC7BA,EAAO,WAAW,WAAW,IAAMA,KAAUU,IAAmB,kBAAkB,KAAKV,CAAM,GAElFY,GAAwB,CACnC,iBACA,mBACA,qBACA,uBACA,eACA,cACA,kBACA,mBACA,gBACF,EAEaC,GAAuB,CAClC,MACA,QACA,WACA,SACF,EAEaC,GAAmB,CAC9B,UACA,iBACA,2BACA,kBACA,QACA,SACA,cACF,EAMaC,GAAe,CAC1B,UACA,SACA,YACA,UACA,SACA,UACA,YACA,aACA,WACA,mBACA,SACA,SACA,WACA,kBACA,eACA,cACA,eACA,SACA,QACA,QACA,UACA,UACA,SACA,WACA,WACA,QACA,aACA,aACA,gBACA,QACA,SACA,SACA,UACA,UACA,SACA,eACA,SACA,SACA,cACA,SACA,eACA,eACA,wBACA,YACA,YACA,eACA,UACA,UACA,UACA,WACA,cACA,cACA,WACA,cACA,WACA,UACA,gBACA,UACA,YACA,iBACA,aACA,UACA,WACA,WACA,qBACA,SACA,YACA,aACA,YACA,QACA,cACA,YACA,YACA,eACA,WACA,QACA,UACA,QACA,WACA,WACA,aACA,eACA,WACA,cACA,WACA,UACA,UACA,iBACA,gBACA,YACA,YACA,UACA,aACA,aACA,eACA,eACA,WACA,OACA,WACA,aACA,WACF,EAEaC,GAAsB,IAAI,IAAI,CACzC,QAAS,gBAAiB,SAAU,SAAU,UAAW,SACzD,WAAY,UAAW,OAAQ,OAAQ,SAAU,QAAS,MAC1D,MAAO,UAAW,UAAW,SAAU,SAAU,OAAQ,UACzD,UAAW,SAAU,eAAgB,SAAU,WAAY,iBAC7D,CAAC,EAEYC,GAA0B,IAAI,IAAI,CAC7C,SAAU,QAAS,SAAU,QAAS,SAAU,WAAY,YAC5D,UAAW,kBAAmB,QAAS,QAAS,UAAW,iBAAkB,QAAS,OACtF,OAAQ,SAAU,SAAU,QAAS,UAAW,UAAW,OAC3D,YAAa,YAAa,QAAS,SAAU,SAAU,WACvD,SAAU,SAAU,SAAU,WAAY,cAAe,WACzD,WAAY,QAAS,cAAe,cAAe,YACrD,CAAC,EAEYC,GAAsBlB,GAC7BA,EAAO,SAAS,GAAG,GACnBiB,GAAwB,IAAIjB,CAAM,EAAU,GACzC,sBAAsB,KAAKA,CAAM,EAO7BmB,GAA0BnB,GAAuC,C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","names":["Effect","Option","Option","AnalysisError","code","message","location","isStaticEffectNode","node","isStaticGeneratorNode","isStaticPipeNode","isStaticParallelNode","isStaticRaceNode","isStaticErrorHandlerNode","isStaticRetryNode","isStaticTimeoutNode","isStaticResourceNode","isStaticConditionalNode","isStaticLoopNode","isStaticLayerNode","isStaticCauseNode","isStaticExitNode","isStaticScheduleNode","isStaticMatchNode","isStaticTransformNode","isStaticStreamNode","isStaticConcurrencyPrimitiveNode","node","isStaticFiberNode","isStaticUnknownNode","node","getStaticChildren","node","Option","y","retryNode","list","src","children","c","Effect","createRequire","tsMorphModule","projectCache","loadTsMorph","createProject","tsConfigPath","cacheKey","cached","Project","options","project","createProjectFromSource","code","filePath","Project","loadTsMorph","Option","EFFECT_TYPE_REGEX_3","EFFECT_TYPE_REGEX_2","effectTypeSignatureFromTypeText","typeText","clean","s","match3","match2","extractEffectTypeSignature","node","_typeChecker","nodeType","isEffectType","typeArgs","extractTypeArguments","aType","eType","rType","typeToString","fromText","fromCallee","tryExtractFromCalleeReturnType","callee","callSignatures","returnType","returnArgs","returnText","fromReturnText","symbol","decl","returnTypeText","sigs","retType","retArgs","fromAnnotation","type","name","aliasSymbol","aliasName","aliasTypeArgs","extractServiceRequirements","requirements","locationNode","nodeTypeArgs","parent","varDecl","declaredType","extractRequirementsType","services","extractServicesFromContext","service","sourceFile","line","column","location","contextType","contextMatch","tagType","extractTagIdentifier","parts","splitTopLevelUnion","part","match","trackTypeTransformation","inputType","operation","outputType","changes","current","depth","inString","i","ch","last","formatTypeSignature","sig","cleanTypeArg","STREAM_TYPE_REGEX","LAYER_TYPE_REGEX","SCHEDULE_TYPE_REGEX","CAUSE_TYPE_REGEX","extractStreamTypeSignature","extractLayerTypeSignature","extractScheduleTypeSignature","extractCauseTypeSignature","isSchemaType","extractSchemaInfo","DEFAULT_OPTIONS","idCounter","resetIdCounter","generateId","nodeTextCache","getNodeText","node","text","collectErrorTypes","nodes","set","visit","list","err","part","splitTopLevelUnion","children","Option","getStaticChildren","collectDependencies","byName","reqs","r","callee","extractLocation","filePath","includeLocations","sourceFile","pos","line","column","endPos","end","extractJSDocDescription","jsDocs","firstJsDoc","comment","description","c","tagIndex","rawText","descriptionMatch","leadingComments","lastComment","commentText","cleaned","extractJSDocTags","tryGetJsDocText","SyntaxKind","loadTsMorph","current","kind","grandparent","parseJSDocTags","params","returns","throws","example","tagPattern","match","tag","rest","paramMatch","name","value","exampleStart","nextTagMatch","getJSDocFromParentVariable","parent","parentKind","isJsOrJsxPath","path","extractYieldVariableName","yieldNode","extractProgramName","getEnclosingVariableName","start","propertyName","containerName","ancestor","depth","extractEnclosingEffectFnName","callExpr","exprText","args","firstArg","createEmptyStats","truncate","s","max","computeDisplayName","variableName","prefix","parts","op","channelOps","sinkOps","computeSemanticRole","desc","ERROR_HANDLER_PATTERNS","CONDITIONAL_PATTERNS","RESOURCE_PATTERNS","COLLECTION_PATTERNS","FIBER_PATTERNS","TRANSFORM_OPS","EFFECTFUL_TRANSFORMS","isTransformCall","callee","MATCH_OP_MAP","EXHAUSTIVE_OPS","isMatchCall","CAUSE_OP_MAP","CAUSE_CONSTRUCTORS","isCauseCall","EXIT_OP_MAP","EXIT_CONSTRUCTORS","isExitCall","SCHEDULE_OP_MAP","isScheduleCall","INTERRUPTION_PATTERNS","DO_NOTATION_PATTERNS","CACHING_PATTERNS","API_PREFIXES","BUILT_IN_TYPE_NAMES","KNOWN_EFFECT_NAMESPACES","isServiceTagCallee","getSemanticDescription","p","getSemanticDescriptionWithAliases","effectAliases","direct","dotIndex","prefix","method","isLikelyDirectEffectInitializer","initializer","effectImportNames","nonProgramEffectImportNames","SyntaxKind","loadTsMorph","isNonProgramName","name","isRunEntrypointCalleeText","exprText","isDirectEffectCalleeText","isPipeCall","alias","isLikelyEffectCall","call","isMethodPipeCall","arg","base","isInSameScope","node","scope","current","k","blockContainsEffectLikeUsage","block","awaitExpr","expr","blockContainsRunEntrypointUsage","prop","init","body","bodyBlock","ret","awaited","conditional","text","isEffectPackageSpecifier","specifier","EFFECT_NAMESPACE_NAMES","KNOWN_INTERNAL_MODULES","parseServiceIdsFromContextType","requiredType","skip","normalized","s","getNumericLiteralFromNode","kind","n","unary","operand","v","existsSync","dirname","resolve","join","sep","effectAliasCache","symbolResolutionCache","getNamesReExportedFromEffect","barrelSourceFile","out","decl","specifier","isEffectPackageSpecifier","EFFECT_NAMESPACE_NAMES","n","named","alias","resolveBarrelSourceFile","project","currentFilePath","baseDir","dirname","resolved","resolve","candidates","join","p","f","resolveModulePath","existsSync","isSpecifierUnderKnownEffectInternalsRoot","knownEffectInternalsRoot","normalizedSpecifier","resolvedPath","normalizedResolved","normalizedRoot","sep","getEffectImportNames","sourceFile","names","currentPath","def","ns","barrelFile","reExported","text","getEffectLikeNamespaceAliases","aliases","importDecl","moduleSpecifier","namespaceImport","aliasName","basename","KNOWN_INTERNAL_MODULES","NON_PROGRAM_EFFECT_MODULE_BASENAMES","getNonProgramEffectImportNames","getAliasesForFile","sf","effectSubmoduleAliasCache","canonicalNamespaceFromSpecifier","getEffectSubmoduleAliasMap","map","nsImport","canonical","normalizeEffectCallee","callee","dotIdx","rest","resolveCalleeModuleOrigin","calleeText","cache","nsText","cached","result","resolveNamespaceImportModuleSpecifier","expr","isEffectLikeCallExpression","call","effectAliases","API_PREFIXES","SyntaxKind","loadTsMorph","propAccess","isEffectCallee","prefix","WORKFLOW_FACTORY_NAMES","isWorkflowFactoryCall","calleeText","name","isWorkflowMakeCall","call","expr","loadTsMorph","prop","args","third","SyntaxKind","isWorkflowPackageSpecifier","specifier","_currentFilePath","n","isWorkflowNamespaceFromPackage","localName","isActivityNamespaceFromPackage","objectArgHasAnyProperty","propertyNames","arg","props","names","p","isWorkflowMakeOptionsCall","importSpecifierByLocalName","currentFilePath","baseText","isActivityMakeOptionsCall","getWorkflowBodyNodeForRunCall","runCall","sourceFile","innerCall","varDecls","decl","initializer","isInsideEffectGen","node","current","text","isTopLevelVariableDeclaration","isYieldBoundDeclaration","getCallExpressionFromInitializer","awaited","buildDiscoveryInfo","discoveryConfidence","discoveryReason","EFFECT_FAMILY_TYPE_HINTS","hasEffectFamilyTypeHint","hint","DISCOVERY_CONFIDENCE_RANK","isRunCall","exprText","bodyContainsRunMainOrRunPromise","body","isIndirectRunMainWrapper","_sourceFile","kind","init","isRuntimeCurriedForm","innerExprText","findEffectPrograms","_opts","programs","seenCallStarts","workflowProgramBuilders","effectImportNames","getEffectLikeNamespaceAliases","nonProgramEffectImportNames","getNonProgramEffectImportNames","importDecl","def","ns","named","inferAliasBackedDiscovery","aliasName","isSpecifierUnderKnownEffectInternalsRoot","inferDirectInitializerDiscovery","inferFromNestedEffectAliasUsage","propertyAccesses","base","calls","c","callee","local","nested","inferTypeAnnotatedDiscovery","typeText","isExportedDecl","fnReturnTypeText","typeArgText","isProgramRootExported","program","inferMethodReturnDiscovery","returnStatements","ret","isLikelyDirectEffectInitializer","filePath","varDeclarations","initCall","genCalls","expression","callStart","isWorkflowInvocation","propertyAccess","objectText","methodName","extractProgramName","isEffectLikeCallExpression","extractEnclosingEffectFnName","pipeName","hasEffectInArgs","callInitializer","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","threshold","confidence","alias","extractServiceDefinitionsFromFile","results","typeChecker","extExpr","extText","typeArgs","inner","interfaceTypeNode","type","sym","propName","classText","hasCustomEquality","hasCustomHash","r","Effect","Option","Effect","Option","analyzePipeChain","node","sourceFile","filePath","opts","warnings","stats","Effect","SyntaxKind","loadTsMorph","args","expr","isMethodPipe","baseExpr","transformArgs","baseNode","resolveIdentifierToLayerInitializer","baseSourceFile","basePath","project","inProject","added","initial","analyzeEffectExpression","transformations","arg","analyzed","typeFlow","typeChecker","flow","initialSig","extractEffectTypeSignature","argNode","sig","pipeNode","generateId","computeDisplayName","computeSemanticRole","serviceScope","body","unknownNode","extractLocation","returnedExpr","stmt","analyzeEffectCall","text","operation","isEffectCallee","getAliasesForFile","effectNode","objLit","HANDLER_PROPS","props","handlerEntries","hasKnownHandler","prop","assignment","propName","initializer","call","callee","normalizedCallee","normalizeEffectCallee","calleeOperation","location","nodes","analyzeLayerCall","analyzeStreamCall","analyzeChannelCall","analyzeSinkCall","analyzeConcurrencyPrimitiveCall","FIBER_PATTERNS","p","analyzeFiberCall","INTERRUPTION_PATTERNS","analyzeInterruptionCall","analyzeParallelCall","analyzeRaceCall","ERROR_HANDLER_PATTERNS","pattern","analyzeErrorHandlerCall","analyzeRetryCall","analyzeTimeoutCall","resourceOps","resourceOpPrefixes","isResourceOp","op","baseCall","baseCallee","baseOperation","analyzeResourceCall","CONDITIONAL_PATTERNS","analyzeConditionalCall","COLLECTION_PATTERNS","analyzeLoopCall","isTransformCall","analyzeTransformCall","isMatchCall","analyzeMatchCall","isCauseCall","analyzeCauseCall","isExitCall","analyzeExitCall","isScheduleCall","analyzeScheduleCall","callbackBody","isConstructorWithCallback","c","asyncCallback","firstArg","fn","innerNodes","block","retExpr","isEffectLikeCallExpression","resumeParamName","resumeCallCount","visit","returnsCanceller","k","effectJSDoc","extractJSDocDescription","typeSignature","requiredServices","extractServiceRequirements","serviceCall","tryResolveServiceCall","serviceMethod","propAccess","objectText","methodName","serviceId","provideKind","contextArgText","constructorKind","fiberRefName","KNOWN_FIBER_REFS","refName","tracedName","strMatch","getSemanticDescriptionWithAliases","extractJSDocTags","_sourceFile","objExpr","objectName","firstSegment","KNOWN_EFFECT_NAMESPACES","type","symbol","typeName","BUILT_IN_TYPE_NAMES","isLayerOrEffectInitializerCallee","initCall","initText","srcFile","normalized","resolveLayerInitializerFromImport","ident","importSpec","isLayerInit","currentPath","specifier","targetFile","resolveBarrelSourceFile","resolvedPath","resolveModulePath","tryDecl","d","init","list","v","exportName","exported","decls","targetName","declList","resolveLayerInitializerFromDefaultImport","importDecl","name","sym","decl","fromDecls","sf","id","fromDefault","spec","n","fromImport","operations","elements","elem","toAnalyze","argSourceFile","isMerged","lifecycle","provides","extractTagName","pae","obj","tag","isProvideCall","requiresSet","depName","baseName","collectRequires","eff","req","calleeText","layer","r","Option","getStaticChildren","layerSig","extractLayerTypeSignature","parseServiceIdsFromContextType","layerOpName","layerName","isMemoMap","layerNode","source","opName","constructorType","classifyOperator","isEffectful","opCategory","cardinality","windowSize","stride","getNumericLiteralFromNode","thisOp","sink","backpressureStrategy","effectiveSource","pipeline","effectiveConstructorType","srcStream","streamNode","channelOpCategory","srcChan","channelNode","sinkOpCategory","srcSink","sinkNode","_warnings","_stats","primitive","strategy","capacity","permitCount","first","lifecycleOptions","innerPrimNode","concurrencyNode","isScoped","isDaemon","fiberSource","scopeContext","parent","parentText","fiberNode","interruptionType","handler","interruptionNode","parseEffectAllOptions","optionsNode","concurrency","batching","discard","children","parsed","mode","branchLabels","child","parallelNode","raceLabels","raceNode","handlerType","exprSource","errorTag","errorTags","tagArg","objArg","a","handlerNode","schedule","scheduleNode","hasFallback","scheduleInfo","parseScheduleInfo","retryNode","scheduleText","baseStrategy","maxRetries","recursMatch","recurUpToMatch","jittered","conditions","duration","getNodeText","exprText","timeoutNode","resourceOperation","acquire","release","useEffect","resourceNode","conditionalType","condition","onTrue","onFalse","secondArg","propAssign","truncatedCondition","conditionalNode","loopType","bodyArgIndex","iterSource","loopNode","matchOp","MATCH_OP_MAP","isExhaustive","EXHAUSTIVE_OPS","matchedTags","arg0","matchNode","causeOp","CAUSE_OP_MAP","isConstructor","CAUSE_CONSTRUCTORS","childNodes","causeKind","childKinds","causeNode","exitOp","EXIT_OP_MAP","EXIT_CONSTRUCTORS","exitNode","scheduleOp","SCHEDULE_OP_MAP","transformType","TRANSFORM_OPS","EFFECTFUL_TRANSFORMS","fnText","transformNode","analyzeProgram","program","sourceFile","filePath","opts","tsVersion","Effect","warnings","stats","createEmptyStats","children","analyzeProgramNode","programJSDoc","getJSDocFromParentVariable","typeChecker","typeSignature","extractEffectTypeSignature","requiredServices","extractServiceRequirements","root","generateId","collectDependencies","collectErrorTypes","extractLocation","extractJSDocTags","serviceDefinitions","extractServiceDefinitionsFromFile","node","programType","args","genFn","analyzeGeneratorFunction","analyzePipeChain","call","SyntaxKind","loadTsMorph","pipeResult","analyzeRunEntrypointExpression","Option","callbackInArgs","arg","workflowBody","getWorkflowBodyNodeForRunCall","effect","analyzeEffectExpression","exprText","initializer","classDecl","callee","clause","clauseText","description","classEffectNode","extractJSDocDescription","body","SK","returnStatements","ret","expr","result","isFunctionBoundary","kind","containsGeneratorYield","found","child","extractLiteralValue","resolveConditionConsts","condition","constValues","resolved","name","value","pattern","replacement","simplifyBooleanExpression","unwrapExpression","inner","hasTerminatorStatement","stmts","last","collectYieldExpressionsDF","results","STEP_FUNCTIONS","isStepCall","extractStringLiteral","parseBranchCases","casesObj","cases","objLit","prop","analyzeStepCall","callExpr","ctx","stepId","innerEffect","analyzed","label","expression","c","effectsArg","arrayLit","element","iterSource","fn","effectNode","analyzeYieldNode","yieldNode","yieldExpr","isDelegated","opaqueNode","extractYieldVariableName","unwrappedExpr","stepResult","variableName","enrichedStep","computeDisplayName","computeSemanticRole","isServiceTagCallee","enrichedEffect","analyzeGeneratorBody","block","stmt","nodes","analyzeStatement","analyzeExpressionForYields","varStmt","VariableDeclarationKind","isConst","decl","init","literalValue","calleeText","yieldEntries","declName","lastEntry","ifStmt","condYields","thenStmt","elseStmt","onTrue","analyzeStatementBlock","onFalse","resolvedCondition","decisionLabel","decisionNode","y","switchStmt","clauses","hasFallthrough","hasDefault","currentLabels","currentBodyYields","currentIsDefault","caseClause","clauseStmts","clauseStmt","resolvedExpression","switchNode","forStmt","headerYields","entries","e","incrementor","bodyStmt","bodyYields","hasEarlyExit","checkEarlyExit","loopBody","loopNode","forOfStmt","iterExpr","iterVariable","forInStmt","whileStmt","doStmt","tryStmt","tryBlock","tryYields","catchClause","catchVariable","catchYields","catchBlock","finallyBlock","finallyYields","hasTerminalInTry","tryCatchNode","termNode","valueYields","k","unwrapped","exprKind","ternary","whenTrue","whenFalse","trueYields","falseYields","resolvedCond","binary","operatorToken","left","right","rightYields","yieldExprs","entry","serviceScope","yields","calls","aliases","getAliasesForFile","isEffectLikeCallExpression","analyzeEffectCall","generatorJSDoc","generatorNode","lastArg","lastArgText","analyzeEffectFile","filePath","options","Effect","opts","DEFAULT_OPTIONS","ts","Project","loadTsMorph","project","isJsOrJsxPath","createProject","error","AnalysisError","existingFile","sourceFile","programs","findEffectPrograms","program","analyzeProgram","analyzeEffectSource","code","createProjectFromSource","createResult","programs","Effect","program","AnalysisError","Option","name","found","p","available","analyze","filePath","options","resetIdCounter","programsEffect","analyzeEffectFile","code","analyzeEffectSource","Effect","Option","readdir","readFile","stat","readFileSync","join","extname","resolve","basename","Option","extractServiceTagsFromFile","sourceFile","filePath","SyntaxKind","loadTsMorph","results","typeChecker","classDeclarations","classDecl","name","extExpr","extText","tagId","tagMatch","typeArgs","inner","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","children","Option","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","countNodes","nodes","total","unknown","visit","list","node","children","Option","getStaticChildren","countUnknownReasons","byReason","isStaticUnknownNode","r","fileImportsEffect","filePath","content","readFileSync","isTypeOnlyZeroCandidate","detectExpectedZeroCategory","normalized","base","basename","findTsFiles","dir","extensions","maxDepth","currentDepth","result","entries","readdir","ent","full","join","extname","findPackageJsonDirs","e","resolveEntry","pkgDir","entry","resolve","fileHasTopLevelRunCall","Project","SyntaxKind","loadTsMorph","callExpressions","functionKinds","call","parent","current","kind","exprText","getEntryPointsFromPackageJson","dirPath","pkgDirs","entryPaths","raw","readFile","pkg","dirs","v","p","stat","analyzeProject","options","Effect","files","byFile","allPrograms","entryPointFiles","failedFiles","zeroProgramFiles","file","analyze","programs","err","ir","nameLikeEntry","isRunCall","packageEntryPaths","serviceMap","project","sourceFileMap","sf","buildProjectServiceMap","runCoverageAudit","startMs","outcomes","totalNodes","unknownNodes","fileUnknownRates","unknownReasonsCorpus","includePerFileTiming","fileStartMs","durationMs","count","fileTotal","fileUnknown","counts","reasonCounts","reason","n","msg","isZeroPrograms","discovered","analyzed","o","zeroPrograms","failed","percentage","analyzableCoverage","excludePatterns","isExcludedFromSuspicious","zeroProgramCategoryCounts","suspiciousZeros","zeroProgramClassifications","zeroOutcomes","importsEffect","expectedCategory","category","unknownNodeRate","topUnknownFiles","f","a","b","unknownReasonCounts","topUnknownReasons","readdir","join","extname","Project","SyntaxKind","addOpportunity","list","filePath","node","sourceFile","pattern","suggestion","snippet","line","column","findMigrationOpportunities","source","opportunities","project","text","name","m","isFsReaddir","isFsCopyFile","isFsMkdtemp","isFsSymlink","hasChildProcessFork","fileText","hasChildProcess","expr","full","hasStreamModule","isAssertThrows","isExpectRejects","findMigrationOpportunitiesInProject","dirPath","options","extensions","fileCount","scan","dir","entries","ent","formatMigrationReport","report","lines","o","Effect","Option","Option","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","getDataFlowOrder","graph","inDegree","adjacency","edge","targets","queue","id","degree","current","neighbor","newDegree","getProducers","stepId","producerIds","getConsumers","consumerIds","getTransitiveDependencies","visited","visit","findCycles","cycles","recStack","dfs","path","cycleStart","validateDataFlow","issues","read","write","cycle","sanitizeId","renderDataFlowMermaid","lines","label","warningId","Option","parseErrorTypes","errorType","splitTopLevelUnion","collectEffectErrors","nodes","result","node","eff","errors","children","getStaticChildren","analyzeErrorFlow","ir","stepErrors","allErrorsSet","errorToSteps","stepsWithoutErrors","step","error","steps","unionErrors","a","b","withoutErrors","current","removed","set","e","collectErrorsFromSubtree","out","visit","err","findCauseKindInSubtree","child","walkPropagation","errorsIn","own","handler","sourceErrors","afterNarrow","handlerErrors","causeKind","branchErrors","fromChild","analyzeErrorPropagation","propagation","byNodeId","p","getErrorsAtPoint","analysis","afterStepId","found","getErrorProducers","errorTag","stepIds","s","validateWorkflowErrors","declaredErrors","declaredSet","computedSet","unusedDeclared","undeclaredErrors","sanitizeId","id","renderErrorFlowMermaid","lines","label","stepId","formatErrorSummary","producers","name","DEFAULT_STYLES","DEFAULT_OPTIONS","escapeLabel","label","truncate","str","maxLength","sanitizeId","id","renderStaticMermaidInternal","ir","options","nodeLabelAnnotations","opts","context","lines","startId","endId","firstNodeId","lastNodeIds","renderNodes","lastId","subgraph","line","edge","styles","key","value","nodeId","styleClass","dataFlow","buildDataFlowGraph","irToMermaid","dfEdge","fromMermaid","toMermaid","read","mermaidId","dup","writerId","errorFlow","analyzeErrorFlow","errorPropagation","analyzeErrorPropagation","stepError","prop","handlerMermaid","nodeMermaid","narrowed","nodes","prevLastNodeIds","node","result","renderNode","prevId","getNodeId","getNodeLabel","annotations","p","sig","getNodeStyleClass","childResult","children","y","chain","forkId","joinId","modeLabel","i","child","branchResult","sourceResult","handlerNodeId","lastIds","handlerResult","wrapperId","acquireResult","resourceId","useResult","decisionId","condLabel","onTrueResult","onFalseResult","loopId","bodyLabel","bodyResult","trueResult","falseResult","switchId","switchLabel","caseItem","caseLabel","caseResult","warnId","tryResult","allLastIds","catchId","catchLabel","catchResult","finallyResult","termId","termLabel","valueResult","opaqueId","causeId","exitId","schedId","matchId","tag","tagNodeId","chanId","sinkId","intId","renderStaticMermaid","renderMermaid","Effect","isLogLikeStep","name","n","isPureTransformLikeStep","isEnvironmentLikeStep","isServiceBoundaryLikeStep","prefix","applyServiceBoundaryPrefixes","steps","out","prefixed","step","summarizePathSteps","path","collapseLogs","collapseTransforms","collapseEnvironment","collapsedGroups","current","currentName","j","next","nextName","count","renderPathsMermaid","paths","direction","stepNodes","nodeCounter","displayPaths","displayPath","stepInfo","edges","firstStep","firstInfo","cur","curInfo","nextInfo","lastStep","lastInfo","DEFAULT_ENHANCED_OPTIONS","collectEnhancedAnnotations","map","showTypes","showServices","visit","services","s","t","c","op","renderEnhancedMermaid","enhancedOpts","renderEnhancedMermaidEffect","collectFiberNodes","Option","getStaticChildren","renderSequenceMermaid","fibers","forks","f","joins","_f","_","fid","collectRetryNodes","renderRetryGanttMermaid","retries","withSchedule","r","idx","info","max","renderServiceGraphMermaid","serviceMap","sgLines","sanitize","serviceId","artifact","methodCount","edgesAdded","layer","req","edgeKey","fromId","toId","Option","stepId","index","letter","cycle","escapeLabel","text","stripErrorSuffix","name","extractErrorTypes","node","raw","splitTopLevelUnion","s","collectErrorTypes","seen","errors","visit","current","errorType","children","Option","getStaticChildren","child","computeLabel","stripped","isTransparentRailwayNode","isOpaqueRailwayStep","isSkippedRailwayNode","isSkippableEffectNode","callee","displayName","flattenNodesToSteps","nodes","steps","buildSteps","renderRailwayMermaid","ir","options","direction","lines","errorLines","hasPerStepErrors","i","currentStep","id","label","nextStep","nextId","nextLabel","errorTypes","errId","errLabel","lastId","Option","collectRequiredFromNode","node","result","reqs","r","x","children","getStaticChildren","c","getProvidedServiceId","getFirstArgText","callee","analyzeServiceFlow","ir","options","requiredServices","child","dedupedRequired","providedServices","unsatisfiedAt","consumedBy","available","getFirstArg","walk","nodes","eff","providedId","prov","list","u","serviceLifecycle","p","escapeLabel","text","sanitizeId","renderServicesMermaid","ir","options","direction","requiredServices","providedServices","analyzeServiceFlow","depsFromIR","allServiceIds","req","dep","lines","programName","serviceId","id","label","prov","renderServicesMermaidFromMap","serviceMap","artifact","methodCount","edgesAdded","layer","edgeKey","fromId","toId","escapeLabel","text","sanitizeId","stripErrorSuffix","name","renderErrorsMermaid","ir","options","direction","errorFlow","analyzeErrorFlow","propagation","analyzeErrorPropagation","lines","handlerNodes","handledErrors","p","handlerId","err","unhandledErrors","e","stepsWithErrors","s","step","label","error","handler","Option","DECISION_TYPES","escapeLabel","text","truncate","max","nodeLabel","node","collectDecisionNodes","nodes","result","counter","visit","children","Option","getStaticChildren","child","cond","dec","sw","c","findDecisionInfo","decisions","d","findFirstDecision","found","renderBranchTarget","terminalCounter","tId","decInfo","label","renderArrayBranchTarget","firstNode","renderDecisionsMermaid","ir","options","direction","lines","nodeId","condText","trueLabel","falseLabel","trueBranch","falseBranch","exprText","caseLabel","caseBranch","m","matchLabel","tag","Option","escapeLabel","text","sanitizeId","EFFECT_FAILURE_CALLEES","getErrorTypeLabel","node","raw","calleeToKind","callee","collectFailureNodes","results","op","childFailures","children","child","kind","errorType","label","Option","getStaticChildren","renderFailureNode","parentId","edgeLabel","lines","styledNodes","counter","nodeId","escaped","edge","childEdgeLabel","renderCausesMermaid","ir","options","direction","failureNodes","rootId","programName","styleGroups","className","nodeIds","Option","escapeLabel","text","nodeId","prefix","index","childLabel","node","capitalize","s","collectConcurrencyNodes","nodes","result","visit","children","Option","getStaticChildren","child","renderConcurrencyMermaid","ir","options","direction","collected","lines","styleLines","globalIdx","orderedIds","entry","pNode","pId","count","modeLabel","label","joinId","i","cId","cLabel","branchLabel","edgeLabel","rNode","rId","winnerId","fNode","fId","op","sourceLabel","cpNode","cpId","primName","from","to","Option","collectSteps","nodes","steps","visit","node","callee","displayName","children","Option","getStaticChildren","child","collectParticipants","seen","participants","visitStep","step","svc","renderParallelBlock","lines","indent","i","label","renderTimelineMermaid","ir","p","method","info","retries","dur","Option","collectLayerNodes","nodes","result","node","layer","info","op","children","getStaticChildren","buildLayerDependencyGraph","ir","layers","edges","serviceToLayers","depLayerId","svc","list","req","detectLayerCycles","graph","providerByService","providers","adjacency","deps","provider","cycles","visiting","visited","dfs","path","cycleStart","next","layerId","detectDiamondDependencies","diamonds","serviceId","findUnsatisfiedServices","allProvided","unsatisfied","requiredBy","computeLayerDepths","depths","computeDepth","cached","l","maxDep","sanitizeId","id","DEPTH_COLORS","renderLayerGraphMermaid","lines","cycleEdges","cycle","i","label","provided","e","isCycleEdge","maxDepth","d","depth","cycleNodes","sanitizeId","id","renderLayersMermaid","ir","options","direction","graph","buildLayerDependencyGraph","lines","allServices","layer","svc","req","mergedLayerIds","label","lifecycle","nodeId","edge","from","to","Option","escapeLabel","text","collectResilienceNodes","nodes","result","node","children","Option","getStaticChildren","buildRetryLabel","info","parts","operationLabel","source","renderRetryMermaid","ir","options","direction","collected","lines","index","prefix","opLabel","retryNode","retryLabel","timeoutNode","duration","timeoutLabel","renderTestabilityMermaid","ir","options","direction","services","deps","layerNames","d","lines","easyIds","hardIds","i","sid","service","mockWord","Option","stepId","index","escapeLabel","text","collectPipeSteps","node","chains","pipeNode","steps","initialSig","i","t","transformType","isEffectful","sig","children","Option","getStaticChildren","child","collectGeneratorSteps","genNode","y","renderDataflowMermaid","ir","options","direction","allChains","lines","styleLines","globalIdx","baseIdx","step","id","label","nextStep","nextId","nextLabel","edgeLabel","prevError","nextError","arrow","Option","Option","DEFAULT_THRESHOLDS","calculateComplexity","ir","nodes","cyclomatic","calculateCyclomaticComplexity","cognitive","calculateCognitiveComplexity","pathCount","calculatePathCount","maxDepth","calculateMaxDepth","maxParallelBreadth","calculateMaxParallelBreadth","decisionPoints","countDecisionPoints","complexity","node","countDecisionPointsInNode","children","getStaticChildren","childList","Option","count","child","calculateCognitiveForNodes","nestingDepth","calculateCognitiveForNode","caseItem","hasUnbounded","result","pathCountForNode","truePaths","pathCountForNodes","falsePaths","total","childPaths","product","c","casePaths","paths","depthOfNode","currentDepth","maxChildDepth","maxBreadth","parallelBreadthOfNode","assessComplexity","metrics","thresholds","warnings","recommendations","level","hasError","w","hasWarning","formatComplexitySummary","assessment","lines","warning","icon","rec","inferBestDiagramType","ir","nodes","hasNodeType","stats","metrics","calculateComplexity","type","node","children","Option","getStaticChildren","Option","DEFAULT_OPTIONS","generatePaths","ir","options","generatePathsWithMetadata","context","initialState","generatePathsForNodes","state","index","generatePathDescription","nodes","currentState","states","node","newStates","generatePathsForNode","term","handleEffectNode","handleGeneratorNode","handlePipeNode","handleParallelNode","handleRaceNode","handleErrorHandlerNode","handleSingleChildNode","handleResourceNode","handleConditionalNode","handleLoopNode","handleLayerNode","handleStreamNode","handleConcurrencyOrFiberNode","handleDecisionNode","handleSwitchNode","handleTryCatchNode","handleTerminalNode","handleCauseNode","handleLeafStepNode","handleMatchNode","handleTransformNode","handleChannelNode","handleSinkNode","handleInterruptionNode","stepRef","children","y","combinedStates","child","newCombinedStates","childStates","childState","first","allStates","maxAllowed","roomLeft","toAdd","sourceStates","handlerStates","resourceNodes","trueCondition","trueState","trueStates","falseCondition","falseState","falseStates","step","idx","p","stateWithStep","caseItem","caseLabel","caseCondition","caseState","caseStates","tryStates","catchStates","catchCondition","catchState","combined","finalStates","_context","parts","conditionParts","c","verb","stepNames","s","name","calculatePathStatistics","paths","conditions","pathsWithLoops","pathsWithUnresolvedRefs","totalLength","maxLength","minLength","path","length","filterPaths","filter","MAX_PROGRAM_TIPS","MAX_FILE_TIPS","clamp","n","min","max","uniqueCapped","items","startsWithAllowedTipPrefix","tip","normalizeTip","collectAllNodes","nodes","out","visit","list","node","children","Option","getStaticChildren","isLogLike","name","looksAnonymousEffectNode","callee","isServiceCallNode","hasNamedServiceCallee","c","computeMetrics","ir","options","detailedSteps","effects","sideEffects","logEffects","unknownNodes","anonymousNodeCount","serviceCalls","namedServiceCalls","pipeNodes","pipeChainCount","maxPipeChainLength","p","representativePath","generatePaths","a","b","summary","summarizePathSteps","ratioBase","serviceBase","scoreFromMetrics","metrics","unknownPenalty","anonymousPenalty","stepPenalty","logPenalty","sideEffectPenalty","score","band","reasonsFromMetrics","reasons","logCount","tipsFromMetrics","tips","computeProgramDiagramQuality","hintReasons","hintTips","aggregateMetrics","qualities","weights","q","totalWeight","weightedAvg","picker","sum","i","weightedSum","computeFileDiagramQuality","filePath","programs","programQualities","weightedScore","makeEntry","metricValue","rankTop","entries","valueOf","topN","dv","buildTopOffendersReport","fileQualities","capped","readFile","resolve","isEffectLikeRule","ruleId","mapTip","message","text","formatReason","rule","msg","parseResults","raw","results","loadDiagramQualityHintsFromEslintJson","jsonPath","content","parsed","byFile","file","filePath","messages","cur","reason","tip","out","hints","indent","depth","shortLabel","node","explainNode","state","pad","lines","desc","label","y","childLines","firstChild","trimmed","retLines","firstRet","initLines","t","tLines","concDesc","child","tagInfo","maxPart","stratPart","parts","dur","c","caseLabel","src","provides","requires","op","ops","o","sinkPart","scopeNote","cap","renderProgram","program","_ir","bodyLines","numberedLines","numberTopLevelSteps","header","footer","services","dep","svc","sections","step","line","renderExplanation","ir","renderMultipleExplanations","irs","SOURCE_ABBREVIATIONS","abbreviateSource","source","renderSummary","ir","name","kind","steps","services","errors","handlers","complexity","calculateComplexity","extractRow","renderMultipleSummaries","irs","rows","headers","widths","r","padRight","s","w","padLeft","headerLine","separatorLine","dataLines","row","renderDependencyMatrix","irs","serviceSet","depsByProgramName","ir","programName","depSet","dep","services","a","b","programNames","buildMarkdownTable","program","service","deps","renderDependencyMatrixFromServiceMap","serviceMap","programSet","programInstances","serviceToProgramsMap","serviceId","artifact","consumerPrograms","consumer","programs","consumers","hasRelation","summary","summaryPrograms","summaryServices","lines","separators","s","cells","Effect","DEFAULT_OPTIONS","renderJSON","ir","options","opts","space","data","replacer","renderMultipleJSON","irs","_key","value","resolveThemeName","theme","renderInteractiveHTML","ir","options","title","resolvedTheme","mermaidCode","renderStaticMermaid","paths","generatePaths","complexity","calculateComplexity","mermaidWithDataFlow","mermaidWithErrorFlow","irJson","pathsJson","complexityJson","initialThemeJs","escapeHtml","s","Option","DEFAULT_DOC_OPTIONS","collectWorkflowSteps","nodes","steps","depth","node","step","describeNode","children","Option","getStaticChildren","p","renderDocumentation","ir","options","opts","sections","sig","indent","dep","errorFlow","analyzeErrorFlow","error","producers","complexity","calculateComplexity","dataFlow","buildDataFlowGraph","read","dup","renderStaticMermaid","renderMultiProgramDocs","irs","Option","resolveTypeConfidence","sig","formatErrorTypeDisplay","errorType","parseErrorTags","splitTopLevelUnion","s","describeFlowNode","node","collectStepDetails","nodes","result","ctx","detail","nodeToStepDetail","childCtx","retryInfo","yieldEffects","y","children","Option","getStaticChildren","outputType","errors","generateShowcase","ir","options","sourceCode","mermaid","renderStaticMermaid","stepDetails","generateMultipleShowcase","irs","Option","collectEffectCallees","nodes","result","node","eff","callee","location","children","Option","getStaticChildren","collectYieldStarCalls","y","analyzeProgramGraph","irs","filePath","options","programNames","ir","firstIr","entryProgram","graph","name","refs","calls","r","calledBy","other","otherRefs","stack","visited","dfs","programName","start","call","getTopologicalOrder","temp","visit","getDependencies","deps","collect","getDependents","dependents","caller","calculateGraphComplexity","totalCC","maxDepth","calculateComplexity","order","depths","depth","renderGraphMermaid","lines","sanitize","s","shape","label","cyclicNodes","cycle","n","renderCompositionMermaid","byFile","list","fileIdx","fileName","ref","refId","analyzeProjectComposition","serviceMap","allProgramNames","programToFile","programToIR","firstProgram","yieldRefs","yr","entry","knownServiceIds","otherName","otherIR","otherYields","renderCompositionWithServicesMermaid","projectServiceMap","compLines","serviceId","artifact","consumer","dep","Option","isRefCallee","callee","getRefOperation","getRefId","WRITE_OPS","analyzeStateFlow","ir","refs","mutations","readersByRef","writersByRef","visit","nodes","node","eff","refId","operation","info","w","r","children","getStaticChildren","stateGraph","potentialRaces","readers","writers","Option","analyzeScopeResource","ir","acquisitions","scopeBoundaries","poolCreations","potentialLeaks","visit","nodes","node","eff","callee","acq","sb","res","children","Option","getStaticChildren","Option","isSpanCallee","callee","isLogCallee","getLogLevel","isMetricCallee","getMetricType","analyzeObservability","ir","spans","logPoints","metrics","effectCount","effectsWithSpans","effectsWithMetrics","errorHandlersWithLogging","errorHandlerCount","visit","nodes","underSpan","underMetric","node","eff","s","lp","isTagged","m","handler","hasLog","checkLog","n","c","getStaticChildren","children","thisIsSpan","thisIsMetric","nextUnderSpan","nextUnderMetric","Option","detectLayerCycles","layerGraph","adjacency","providerByService","layer","svc","providers","deps","req","provider","visiting","visited","hasCycle","node","next","layerId","checkDICompleteness","ir","serviceFlow","analyzeServiceFlow","layerGraph","buildLayerDependencyGraph","providedByLayer","layer","svc","requiredIds","r","entries","valid","serviceId","provider","layerGraphAcyclic","detectLayerCycles","serviceProviderIds","providers","layerLocMap","collectLayerLocations","nodes","node","ch","Option","getStaticChildren","layerConflicts","providerLayerIds","locs","id","l","formatDICompletenessReport","report","lines","e","icon","Option","DEFAULT_OPTIONS","validateStrict","ir","options","opts","diagnostics","validateNodes","validateFiberLeaks","validateResourceScopes","validateConcurrencyBounds","validateDeadCodePaths","validateUnusedServices","errors","d","warnings","nodes","hasAncestorErrorHandler","node","currentHasErrorHandler","eff","validateEffectNode","errorType","child","children","Option","getStaticChildren","joinPointsInScope","fiber","inScope","isScope","callee","label","layerGraph","buildLayerDependencyGraph","consumedServices","layer","req","collectConsumedServicesFromNodes","svc","consumed","reqs","r","formatDiagnostics","result","lines","diag","icon","loc","formatDiagnosticsJSON","getSummary","DEFAULT_OPTIONS","defaultTestNameGenerator","generateTestMatrix","paths","options","opts","filteredPaths","p","testPaths","path","generateTestPath","conditions","extractConditions","summary","calculateSummary","testName","priority","determinePriority","setupConditions","c","verb","expectedSteps","s","name","parts","mainSteps","stepNames","camelToSpaces","conditionDescriptions","simplified","simplifyCondition","str","expression","conditionMap","condition","key","entry","affected","highPriorityPaths","minTestsForCoverage","formatTestMatrixMarkdown","matrix","lines","highPriority","mediumPriority","lowPriority","formatTestPathLines","truncatedExpr","trueCount","falseCount","i","formatTestMatrixAsCode","runner","programName","escapeString","step","formatTestChecklist","marker","Project","SyntaxKind","getLocation","filePath","node","sourceFile","line","column","analyzeConfig","source","project","requiredConfigs","optionalConfigs","secretConfigs","providerOverrides","envVarHints","combinators","text","loc","key","parentText","hasDefault","envKey","configType","item","COMBINATOR_MAP","pattern","kind","formatConfigReport","analysis","lines","all","seen","c","req","def","secret","s","byKind","combSummary","k","n","Project","SyntaxKind","getLoc","filePath","node","sf","line","column","analyzeMatch","source","project","matchSites","nonExhaustive","text","full","arms","hasExhaustive","hasOrElse","tagMatch","tag","arm","site","Project","SyntaxKind","getLoc","filePath","node","sf","line","column","extractPathFromTemplate","template","path","walkAddChainForApiContext","apiId","groupName","current","i","parent","call","callee","receiver","makeMatch","groupMatch","result","analyzePlatformUsage","source","project","locations","http","filesystem","sockets","terminal","workers","commands","keyValueStore","multipart","codecs","openApi","platforms","fileSystemOps","commandOps","routeDefinitions","middlewareChain","cliCommands","expr","fsOps","method","op","cmdOps","methods","m","args","name","ctx","mwName","nameArg","hasSchema","a","SyntaxKind","SyntaxKind","resolveSchemaNode","node","sf","project","SyntaxKind","ident","symbol","decls","decl","init","exportName","importDecl","spec","currentPath","resolvedPath","resolveModulePath","targetSf","expDecls","ed","name","vars","v","schemaToJsonSchema","defs","resolved","walkSchema","text","call","args","objArg","obj","properties","required","prop","pa","propText","propSchema","result","oneOf","a","s","inner","literalMatch","literalNumMatch","literalBoolMatch","getLoc","filePath","node","sf","line","column","extractPathFromTemplate","template","path","extractAnnotations","_sf","_filePath","result","current","i","parent","SyntaxKind","call","callee","args","tagArg","valueArg","v","extractEndpointSchemas","endpointBase","project","schemaArg","json","schemaToJsonSchema","extractEndpoint","method","name","annotations","schemas","collectEndpointsFromGroup","groupMakeNode","endpoints","methods","seen","addArgs","collectAddArgsFromChain","findEndpointBase","schemaMethods","c","expr","m","hasMethod","notChained","s","receiver","resolveToEndpointOrAdd","n","symbol","decls","decl","init","vars","visit","resolved","base","ep","arg","extractGroupInfo","groupCall","groupPrefix","optsArg","topLevel","topLevelProp","extractPrefixFromChain","makeNode","topAdd","makeExpr","isApiMake","isGroupMake","inner","collectGroupsFromApiRoot","groups","chainMethods","getMakeFromAddChain","resolveToGroupOrApi","processArg","group","a","findApiRootFromMake","recCall","extractHttpApiStructure","sourceFile","results","filePathResolved","seenApiIds","apiId","root","renderApiDocsMarkdown","structures","lines","api","apiPrefix","group","groupPrefix","ep","fullPath","desc","dep","renderApiDocsMermaid","nodeId","ids","id","prefix","n","apiNode","groupNode","epNode","renderOpenApiPaths","paths","path","op","pathOp","params","name","schema","Project","SyntaxKind","getLoc","filePath","node","sf","line","column","analyzeTestingPatterns","source","project","locations","testClockUsed","testContextUsed","mockLayers","runInTests","effectVitestUsed","effectVitestImported","sharedLayerUsed","testAnnotationsUsed","flakyTestUsed","exitAssertionsUsed","testServicesUsed","fastCheckUsed","propertyTestUsed","decl","specifier","expr","loc","readFile","join","VERSION_RE","parseVersion","version","m","getEffectVersion","dir","pkgPath","raw","pkg","effectVersion","clean","checkVersionCompat","projectRoot","deprecationWarnings","suggestion","Option","collectBindings","nodes","bindings","serviceYields","index","node","gen","y","callee","binding","children","getStaticChildren","analyzeGenYields","ir","usedIndices","b","unusedYieldIndices","i","Project","SyntaxKind","getLoc","filePath","node","sf","line","column","analyzeSqlPatterns","source","project","locations","sqlClientUsed","withTransaction","schemaDefs","queryInLoop","resolvers","migrations","queriesInLoops","expr","loc","args","nameArg","loopKinds","loopKind","loop","text","loopLoc","Project","SyntaxKind","getLoc","filePath","node","sf","line","column","analyzeRpcPatterns","source","project","locations","rpcDefined","routers","clientCalls","rpcDefinitions","expr","loc","args","nameArg","nodeText","isStreaming","Project","SyntaxKind","getLoc","filePath","node","sf","line","column","analyzeRequestBatching","source","project","locations","requestTagged","resolverBatched","withBatching","withCaching","expr","loc","Project","SyntaxKind","getLoc","filePath","node","sf","line","column","analyzeStm","source","project","locations","commitSites","tRefs","tMaps","tQueues","retryUsed","expr","loc","exportForPlayground","ir","mermaid","renderStaticMermaid","encodePlaygroundPayload","payload","decodePlaygroundPayload","encoded","json","createHash","readFile","writeFile","mkdir","stat","join","CACHE_DIR","CACHE_VERSION","contentHash","content","cachePath","baseDir","filePath","safe","getCached","path","hash","raw","entry","setCached","irs","dir","VariableDeclarationKind","createConstCache","sourceFile","resolveConst","name","cache","cached","variableDeclarations","decl","sentinel","result","initializer","resolveNode","node","Node","loadTsMorph","elements","values","element","elementResult","properties","obj","prop","refResult","nameNode","valueResult","expression","callee","args","arg","argResult","constValueToJS","value","k","v","extractStringArray","strings","item","extractString","Option","CONTAINER_TYPES","collectStepsWithContext","node","containerType","index","results","children","Option","getStaticChildren","nextContainer","childIdx","child","childResults","countContainerTypes","counts","walk","diffPrograms","before","after","options","detectRenames","regressionMode","beforeSteps","afterSteps","beforeMap","s","afterMap","matchedBefore","matchedAfter","entries","afterStep","beforeStep","unmatchedBefore","unmatchedAfter","candidate","bs","as2","structuralChanges","beforeContainers","afterContainers","allContainerKeys","key","bCount","aCount","i","summary","e","sc","KIND_ICONS","formatStepLine","entry","icon","callee","renderDiffMarkdown","diff","options","showUnchanged","title","lines","visibleSteps","s","sc","prefix","renderDiffJSON","diff","options","buildStepIdMap","mermaidOutput","map","nodePattern","match","id","renderDiffMermaid","after","diff","options","direction","showRemoved","baseMermaid","renderStaticMermaid","_stepIdMap","addedIds","s","_removedIds","movedIds","renamedIds","irToMermaid","lines","styleLines","line","nodeMatch","mermaidId","label","step","irId","phantomId","execSync","parseSourceArg","arg","gitRefMatch","resolveGitSource","ref","filePath","cwd","error","msg","Option","hasCauseSignals","node","Option","getStaticChildren","selectFormats","ir","stats","root","top","s","b","inferBestDiagramType","Option","collectForks","nodes","forks","joinIds","node","fiber","children","getStaticChildren","classifyFork","fork","hasJoin","analyzeFiberLeaks","ir","rawForks","risk","info","potentialLeaks","f","daemonForks","safeForks","uncertain","formatFiberLeakReport","analysis","lines","leak","loc","df","Option","untaggedYieldRule","ir","issues","checkNode","node","_parentId","isStaticGeneratorNode","yield_","isStaticEffectNode","childrenOpt","getStaticChildren","child","missingErrorHandlerRule","hasErrorHandler","currentHasHandler","isStaticErrorHandlerNode","op","collectUsedNamesInSubtree","used","visit","callee","c","deadCodeRule","yields","i","varName","usedLater","j","laterYield","name","complexLayerRule","layerCount","layerProvideCount","countLayers","catchAllVsCatchTagRule","errorTypeTooWideRule","err","unboundedParallelismRule","isStaticParallelNode","redundantPipeRule","isStaticPipeNode","orDieWarningRule","DEFAULT_LINT_RULES","lintEffectProgram","rules","allIssues","rule","errors","warnings","infos","formatLintReport","result","programName","lines","issue","icon"]}