footprintjs 9.9.0 → 9.10.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.
Files changed (227) hide show
  1. package/AGENTS.md +9 -9
  2. package/CLAUDE.md +82 -753
  3. package/README.md +51 -20
  4. package/dist/esm/advanced.d.ts +52 -0
  5. package/dist/esm/detach.d.ts +59 -0
  6. package/dist/esm/index.d.ts +202 -0
  7. package/dist/esm/lib/builder/FlowChartBuilder.d.ts +475 -0
  8. package/dist/esm/lib/builder/FlowChartBuilder.js +4 -3
  9. package/dist/esm/lib/builder/index.d.ts +11 -0
  10. package/dist/esm/lib/builder/structure/StructureRecorder.d.ts +349 -0
  11. package/dist/esm/lib/builder/structure/StructureRecorderDispatcher.d.ts +77 -0
  12. package/dist/esm/lib/builder/typedFlowChart.d.ts +25 -0
  13. package/dist/esm/lib/builder/types.d.ts +154 -0
  14. package/dist/esm/lib/capture/envelope.d.ts +169 -0
  15. package/dist/esm/lib/capture/index.d.ts +16 -0
  16. package/dist/esm/lib/capture/policies.d.ts +42 -0
  17. package/dist/esm/lib/capture/summarize.d.ts +65 -0
  18. package/dist/esm/lib/contract/defineContract.d.ts +18 -0
  19. package/dist/esm/lib/contract/index.d.ts +14 -0
  20. package/dist/esm/lib/contract/openapi.d.ts +18 -0
  21. package/dist/esm/lib/contract/schema.d.ts +13 -0
  22. package/dist/esm/lib/contract/types.d.ts +105 -0
  23. package/dist/esm/lib/decide/decide.d.ts +47 -0
  24. package/dist/esm/lib/decide/evaluator.d.ts +39 -0
  25. package/dist/esm/lib/decide/evidence.d.ts +22 -0
  26. package/dist/esm/lib/decide/index.d.ts +12 -0
  27. package/dist/esm/lib/decide/types.d.ts +111 -0
  28. package/dist/esm/lib/detach/drivers/immediate.d.ts +39 -0
  29. package/dist/esm/lib/detach/drivers/microtaskBatch.d.ts +57 -0
  30. package/dist/esm/lib/detach/drivers/sendBeacon.d.ts +38 -0
  31. package/dist/esm/lib/detach/drivers/setImmediate.d.ts +32 -0
  32. package/dist/esm/lib/detach/drivers/setTimeout.d.ts +34 -0
  33. package/dist/esm/lib/detach/drivers/workerThread.d.ts +50 -0
  34. package/dist/esm/lib/detach/flush.d.ts +62 -0
  35. package/dist/esm/lib/detach/handle.d.ts +83 -0
  36. package/dist/esm/lib/detach/registry.d.ts +82 -0
  37. package/dist/esm/lib/detach/runChild.d.ts +41 -0
  38. package/dist/esm/lib/detach/spawn.d.ts +64 -0
  39. package/dist/esm/lib/detach/types.d.ts +200 -0
  40. package/dist/esm/lib/engine/errors/errorInfo.d.ts +46 -0
  41. package/dist/esm/lib/engine/errors/index.d.ts +2 -0
  42. package/dist/esm/lib/engine/graph/StageNode.d.ts +108 -0
  43. package/dist/esm/lib/engine/graph/index.d.ts +2 -0
  44. package/dist/esm/lib/engine/handlers/ChildrenExecutor.d.ts +32 -0
  45. package/dist/esm/lib/engine/handlers/ContinuationResolver.d.ts +95 -0
  46. package/dist/esm/lib/engine/handlers/DeciderHandler.d.ts +56 -0
  47. package/dist/esm/lib/engine/handlers/NodeResolver.d.ts +41 -0
  48. package/dist/esm/lib/engine/handlers/RuntimeStructureManager.d.ts +37 -0
  49. package/dist/esm/lib/engine/handlers/SelectorHandler.d.ts +27 -0
  50. package/dist/esm/lib/engine/handlers/StageRunner.d.ts +17 -0
  51. package/dist/esm/lib/engine/handlers/SubflowExecutor.d.ts +34 -0
  52. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +8 -1
  53. package/dist/esm/lib/engine/handlers/SubflowInputMapper.d.ts +40 -0
  54. package/dist/esm/lib/engine/handlers/index.d.ts +13 -0
  55. package/dist/esm/lib/engine/handlers/types.d.ts +32 -0
  56. package/dist/esm/lib/engine/index.d.ts +28 -0
  57. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +139 -0
  58. package/dist/esm/lib/engine/narrative/FlowRecorderDispatcher.d.ts +47 -0
  59. package/dist/esm/lib/engine/narrative/NarrativeFlowRecorder.d.ts +34 -0
  60. package/dist/esm/lib/engine/narrative/NullControlFlowNarrativeGenerator.d.ts +27 -0
  61. package/dist/esm/lib/engine/narrative/index.d.ts +15 -0
  62. package/dist/esm/lib/engine/narrative/narrativeTypes.d.ts +196 -0
  63. package/dist/esm/lib/engine/narrative/recorders/AdaptiveNarrativeFlowRecorder.d.ts +25 -0
  64. package/dist/esm/lib/engine/narrative/recorders/ManifestFlowRecorder.d.ts +69 -0
  65. package/dist/esm/lib/engine/narrative/recorders/MilestoneNarrativeFlowRecorder.d.ts +24 -0
  66. package/dist/esm/lib/engine/narrative/recorders/ProgressiveNarrativeFlowRecorder.d.ts +30 -0
  67. package/dist/esm/lib/engine/narrative/recorders/RLENarrativeFlowRecorder.d.ts +25 -0
  68. package/dist/esm/lib/engine/narrative/recorders/SeparateNarrativeFlowRecorder.d.ts +32 -0
  69. package/dist/esm/lib/engine/narrative/recorders/SilentNarrativeFlowRecorder.d.ts +25 -0
  70. package/dist/esm/lib/engine/narrative/recorders/WindowedNarrativeFlowRecorder.d.ts +29 -0
  71. package/dist/esm/lib/engine/narrative/recorders/index.d.ts +9 -0
  72. package/dist/esm/lib/engine/narrative/types.d.ts +384 -0
  73. package/dist/esm/lib/engine/runtimeStageId.d.ts +103 -0
  74. package/dist/esm/lib/engine/traversal/FlowchartTraverser.d.ts +376 -0
  75. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +1 -1
  76. package/dist/esm/lib/engine/traversal/index.d.ts +2 -0
  77. package/dist/esm/lib/engine/types.d.ts +417 -0
  78. package/dist/esm/lib/engine/walkSubflowSpec.d.ts +95 -0
  79. package/dist/esm/lib/memory/DiagnosticCollector.d.ts +33 -0
  80. package/dist/esm/lib/memory/EventLog.d.ts +27 -0
  81. package/dist/esm/lib/memory/SharedMemory.d.ts +31 -0
  82. package/dist/esm/lib/memory/StageContext.d.ts +368 -0
  83. package/dist/esm/lib/memory/StageContext.js +44 -2
  84. package/dist/esm/lib/memory/TransactionBuffer.d.ts +183 -0
  85. package/dist/esm/lib/memory/TransactionBuffer.js +35 -13
  86. package/dist/esm/lib/memory/backtrack.d.ts +252 -0
  87. package/dist/esm/lib/memory/backtrack.js +79 -8
  88. package/dist/esm/lib/memory/commitLogUtils.d.ts +41 -0
  89. package/dist/esm/lib/memory/index.d.ts +14 -0
  90. package/dist/esm/lib/memory/pathOps.d.ts +54 -0
  91. package/dist/esm/lib/memory/types.d.ts +230 -0
  92. package/dist/esm/lib/memory/types.js +1 -1
  93. package/dist/esm/lib/memory/utils.d.ts +124 -0
  94. package/dist/esm/lib/observer-queue/deferredDispatcher.d.ts +169 -0
  95. package/dist/esm/lib/observer-queue/flushDriver.d.ts +124 -0
  96. package/dist/esm/lib/observer-queue/index.d.ts +25 -0
  97. package/dist/esm/lib/observer-queue/mergedQueue.d.ts +85 -0
  98. package/dist/esm/lib/observer-queue/ring.d.ts +99 -0
  99. package/dist/esm/lib/pause/index.d.ts +2 -0
  100. package/dist/esm/lib/pause/types.d.ts +238 -0
  101. package/dist/esm/lib/pause/types.js +2 -2
  102. package/dist/esm/lib/reactive/allowlist.d.ts +30 -0
  103. package/dist/esm/lib/reactive/arrayTraps.d.ts +23 -0
  104. package/dist/esm/lib/reactive/createTypedScope.d.ts +24 -0
  105. package/dist/esm/lib/reactive/index.d.ts +14 -0
  106. package/dist/esm/lib/reactive/pathBuilder.d.ts +31 -0
  107. package/dist/esm/lib/reactive/types.d.ts +159 -0
  108. package/dist/esm/lib/reactive/types.js +1 -1
  109. package/dist/esm/lib/recorder/BoundaryStateStore.d.ts +115 -0
  110. package/dist/esm/lib/recorder/CombinedRecorder.d.ts +215 -0
  111. package/dist/esm/lib/recorder/CombinedRecorder.js +2 -2
  112. package/dist/esm/lib/recorder/CommitRangeIndex.d.ts +147 -0
  113. package/dist/esm/lib/recorder/CompositeRecorder.d.ts +95 -0
  114. package/dist/esm/lib/recorder/ControlDepRecorder.d.ts +133 -0
  115. package/dist/esm/lib/recorder/EmitRecorder.d.ts +135 -0
  116. package/dist/esm/lib/recorder/InOutRecorder.d.ts +176 -0
  117. package/dist/esm/lib/recorder/KeyedStore.d.ts +70 -0
  118. package/dist/esm/lib/recorder/QualityRecorder.d.ts +122 -0
  119. package/dist/esm/lib/recorder/RecorderOperation.d.ts +35 -0
  120. package/dist/esm/lib/recorder/SequenceStore.d.ts +120 -0
  121. package/dist/esm/lib/recorder/TopologyRecorder.d.ts +165 -0
  122. package/dist/esm/lib/recorder/TopologyRecorder.js +1 -1
  123. package/dist/esm/lib/recorder/index.d.ts +9 -0
  124. package/dist/esm/lib/recorder/invokeHook.d.ts +32 -0
  125. package/dist/esm/lib/recorder/qualityTrace.d.ts +54 -0
  126. package/dist/esm/lib/runner/ComposableRunner.d.ts +33 -0
  127. package/dist/esm/lib/runner/DeferredObserverTier.d.ts +204 -0
  128. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +162 -0
  129. package/dist/esm/lib/runner/ExecutionRuntime.js +16 -1
  130. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +660 -0
  131. package/dist/esm/lib/runner/FlowChartExecutor.js +35 -3
  132. package/dist/esm/lib/runner/RunContext.d.ts +42 -0
  133. package/dist/esm/lib/runner/RunnableChart.d.ts +57 -0
  134. package/dist/esm/lib/runner/checkpointSanitize.d.ts +44 -0
  135. package/dist/esm/lib/runner/getSubtreeSnapshot.d.ts +70 -0
  136. package/dist/esm/lib/runner/index.d.ts +11 -0
  137. package/dist/esm/lib/runner/runId.d.ts +45 -0
  138. package/dist/esm/lib/runner/validateInput.d.ts +11 -0
  139. package/dist/esm/lib/schema/detect.d.ts +32 -0
  140. package/dist/esm/lib/schema/errors.d.ts +36 -0
  141. package/dist/esm/lib/schema/index.d.ts +14 -0
  142. package/dist/esm/lib/schema/validate.d.ts +33 -0
  143. package/dist/esm/lib/scope/ScopeFacade.d.ts +250 -0
  144. package/dist/esm/lib/scope/detectCircular.d.ts +47 -0
  145. package/dist/esm/lib/scope/index.d.ts +16 -0
  146. package/dist/esm/lib/scope/protection/createProtectedScope.d.ts +9 -0
  147. package/dist/esm/lib/scope/protection/index.d.ts +2 -0
  148. package/dist/esm/lib/scope/protection/readonlyInput.d.ts +26 -0
  149. package/dist/esm/lib/scope/protection/types.d.ts +13 -0
  150. package/dist/esm/lib/scope/providers/baseStateCompatible.d.ts +24 -0
  151. package/dist/esm/lib/scope/providers/guards.d.ts +14 -0
  152. package/dist/esm/lib/scope/providers/index.d.ts +6 -0
  153. package/dist/esm/lib/scope/providers/providers.d.ts +8 -0
  154. package/dist/esm/lib/scope/providers/registry.d.ts +11 -0
  155. package/dist/esm/lib/scope/providers/resolve.d.ts +8 -0
  156. package/dist/esm/lib/scope/providers/types.d.ts +40 -0
  157. package/dist/esm/lib/scope/recorders/DebugRecorder.d.ts +63 -0
  158. package/dist/esm/lib/scope/recorders/MetricRecorder.d.ts +125 -0
  159. package/dist/esm/lib/scope/recorders/index.d.ts +5 -0
  160. package/dist/esm/lib/scope/recorders/summarizeValue.d.ts +7 -0
  161. package/dist/esm/lib/scope/recorders/summarizeValue.js +3 -3
  162. package/dist/esm/lib/scope/state/installResolvers.d.ts +4 -0
  163. package/dist/esm/lib/scope/state/zod/defineScopeFromZod.d.ts +9 -0
  164. package/dist/esm/lib/scope/state/zod/index.d.ts +5 -0
  165. package/dist/esm/lib/scope/state/zod/resolver.d.ts +5 -0
  166. package/dist/esm/lib/scope/state/zod/schema/builder.d.ts +12 -0
  167. package/dist/esm/lib/scope/state/zod/scopeFactory.d.ts +9 -0
  168. package/dist/esm/lib/scope/state/zod/utils/validateHelper.d.ts +25 -0
  169. package/dist/esm/lib/scope/types.d.ts +142 -0
  170. package/dist/esm/lib/slice/elementProvenance.d.ts +74 -0
  171. package/dist/esm/lib/slice/elementProvenance.js +181 -0
  172. package/dist/esm/lib/slice/index.d.ts +16 -0
  173. package/dist/esm/lib/slice/index.js +16 -0
  174. package/dist/esm/lib/slice/keysReadSources.d.ts +51 -0
  175. package/dist/esm/lib/slice/keysReadSources.js +96 -0
  176. package/dist/esm/lib/slice/serialize.d.ts +40 -0
  177. package/dist/esm/lib/slice/serialize.js +97 -0
  178. package/dist/esm/lib/slice/sliceForKey.d.ts +47 -0
  179. package/dist/esm/lib/slice/sliceForKey.js +72 -0
  180. package/dist/esm/lib/slice/types.d.ts +240 -0
  181. package/dist/esm/lib/slice/types.js +20 -0
  182. package/dist/esm/recorders.d.ts +70 -0
  183. package/dist/esm/trace.d.ts +57 -0
  184. package/dist/esm/trace.js +2 -1
  185. package/dist/esm/zod.d.ts +18 -0
  186. package/dist/lib/builder/FlowChartBuilder.js +4 -3
  187. package/dist/lib/engine/handlers/SubflowExecutor.js +8 -1
  188. package/dist/lib/engine/traversal/FlowchartTraverser.js +1 -1
  189. package/dist/lib/memory/StageContext.js +44 -2
  190. package/dist/lib/memory/TransactionBuffer.js +35 -13
  191. package/dist/lib/memory/backtrack.js +79 -8
  192. package/dist/lib/memory/types.js +1 -1
  193. package/dist/lib/pause/types.js +2 -2
  194. package/dist/lib/reactive/types.js +1 -1
  195. package/dist/lib/recorder/CombinedRecorder.js +2 -2
  196. package/dist/lib/recorder/TopologyRecorder.js +1 -1
  197. package/dist/lib/runner/ExecutionRuntime.js +16 -1
  198. package/dist/lib/runner/FlowChartExecutor.js +35 -3
  199. package/dist/lib/scope/recorders/summarizeValue.js +3 -3
  200. package/dist/lib/slice/elementProvenance.js +186 -0
  201. package/dist/lib/slice/index.js +28 -0
  202. package/dist/lib/slice/keysReadSources.js +102 -0
  203. package/dist/lib/slice/serialize.js +102 -0
  204. package/dist/lib/slice/sliceForKey.js +77 -0
  205. package/dist/lib/slice/types.js +21 -0
  206. package/dist/trace.js +12 -2
  207. package/dist/types/lib/builder/FlowChartBuilder.d.ts +25 -2
  208. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +1 -1
  209. package/dist/types/lib/memory/StageContext.d.ts +28 -1
  210. package/dist/types/lib/memory/TransactionBuffer.d.ts +10 -1
  211. package/dist/types/lib/memory/backtrack.d.ts +26 -0
  212. package/dist/types/lib/memory/types.d.ts +26 -0
  213. package/dist/types/lib/pause/types.d.ts +4 -3
  214. package/dist/types/lib/reactive/types.d.ts +1 -1
  215. package/dist/types/lib/recorder/CombinedRecorder.d.ts +1 -1
  216. package/dist/types/lib/recorder/TopologyRecorder.d.ts +1 -1
  217. package/dist/types/lib/runner/ExecutionRuntime.d.ts +15 -1
  218. package/dist/types/lib/runner/FlowChartExecutor.d.ts +34 -3
  219. package/dist/types/lib/scope/recorders/summarizeValue.d.ts +2 -2
  220. package/dist/types/lib/slice/elementProvenance.d.ts +74 -0
  221. package/dist/types/lib/slice/index.d.ts +16 -0
  222. package/dist/types/lib/slice/keysReadSources.d.ts +51 -0
  223. package/dist/types/lib/slice/serialize.d.ts +40 -0
  224. package/dist/types/lib/slice/sliceForKey.d.ts +47 -0
  225. package/dist/types/lib/slice/types.d.ts +240 -0
  226. package/dist/types/trace.d.ts +3 -0
  227. package/package.json +75 -21
@@ -0,0 +1,475 @@
1
+ /**
2
+ * FlowChartBuilder — Fluent API for constructing flowchart execution graphs.
3
+ *
4
+ * Builds StageNode trees and SerializedPipelineStructure (JSON) in tandem.
5
+ * Zero dependencies on old code — only imports from local types.
6
+ *
7
+ * The builder creates two parallel structures:
8
+ * 1. StageNode tree — runtime graph with embedded functions
9
+ * 2. SerializedPipelineStructure — JSON-safe structure for visualization
10
+ *
11
+ * The execute() convenience method is intentionally omitted —
12
+ * it belongs in the runner layer (Phase 5).
13
+ */
14
+ import type { ScopeFactory } from '../engine/types.js';
15
+ import type { PausableHandler } from '../pause/types.js';
16
+ import type { TypedScope } from '../reactive/types.js';
17
+ import { type RunnableFlowChart } from '../runner/RunnableChart.js';
18
+ import type { StructureEdgeKind, StructureRecorder } from './structure/StructureRecorder.js';
19
+ import { StructureRecorderDispatcher } from './structure/StructureRecorderDispatcher.js';
20
+ import { type TypedStageFunction } from './typedFlowChart.js';
21
+ import type { FlowChart, FlowChartOptions, FlowChartSpec, ILogger, SerializedPipelineStructure, SimplifiedParallelSpec, StageFunction, StageNode, StreamLifecycleHandler, StreamTokenHandler, SubflowMountOptions } from './types.js';
22
+ /**
23
+ * Fluent helper returned by addDeciderFunction to add branches.
24
+ * `end()` sets `deciderFn = true` — the fn IS the decider.
25
+ */
26
+ export declare class DeciderList<TOut = any, TScope = any> {
27
+ private readonly b;
28
+ private readonly curNode;
29
+ private readonly curSpec;
30
+ private readonly branchIds;
31
+ private defaultId?;
32
+ private readonly parentDescriptionParts;
33
+ private readonly parentStageDescriptions;
34
+ private readonly reservedStepNumber;
35
+ private readonly deciderDescription?;
36
+ private readonly branchDescInfo;
37
+ constructor(builder: FlowChartBuilder<TOut, TScope>, curNode: StageNode<TOut, TScope>, curSpec: SerializedPipelineStructure, parentDescriptionParts?: string[], parentStageDescriptions?: Map<string, string>, reservedStepNumber?: number, deciderDescription?: string);
38
+ addFunctionBranch(id: string, name: string, fn?: StageFunction<TOut, TScope>, description?: string,
39
+ /** `{ loopTo }` declares this branch loops back to an already-declared
40
+ * stage — the loop is SOURCED FROM THIS BRANCH (not the decider). */
41
+ options?: {
42
+ readonly loopTo?: string;
43
+ }): DeciderList<TOut, TScope>;
44
+ /**
45
+ * Add a pausable stage as a decider branch.
46
+ *
47
+ * When this branch is chosen, the handler's `execute` runs. If it returns
48
+ * data, the pipeline pauses. On resume, `handler.resume` runs with the
49
+ * human's input. If `execute` returns void, the stage continues normally
50
+ * (conditional pause).
51
+ */
52
+ addPausableFunctionBranch(id: string, name: string, handler: PausableHandler<TScope>, description?: string,
53
+ /** `{ loopTo }` declares this branch loops back to an already-declared
54
+ * stage — the loop is SOURCED FROM THIS BRANCH (not the decider). */
55
+ options?: {
56
+ readonly loopTo?: string;
57
+ }): DeciderList<TOut, TScope>;
58
+ addSubFlowChartBranch(id: string, subflow: FlowChart<any, any>, mountName?: string, options?: SubflowMountOptions): DeciderList<TOut, TScope>;
59
+ addLazySubFlowChartBranch(id: string, resolver: () => FlowChart<any, any>, mountName?: string, options?: SubflowMountOptions): DeciderList<TOut, TScope>;
60
+ addBranchList(branches: Array<{
61
+ id: string;
62
+ name: string;
63
+ fn?: StageFunction<TOut, TScope>;
64
+ }>): DeciderList<TOut, TScope>;
65
+ setDefault(id: string): DeciderList<TOut, TScope>;
66
+ /**
67
+ * Attach a loop-back edge to the LAST-added branch, so the loop is sourced
68
+ * from THAT branch node (e.g. `'tool-calls' → loopTo('context')`) rather than
69
+ * from the decider. The chart then reads honestly: the decider splits into a
70
+ * looping branch `[ToolCalls → back to Context]` and a terminating branch
71
+ * `[Final → end]`, instead of a single loop hanging off the decider.
72
+ *
73
+ * No engine change is needed: the runtime runs the chosen branch and then
74
+ * follows that branch node's OWN `next` — and a `next` flagged `isLoopRef`
75
+ * routes back to the target exactly like the decider's own loop does. This
76
+ * method just lets the builder express what the engine already supports.
77
+ *
78
+ * Targets the branch added immediately before this call (chain it right after
79
+ * the branch's `addFunctionBranch`/`addPausableFunctionBranch`/
80
+ * `addSubFlowChartBranch`). Mirrors `FlowChartBuilder.loopTo` validation.
81
+ *
82
+ * Works on a SUBFLOW branch too: the branch node carries both its subflow
83
+ * resolver AND the loop-back `next` — they coexist safely (the runtime runs
84
+ * the subflow, then follows the loop ref). The target must be a stage already
85
+ * declared BEFORE the decider (e.g. an upstream `context`); branch ids and the
86
+ * synthetic `'default'` clone are NOT valid loop targets.
87
+ */
88
+ loopTo(stageId: string): DeciderList<TOut, TScope>;
89
+ /**
90
+ * Decorate ONE branch node/spec with a loop-back edge to `stageId`. Shared by
91
+ * the positional `loopTo()` (which targets the last-added branch) AND the
92
+ * per-branch `{ loopTo }` option on `addFunctionBranch` /
93
+ * `addPausableFunctionBranch` / `addSubFlowChartBranch`. Either way the loop
94
+ * SOURCE is the branch — so visualizers read `tool-calls → context`, never
95
+ * `Route → context`. Validates the target is a stage declared BEFORE the
96
+ * decider (branch ids / the synthetic 'default' clone are not valid targets).
97
+ */
98
+ private _applyBranchLoop;
99
+ end(): FlowChartBuilder<TOut, TScope>;
100
+ }
101
+ export declare class SelectorFnList<TOut = any, TScope = any> {
102
+ private readonly b;
103
+ private readonly curNode;
104
+ private readonly curSpec;
105
+ private readonly branchIds;
106
+ private readonly parentDescriptionParts;
107
+ private readonly parentStageDescriptions;
108
+ private readonly reservedStepNumber;
109
+ private readonly selectorDescription?;
110
+ private readonly branchDescInfo;
111
+ constructor(builder: FlowChartBuilder<TOut, TScope>, curNode: StageNode<TOut, TScope>, curSpec: SerializedPipelineStructure, parentDescriptionParts?: string[], parentStageDescriptions?: Map<string, string>, reservedStepNumber?: number, selectorDescription?: string);
112
+ addFunctionBranch(id: string, name: string, fn?: StageFunction<TOut, TScope>, description?: string): SelectorFnList<TOut, TScope>;
113
+ /**
114
+ * Add a pausable stage as a selector branch.
115
+ *
116
+ * When this branch is selected, the handler's `execute` runs. If it returns
117
+ * data, the pipeline pauses. On resume, `handler.resume` runs with the
118
+ * human's input. If `execute` returns void, the stage continues normally.
119
+ */
120
+ addPausableFunctionBranch(id: string, name: string, handler: PausableHandler<TScope>, description?: string): SelectorFnList<TOut, TScope>;
121
+ addSubFlowChartBranch(id: string, subflow: FlowChart<any, any>, mountName?: string, options?: SubflowMountOptions): SelectorFnList<TOut, TScope>;
122
+ addLazySubFlowChartBranch(id: string, resolver: () => FlowChart<any, any>, mountName?: string, options?: SubflowMountOptions): SelectorFnList<TOut, TScope>;
123
+ addBranchList(branches: Array<{
124
+ id: string;
125
+ name: string;
126
+ fn?: StageFunction<TOut, TScope>;
127
+ }>): SelectorFnList<TOut, TScope>;
128
+ end(): FlowChartBuilder<TOut, TScope>;
129
+ }
130
+ export declare class FlowChartBuilder<TOut = any, TScope = any> {
131
+ private _root?;
132
+ private _rootSpec?;
133
+ private _cursor?;
134
+ private _cursorSpec?;
135
+ private _stageMap;
136
+ _subflowDefs: Map<string, {
137
+ root: StageNode<TOut, TScope>;
138
+ }>;
139
+ private _streamHandlers;
140
+ /**
141
+ * L7.3 — Build-time observer fan-out. Owned by the builder so every
142
+ * `addX()` method can fire `StructureRecorder` events at the natural
143
+ * moment of the corresponding mutation. Dispatcher is allocated
144
+ * lazily on first attach to keep the zero-recorder path allocation-
145
+ * free.
146
+ */
147
+ private _structureDispatcher?;
148
+ /**
149
+ * L7.3 — Sealed-after-build flag (Panel 2 phase invariant). Flips
150
+ * to `true` when `.build()` returns; subsequent `attachStructureRecorder`
151
+ * throws. Prevents the footgun where a consumer attaches a recorder
152
+ * mid-execution and gets partial structure data (missed every event
153
+ * already fired during construction).
154
+ */
155
+ private _sealed;
156
+ private _enableNarrative;
157
+ private _logger?;
158
+ private _descriptionParts;
159
+ private _stepCounter;
160
+ private _stageDescriptions;
161
+ private _stageStepMap;
162
+ private _knownStageIds;
163
+ private _inputSchema?;
164
+ private _outputSchema?;
165
+ private _outputMapper?;
166
+ private _scopeFactory?;
167
+ /**
168
+ * Attach a `StructureRecorder` for build-phase observation. Multiple
169
+ * recorders coexist (same id allowed; iteration order = attach
170
+ * order). Throws if called after `.build()` — the chart is sealed at
171
+ * that point and any recorder attached late would miss every event
172
+ * fired during construction.
173
+ *
174
+ * **Seed replay**: when this is called AFTER `start()` has already
175
+ * fired (i.e., after the `flowChart()` factory returns), the
176
+ * just-attached recorder receives a one-time `onStageAdded` for the
177
+ * root stage so it observes the seed. Only the new recorder sees
178
+ * the replay; already-attached recorders are not re-fired.
179
+ *
180
+ * **Mid-chain attach caveat**: a recorder attached AFTER one or more
181
+ * `addX()` calls receives the seed replay but MISSES every
182
+ * intermediate event. Attach BEFORE the first `addX()` for complete
183
+ * capture.
184
+ *
185
+ * Public for now to enable direct attach in tests + early consumers.
186
+ * L7.4 will wire `flowChart(..., { structureRecorders: [...] })` as
187
+ * an additional registration site; this method will remain.
188
+ */
189
+ attachStructureRecorder(recorder: StructureRecorder): this;
190
+ /**
191
+ * Inspect accumulated `StructureBuildError`s. Returns empty array
192
+ * when no recorders attached OR no errors occurred. Returns a
193
+ * defensive copy — caller mutations do not affect subsequent calls.
194
+ *
195
+ * **Call on the BUILDER, not the chart returned by `.build()`.**
196
+ * Capture the builder reference before `.build()` if you need
197
+ * post-build access:
198
+ * ```ts
199
+ * const builder = flowChart(...).attachStructureRecorder(rec);
200
+ * const chart = builder.build();
201
+ * const errors = builder.getStructureBuildErrors();
202
+ * ```
203
+ */
204
+ getStructureBuildErrors(): ReturnType<StructureRecorderDispatcher['getErrors']>;
205
+ private _fireStageAdded;
206
+ private _fireEdgeAdded;
207
+ private _fireLoopEdgeAdded;
208
+ /**
209
+ * Fire the `next` edge(s) from a parent spec to a freshly-added
210
+ * node — with convergence expansion when the parent is a
211
+ * fork / decider / selector with branches.
212
+ *
213
+ * A fork at `parent` is semantically `parent ──fork-branch──► child[i]`
214
+ * for each child, and the chained `.addFunction(X)` continues
215
+ * AFTER the fork converges. The runtime semantics are that each
216
+ * child INDEPENDENTLY feeds `X` (parallel completion → join). The
217
+ * literal "edge from parent to X" would misrepresent this —
218
+ * visualizers and topological algorithms would see one edge where
219
+ * there should be N convergence edges.
220
+ *
221
+ * Fix: when `parentSpec` has branch children (fork or branched
222
+ * decider/selector), fire one `next` edge from EACH child to the
223
+ * target. Otherwise fire the single edge from `parentSpec` itself.
224
+ *
225
+ * Loop-reference children (synthetic spec nodes created by
226
+ * `.loopTo()`) are excluded — they're back-edge markers, not
227
+ * convergence sources. A branch that carries an OWN loop-back `next`
228
+ * (a branch-sourced `loopTo`) is likewise skipped — it loops, it does
229
+ * not converge at the linear next stage.
230
+ *
231
+ * A branch carrying `convergeAt` is REDIRECTED: its single convergence
232
+ * edge fires to its named target instead of `targetId` — expressing an
233
+ * unequal-depth merge (e.g. `tools → call-llm`, bypassing `message-api`).
234
+ * The named target is a forward stage, so it is NOT validated here.
235
+ *
236
+ * Call ORDER constraint: must be called BEFORE the cursor advances
237
+ * to the new target. The caller passes the PRE-ADVANCE parent spec.
238
+ */
239
+ private _fireNextEdgeFromParent;
240
+ private _fireDeciderComplete;
241
+ private _fireSubflowMounted;
242
+ /** Sub-builder access (`.b._fireXxx`) is needed by DeciderList /
243
+ * SelectorFnList; expose the dispatcher through internal helpers
244
+ * that go through the same no-op-when-absent guard.
245
+ *
246
+ * @internal — these methods are exposed because TypeScript `private`
247
+ * doesn't traverse class boundaries. Consumer code MUST NOT call
248
+ * them; calling them post-construction lets a hostile caller
249
+ * fabricate structure events and corrupt downstream visualizations
250
+ * or audit trails. The `_` prefix is intentional convention. */
251
+ _fireEdgeAddedFromSubBuilder(from: string, to: string, kind: StructureEdgeKind, label?: string): void;
252
+ /** @internal — see `_fireEdgeAddedFromSubBuilder`. */
253
+ _fireStageAddedFromSubBuilder(spec: SerializedPipelineStructure): void;
254
+ /** @internal — see `_fireEdgeAddedFromSubBuilder`. */
255
+ _fireDeciderCompleteFromSubBuilder(decider: string, type: 'decider' | 'selector', branchIds: string[], defaultBranch?: string): void;
256
+ /** @internal — see `_fireEdgeAddedFromSubBuilder`. */
257
+ _fireSubflowMountedFromSubBuilder(subflowId: string, subflowName: string, rootStageId: string, isLazy?: boolean, subflowSpec?: SerializedPipelineStructure, subflowPath?: string): void;
258
+ /** @internal — see `_fireEdgeAddedFromSubBuilder`. Used by `DeciderList.loopTo`
259
+ * to validate a branch-sourced loop target against the known stage ids
260
+ * (mirrors `FlowChartBuilder.loopTo`'s `_knownStageIds.has` guard). */
261
+ _knownStageIdsHas(id: string): boolean;
262
+ /** @internal — see `_fireEdgeAddedFromSubBuilder`. Used by `DeciderList.loopTo`
263
+ * to fire a loop back-edge SOURCED FROM A BRANCH node (not the decider). */
264
+ _fireLoopEdgeAddedFromSubBuilder(from: string, to: string): void;
265
+ private _appendDescriptionLine;
266
+ private _appendSubflowDescription;
267
+ setLogger(logger: ILogger): this;
268
+ /**
269
+ * Declare the API contract — input validation, output shape, and output mapper.
270
+ * Replaces setInputSchema() + setOutputSchema() + setOutputMapper() in a single call.
271
+ *
272
+ * If a contract with input schema is declared, chart.run() validates input automatically.
273
+ * Contract data is used by chart.toOpenAPI() and chart.toMCPTool().
274
+ */
275
+ contract(opts: {
276
+ input?: unknown;
277
+ output?: unknown;
278
+ mapper?: (finalScope: Record<string, unknown>) => unknown;
279
+ }): this;
280
+ start(name: string, fn: StageFunction<TOut, TScope> | PausableHandler<TScope>, id: string, description?: string): this;
281
+ /**
282
+ * Start a chart whose ROOT stage IS a selector — it runs first (reading
283
+ * args, seeding state, returning the chosen branch ids via `select()`),
284
+ * and its branches attach directly to the root. Mirrors `start()` for the
285
+ * root-node setup, then returns a `SelectorFnList` bound to the root so
286
+ * `.addFunctionBranch()` / `.addSubFlowChartBranch()` / `.end()` work
287
+ * exactly as they do after `addSelectorFunction()`.
288
+ *
289
+ * Use when the first thing a chart does is choose among branches — e.g. a
290
+ * `Context` selector that inits + picks which context slots to engineer,
291
+ * with no separate seed stage before it.
292
+ */
293
+ startSelector(name: string, fn: StageFunction<any, TScope>, id: string, description?: string, options?: {
294
+ failFast?: boolean;
295
+ }): SelectorFnList<TOut, TScope>;
296
+ addFunction(name: string, fn: StageFunction<TOut, TScope>, id: string, description?: string): this;
297
+ addStreamingFunction(name: string, fn: StageFunction<TOut, TScope>, id: string, streamId?: string, description?: string): this;
298
+ /**
299
+ * Add a pausable stage — can pause execution and resume later with input.
300
+ *
301
+ * The handler has two phases:
302
+ * - `execute`: runs first time. Return any non-void value to pause (it becomes
303
+ * the checkpoint's `pauseData`); return void/undefined to continue normally.
304
+ * - `resume`: runs when the flowchart is resumed with input.
305
+ *
306
+ * @example
307
+ * ```typescript
308
+ * .addPausableFunction('ApproveOrder', {
309
+ * execute: async (scope) => {
310
+ * scope.orderId = '123';
311
+ * return { question: 'Approve?' };
312
+ * },
313
+ * resume: async (scope, input) => {
314
+ * scope.approved = input.approved;
315
+ * },
316
+ * }, 'approve-order', 'Manager approval gate')
317
+ * ```
318
+ */
319
+ addPausableFunction(name: string, handler: PausableHandler<TScope>, id: string, description?: string): this;
320
+ /**
321
+ * Add a stage that fires a child flowchart on the given driver and
322
+ * DISCARDS the handle. Pure fire-and-forget — useful for telemetry
323
+ * exports, audit log shipping, cache warm-up.
324
+ *
325
+ * @param id Stable id for this stage (also the stageMap key).
326
+ * @param child The child flowchart to detach.
327
+ * @param options.driver The driver to schedule on (e.g. `microtaskBatchDriver`).
328
+ * @param options.inputMapper Maps the parent's scope to the child's input.
329
+ * Defaults to passing `undefined`.
330
+ * @param options.mountName Display name; defaults to `id`.
331
+ * @param options.description Stage description for narrative + tools.
332
+ *
333
+ * @example
334
+ * ```ts
335
+ * import { microtaskBatchDriver } from 'footprintjs/detach';
336
+ *
337
+ * flowChart('process', processFn, 'process')
338
+ * .addDetachAndForget('telemetry', telemetryChart, {
339
+ * driver: microtaskBatchDriver,
340
+ * inputMapper: (scope) => ({ event: 'processed', orderId: scope.orderId }),
341
+ * })
342
+ * .addFunction('next', nextFn, 'next')
343
+ * .build();
344
+ * ```
345
+ */
346
+ addDetachAndForget(id: string, child: import('./types.js').FlowChart<any, any>, options: {
347
+ driver: import('../detach/types.js').DetachDriver;
348
+ inputMapper?: (scope: TScope) => unknown;
349
+ mountName?: string;
350
+ description?: string;
351
+ }): this;
352
+ /**
353
+ * Add a stage that fires a child flowchart on the given driver and
354
+ * delivers the resulting `DetachHandle` to a consumer-supplied
355
+ * `onHandle` callback. The handle CANNOT be stored in shared state
356
+ * — `StageContext.setValue` calls `structuredClone` which drops
357
+ * class prototypes (and therefore the handle's `.wait()` method).
358
+ *
359
+ * The callback pattern is the explicit alternative: keep handles in
360
+ * a closure-local array (or whatever shape suits) and have a
361
+ * downstream stage `await Promise.all(...)` over them.
362
+ *
363
+ * @example
364
+ * ```ts
365
+ * import { microtaskBatchDriver } from 'footprintjs/detach';
366
+ * import type { DetachHandle } from 'footprintjs/detach';
367
+ *
368
+ * const handles: DetachHandle[] = [];
369
+ *
370
+ * const chart = flowChart('seed', seedFn, 'seed')
371
+ * .addDetachAndJoinLater('eval-a', evalChart, {
372
+ * driver: microtaskBatchDriver,
373
+ * inputMapper: (scope) => scope.configA,
374
+ * onHandle: (h) => handles.push(h),
375
+ * })
376
+ * .addDetachAndJoinLater('eval-b', evalChart, {
377
+ * driver: microtaskBatchDriver,
378
+ * inputMapper: (scope) => scope.configB,
379
+ * onHandle: (h) => handles.push(h),
380
+ * })
381
+ * .addFunction('join', async (scope) => {
382
+ * const settled = await Promise.all(handles.map((h) => h.wait()));
383
+ * scope.results = settled;
384
+ * }, 'join')
385
+ * .build();
386
+ * ```
387
+ *
388
+ * Note: putting `handles` in a module-level closure is fine for
389
+ * single-run scripts. For server code that runs the same chart
390
+ * concurrently across requests, allocate a new closure per run
391
+ * (e.g., wrap chart construction in a factory function) so handles
392
+ * from different runs don't bleed into each other.
393
+ */
394
+ addDetachAndJoinLater(id: string, child: import('./types.js').FlowChart<any, any>, options: {
395
+ driver: import('../detach/types.js').DetachDriver;
396
+ onHandle: (handle: import('../detach/types.js').DetachHandle) => void;
397
+ inputMapper?: (scope: TScope) => unknown;
398
+ mountName?: string;
399
+ description?: string;
400
+ }): this;
401
+ addDeciderFunction(name: string, fn: StageFunction<any, TScope>, id: string, description?: string): DeciderList<TOut, TScope>;
402
+ addSelectorFunction(name: string, fn: StageFunction<any, TScope>, id: string, description?: string, options?: {
403
+ failFast?: boolean;
404
+ }): SelectorFnList<TOut, TScope>;
405
+ addListOfFunction(children: SimplifiedParallelSpec<TOut, TScope>[], options?: {
406
+ failFast?: boolean;
407
+ }): this;
408
+ addSubFlowChart(id: string, subflow: FlowChart<any, any>, mountName?: string, options?: SubflowMountOptions): this;
409
+ addLazySubFlowChart(id: string, resolver: () => FlowChart<TOut, TScope>, mountName?: string, options?: SubflowMountOptions): this;
410
+ addLazySubFlowChartNext(id: string, resolver: () => FlowChart<TOut, TScope>, mountName?: string, options?: SubflowMountOptions): this;
411
+ addSubFlowChartNext(id: string, subflow: FlowChart<any, any>, mountName?: string, options?: SubflowMountOptions): this;
412
+ loopTo(stageId: string): this;
413
+ onStream(handler: StreamTokenHandler): this;
414
+ onStreamStart(handler: StreamLifecycleHandler): this;
415
+ onStreamEnd(handler: StreamLifecycleHandler): this;
416
+ build(): RunnableFlowChart<TOut, TScope>;
417
+ /** Override the scope factory. Rarely needed — auto-embeds TypedScope by default. */
418
+ setScopeFactory(factory: ScopeFactory<TScope>): this;
419
+ toSpec<TResult = SerializedPipelineStructure>(): TResult;
420
+ toMermaid(): string;
421
+ private _needCursor;
422
+ private _needCursorSpec;
423
+ /**
424
+ * Advance the spec cursor. Retained as a method so call sites stay
425
+ * one-liners and future cursor-related side effects have a hook.
426
+ */
427
+ private _advanceCursorSpec;
428
+ _stageMapHas(key: string): boolean;
429
+ _addToMap(id: string, fn: StageFunction<TOut, TScope>): void;
430
+ _mergeStageMap(other: Map<string, StageFunction<TOut, TScope>>, prefix?: string): void;
431
+ _prefixNodeTree(node: StageNode<TOut, TScope>, prefix: string): StageNode<TOut, TScope>;
432
+ _mergeSubflows(subflows: Record<string, {
433
+ root: StageNode<TOut, TScope>;
434
+ }> | undefined, prefix: string): void;
435
+ }
436
+ /**
437
+ * Start a flowchart with its first stage; returns a fluent builder.
438
+ *
439
+ * Chain `.addFunction()` / `.addDeciderFunction()` / `.addSelectorFunction()` /
440
+ * `.addSubFlowChart()` etc. to add more stages, then finish with `.build()`.
441
+ *
442
+ * @param name Human-readable display label for the stage (shown in the narrative/trace).
443
+ * @param fn The stage's work — a `(scope) => …` function, or a `PausableHandler` for human-in-the-loop pauses.
444
+ * @param id Stable stage id used in traces, the commit log, and `runtimeStageId`. Keep it unique within the chart.
445
+ * @param options Optional `{ description?, structureRecorders? }`.
446
+ *
447
+ * @example
448
+ * const chart = flowChart<State>('FetchUser', async (scope) => {
449
+ * scope.user = await getUser();
450
+ * }, 'fetch-user')
451
+ * .addFunction('Process', processFn, 'process')
452
+ * .build();
453
+ *
454
+ * const trace = narrative();
455
+ * const result = await chart.recorder(trace).run();
456
+ * console.log(trace.getEntries().map((e) => e.text).join('\n'));
457
+ */
458
+ export declare function flowChart<TState extends object>(name: string, fn: TypedStageFunction<TState> | PausableHandler<TypedScope<TState>>, id: string, options?: FlowChartOptions): FlowChartBuilder<any, TypedScope<TState>>;
459
+ export declare function flowChart<TOut = any, TScope = any>(name: string, fn: StageFunction<TOut, TScope> | PausableHandler<TScope>, id: string, options?: FlowChartOptions): FlowChartBuilder<TOut, TScope>;
460
+ /**
461
+ * Like `flowChart()`, but the ROOT stage is a SELECTOR — it runs first and
462
+ * its branches attach directly to it (no separate seed stage). Returns a
463
+ * `SelectorFnList`; declare branches then call `.end()` to get the builder
464
+ * back for any subsequent stages.
465
+ *
466
+ * @example
467
+ * flowChartSelector<MyState>('Context', contextSelectorFn, 'context')
468
+ * .addSubFlowChartBranch('sf-system-prompt', sysSlot, 'System Prompt', {...})
469
+ * .addSubFlowChartBranch('sf-messages', msgSlot, 'Messages', {...})
470
+ * .end()
471
+ * .addFunction('messageAPI', assembleFn, 'message-api')
472
+ * .build();
473
+ */
474
+ export declare function flowChartSelector<TOut = any, TScope = any>(name: string, fn: StageFunction<any, TScope>, id: string, options?: FlowChartOptions): SelectorFnList<TOut, TScope>;
475
+ export declare function specToStageNode(spec: FlowChartSpec): StageNode<any, any>;