footprint-explainable-ui 0.28.0 → 0.29.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.
package/dist/index.js CHANGED
@@ -1984,13 +1984,14 @@ function StageDetailPanel({
1984
1984
  }
1985
1985
 
1986
1986
  // src/components/TimeTravelControls/TimeTravelControls.tsx
1987
- import { useState as useState6, useEffect as useEffect4, useRef as useRef4, useCallback as useCallback3 } from "react";
1988
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1987
+ import { useState as useState6, useEffect as useEffect4, useRef as useRef4, useCallback as useCallback3, useMemo as useMemo7 } from "react";
1988
+ import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
1989
1989
  function TimeTravelControls({
1990
1990
  snapshots,
1991
1991
  selectedIndex,
1992
1992
  onIndexChange,
1993
1993
  autoPlayable = true,
1994
+ tracing = null,
1994
1995
  size = "default",
1995
1996
  unstyled = false,
1996
1997
  className,
@@ -1999,10 +2000,36 @@ function TimeTravelControls({
1999
2000
  const [playing, setPlaying] = useState6(false);
2000
2001
  const playRef = useRef4(null);
2001
2002
  const total = snapshots.length;
2002
- const canPrev = selectedIndex > 0;
2003
- const canNext = selectedIndex < total - 1;
2003
+ const isTracing = !!tracing;
2004
+ const stopSet = useMemo7(
2005
+ () => tracing ? new Set(tracing.stopIndices) : null,
2006
+ [tracing]
2007
+ );
2008
+ const earlierStop = useMemo7(() => {
2009
+ if (!tracing) return null;
2010
+ const earlier = tracing.stopIndices.filter((i) => i < selectedIndex);
2011
+ return earlier.length > 0 ? earlier[earlier.length - 1] : null;
2012
+ }, [tracing, selectedIndex]);
2013
+ const laterStop = useMemo7(() => {
2014
+ if (!tracing) return null;
2015
+ return tracing.stopIndices.find((i) => i > selectedIndex) ?? null;
2016
+ }, [tracing, selectedIndex]);
2017
+ const canPrev = isTracing ? earlierStop !== null : selectedIndex > 0;
2018
+ const canNext = isTracing ? laterStop !== null : selectedIndex < total - 1;
2019
+ const goPrev = useCallback3(() => {
2020
+ setPlaying(false);
2021
+ if (isTracing) {
2022
+ if (earlierStop !== null) onIndexChange(earlierStop);
2023
+ } else if (selectedIndex > 0) onIndexChange(selectedIndex - 1);
2024
+ }, [isTracing, earlierStop, selectedIndex, onIndexChange]);
2025
+ const goNext = useCallback3(() => {
2026
+ setPlaying(false);
2027
+ if (isTracing) {
2028
+ if (laterStop !== null) onIndexChange(laterStop);
2029
+ } else if (selectedIndex < total - 1) onIndexChange(selectedIndex + 1);
2030
+ }, [isTracing, laterStop, selectedIndex, total, onIndexChange]);
2004
2031
  useEffect4(() => {
2005
- if (!playing || !autoPlayable) return;
2032
+ if (!playing || !autoPlayable || isTracing) return;
2006
2033
  if (selectedIndex >= total - 1) {
2007
2034
  setPlaying(false);
2008
2035
  return;
@@ -2018,7 +2045,7 @@ function TimeTravelControls({
2018
2045
  return () => {
2019
2046
  if (playRef.current) clearTimeout(playRef.current);
2020
2047
  };
2021
- }, [playing, selectedIndex, snapshots, total, onIndexChange, autoPlayable]);
2048
+ }, [playing, selectedIndex, snapshots, total, onIndexChange, autoPlayable, isTracing]);
2022
2049
  const togglePlay = useCallback3(() => {
2023
2050
  if (playing) {
2024
2051
  setPlaying(false);
@@ -2031,20 +2058,22 @@ function TimeTravelControls({
2031
2058
  (e) => {
2032
2059
  if (e.key === "ArrowLeft" && canPrev && !playing) {
2033
2060
  e.preventDefault();
2034
- setPlaying(false);
2035
- onIndexChange(selectedIndex - 1);
2061
+ goPrev();
2036
2062
  } else if (e.key === "ArrowRight" && canNext && !playing) {
2037
2063
  e.preventDefault();
2038
- setPlaying(false);
2039
- onIndexChange(selectedIndex + 1);
2040
- } else if (e.key === " " && autoPlayable) {
2064
+ goNext();
2065
+ } else if (e.key === "Escape" && isTracing) {
2066
+ e.preventDefault();
2067
+ tracing.onExit();
2068
+ } else if (e.key === " " && autoPlayable && !isTracing) {
2041
2069
  e.preventDefault();
2042
2070
  togglePlay();
2043
2071
  }
2044
2072
  },
2045
- [canPrev, canNext, playing, selectedIndex, onIndexChange, autoPlayable, togglePlay]
2073
+ [canPrev, canNext, playing, goPrev, goNext, autoPlayable, togglePlay, isTracing, tracing]
2046
2074
  );
2047
2075
  const fs = fontSize[size];
2076
+ const accent = "var(--fp-accent, #6366f1)";
2048
2077
  if (unstyled) {
2049
2078
  return /* @__PURE__ */ jsxs9(
2050
2079
  "div",
@@ -2052,52 +2081,69 @@ function TimeTravelControls({
2052
2081
  className,
2053
2082
  style,
2054
2083
  "data-fp": "time-travel-controls",
2084
+ "data-tracing": isTracing || void 0,
2055
2085
  role: "toolbar",
2056
- "aria-label": "Time travel controls",
2086
+ "aria-label": isTracing ? `Tracing ${tracing.tracedKey}` : "Time travel controls",
2057
2087
  tabIndex: 0,
2058
2088
  onKeyDown: handleKeyDown,
2059
2089
  children: [
2090
+ isTracing && /* @__PURE__ */ jsxs9("span", { "data-fp": "tt-tracing-header", children: [
2091
+ "Tracing ",
2092
+ tracing.tracedKey,
2093
+ tracing.viaKey && /* @__PURE__ */ jsxs9(Fragment3, { children: [
2094
+ " ",
2095
+ "\u25B8 via ",
2096
+ tracing.viaKey,
2097
+ " ",
2098
+ /* @__PURE__ */ jsx10("button", { "data-fp": "tt-show-all", onClick: tracing.onShowAll, children: "show all" })
2099
+ ] }),
2100
+ " \xB7 ",
2101
+ "stop ",
2102
+ tracing.stopOrdinal,
2103
+ " of ",
2104
+ tracing.totalStops,
2105
+ /* @__PURE__ */ jsx10("button", { "data-fp": "tt-exit-tracing", onClick: tracing.onExit, "aria-label": "Exit tracing", children: "Done" })
2106
+ ] }),
2060
2107
  /* @__PURE__ */ jsx10(
2061
2108
  "button",
2062
2109
  {
2063
2110
  "data-fp": "tt-prev",
2064
2111
  disabled: !canPrev || playing,
2065
- onClick: () => {
2066
- setPlaying(false);
2067
- onIndexChange(selectedIndex - 1);
2068
- },
2069
- "aria-label": "Previous stage",
2070
- children: "Prev"
2112
+ onClick: goPrev,
2113
+ "aria-label": isTracing ? "Earlier cause" : "Previous stage",
2114
+ children: isTracing ? "Earlier cause" : "Prev"
2071
2115
  }
2072
2116
  ),
2073
- autoPlayable && /* @__PURE__ */ jsx10("button", { "data-fp": "tt-play", onClick: togglePlay, "aria-label": playing ? "Pause" : "Play", children: playing ? "Pause" : "Play" }),
2117
+ autoPlayable && !isTracing && /* @__PURE__ */ jsx10("button", { "data-fp": "tt-play", onClick: togglePlay, "aria-label": playing ? "Pause" : "Play", children: playing ? "Pause" : "Play" }),
2074
2118
  /* @__PURE__ */ jsx10(
2075
2119
  "button",
2076
2120
  {
2077
2121
  "data-fp": "tt-next",
2078
2122
  disabled: !canNext || playing,
2079
- onClick: () => {
2080
- setPlaying(false);
2081
- onIndexChange(selectedIndex + 1);
2082
- },
2083
- "aria-label": "Next stage",
2084
- children: "Next"
2123
+ onClick: goNext,
2124
+ "aria-label": isTracing ? "Toward result" : "Next stage",
2125
+ children: isTracing ? "Toward result" : "Next"
2085
2126
  }
2086
2127
  ),
2087
- /* @__PURE__ */ jsx10("div", { "data-fp": "tt-ticks", children: snapshots.map((snap, i) => /* @__PURE__ */ jsx10(
2088
- "button",
2089
- {
2090
- "data-fp": "tt-tick",
2091
- "data-active": i === selectedIndex,
2092
- "data-done": i < selectedIndex,
2093
- onClick: () => {
2094
- setPlaying(false);
2095
- onIndexChange(i);
2128
+ /* @__PURE__ */ jsx10("div", { "data-fp": "tt-ticks", children: snapshots.map((snap, i) => {
2129
+ const isStop = !stopSet || stopSet.has(i);
2130
+ return /* @__PURE__ */ jsx10(
2131
+ "button",
2132
+ {
2133
+ "data-fp": "tt-tick",
2134
+ "data-active": i === selectedIndex,
2135
+ "data-done": i < selectedIndex,
2136
+ "data-stop": isTracing ? isStop : void 0,
2137
+ disabled: isTracing && !isStop,
2138
+ onClick: () => {
2139
+ setPlaying(false);
2140
+ onIndexChange(i);
2141
+ },
2142
+ title: snap.stageLabel
2096
2143
  },
2097
- title: snap.stageLabel
2098
- },
2099
- i
2100
- )) })
2144
+ i
2145
+ );
2146
+ }) })
2101
2147
  ]
2102
2148
  }
2103
2149
  );
@@ -2121,7 +2167,7 @@ function TimeTravelControls({
2121
2167
  style: {
2122
2168
  padding: "6px 12px",
2123
2169
  background: theme.bgSecondary,
2124
- borderBottom: `1px solid ${theme.border}`,
2170
+ borderBottom: isTracing ? `2px solid ${accent}` : `1px solid ${theme.border}`,
2125
2171
  display: "flex",
2126
2172
  alignItems: "center",
2127
2173
  gap: 6,
@@ -2129,25 +2175,86 @@ function TimeTravelControls({
2129
2175
  ...style
2130
2176
  },
2131
2177
  "data-fp": "time-travel-controls",
2178
+ "data-tracing": isTracing || void 0,
2132
2179
  role: "toolbar",
2133
- "aria-label": "Time travel controls",
2180
+ "aria-label": isTracing ? `Tracing ${tracing.tracedKey}` : "Time travel controls",
2134
2181
  tabIndex: 0,
2135
2182
  onKeyDown: handleKeyDown,
2136
2183
  children: [
2184
+ isTracing && /* @__PURE__ */ jsxs9(
2185
+ "span",
2186
+ {
2187
+ "data-fp": "tt-tracing-header",
2188
+ style: {
2189
+ display: "flex",
2190
+ alignItems: "center",
2191
+ gap: 6,
2192
+ flexShrink: 0,
2193
+ fontSize: fs.body
2194
+ },
2195
+ children: [
2196
+ /* @__PURE__ */ jsx10(
2197
+ "span",
2198
+ {
2199
+ style: {
2200
+ fontSize: 10,
2201
+ fontWeight: 700,
2202
+ letterSpacing: "0.06em",
2203
+ textTransform: "uppercase",
2204
+ color: "#fff",
2205
+ background: accent,
2206
+ borderRadius: 4,
2207
+ padding: "2px 7px"
2208
+ },
2209
+ children: "Tracing"
2210
+ }
2211
+ ),
2212
+ /* @__PURE__ */ jsx10("span", { style: { fontFamily: "monospace", fontWeight: 600, color: accent }, children: tracing.tracedKey }),
2213
+ tracing.viaKey && /* @__PURE__ */ jsxs9("span", { style: { color: theme.textMuted }, children: [
2214
+ "\u25B8 via",
2215
+ " ",
2216
+ /* @__PURE__ */ jsx10("span", { style: { fontFamily: "monospace", color: theme.textSecondary }, children: tracing.viaKey }),
2217
+ " ",
2218
+ /* @__PURE__ */ jsx10(
2219
+ "button",
2220
+ {
2221
+ "data-fp": "tt-show-all",
2222
+ onClick: tracing.onShowAll,
2223
+ style: {
2224
+ border: "none",
2225
+ background: "transparent",
2226
+ color: accent,
2227
+ cursor: "pointer",
2228
+ fontSize: fs.body,
2229
+ textDecoration: "underline",
2230
+ padding: 0
2231
+ },
2232
+ children: "show all"
2233
+ }
2234
+ )
2235
+ ] }),
2236
+ /* @__PURE__ */ jsxs9("span", { style: { color: theme.textMuted }, children: [
2237
+ "\xB7 stop ",
2238
+ tracing.stopOrdinal,
2239
+ " of ",
2240
+ tracing.totalStops
2241
+ ] })
2242
+ ]
2243
+ }
2244
+ ),
2137
2245
  /* @__PURE__ */ jsx10(
2138
2246
  "button",
2139
2247
  {
2140
2248
  style: btnStyle(!canPrev || playing),
2141
2249
  disabled: !canPrev || playing,
2142
- onClick: () => {
2143
- setPlaying(false);
2144
- onIndexChange(selectedIndex - 1);
2145
- },
2146
- "aria-label": "Previous stage",
2147
- children: "\u25C0"
2250
+ onClick: goPrev,
2251
+ "aria-label": isTracing ? "Earlier cause" : "Previous stage",
2252
+ title: isTracing ? "Earlier cause" : "Previous stage",
2253
+ "data-fp": "tt-prev",
2254
+ children: isTracing ? "\u25C0 earlier cause" : "\u25C0"
2148
2255
  }
2149
2256
  ),
2150
- autoPlayable && /* @__PURE__ */ jsx10(
2257
+ autoPlayable && !isTracing && /* @__PURE__ */ jsx10(
2151
2258
  "button",
2152
2259
  {
2153
2260
  onClick: togglePlay,
@@ -2175,12 +2282,11 @@ function TimeTravelControls({
2175
2282
  {
2176
2283
  style: btnStyle(!canNext || playing),
2177
2284
  disabled: !canNext || playing,
2178
- onClick: () => {
2179
- setPlaying(false);
2180
- onIndexChange(selectedIndex + 1);
2181
- },
2182
- "aria-label": "Next stage",
2183
- children: "\u25B6"
2285
+ onClick: goNext,
2286
+ "aria-label": isTracing ? "Toward result" : "Next stage",
2287
+ title: isTracing ? "Toward result" : "Next stage",
2288
+ "data-fp": "tt-next",
2289
+ children: isTracing ? "toward result \u25B6" : "\u25B6"
2184
2290
  }
2185
2291
  ),
2186
2292
  /* @__PURE__ */ jsx10(
@@ -2196,6 +2302,8 @@ function TimeTravelControls({
2196
2302
  children: snapshots.map((snap, i) => {
2197
2303
  const isActive = i === selectedIndex;
2198
2304
  const isDone = i < selectedIndex;
2305
+ const isStop = !stopSet || stopSet.has(i);
2306
+ const unlandable = isTracing && !isStop;
2199
2307
  return /* @__PURE__ */ jsx10(
2200
2308
  "button",
2201
2309
  {
@@ -2203,15 +2311,19 @@ function TimeTravelControls({
2203
2311
  setPlaying(false);
2204
2312
  onIndexChange(i);
2205
2313
  },
2206
- title: snap.stageLabel,
2314
+ disabled: unlandable,
2315
+ title: unlandable ? `${snap.stageLabel} (not part of this trace)` : snap.stageLabel,
2316
+ "data-fp": "tt-tick",
2317
+ "data-stop": isTracing ? isStop : void 0,
2318
+ "data-active": isActive || void 0,
2207
2319
  style: {
2208
2320
  flex: 1,
2209
- height: isActive ? 14 : 8,
2321
+ height: isActive ? 14 : unlandable ? 4 : 8,
2210
2322
  borderRadius: 3,
2211
2323
  border: "none",
2212
- cursor: "pointer",
2213
- background: isActive ? theme.primary : isDone ? theme.success : theme.bgTertiary,
2214
- opacity: isDone || isActive ? 1 : 0.4,
2324
+ cursor: unlandable ? "default" : "pointer",
2325
+ background: isTracing ? isActive ? accent : isStop ? "color-mix(in srgb, " + accent + " 55%, transparent)" : theme.bgTertiary : isActive ? theme.primary : isDone ? theme.success : theme.bgTertiary,
2326
+ opacity: unlandable ? 0.3 : isTracing || isDone || isActive ? 1 : 0.4,
2215
2327
  transition: "all 0.15s ease"
2216
2328
  }
2217
2329
  },
@@ -2219,6 +2331,16 @@ function TimeTravelControls({
2219
2331
  );
2220
2332
  })
2221
2333
  }
2334
+ ),
2335
+ isTracing && /* @__PURE__ */ jsx10(
2336
+ "button",
2337
+ {
2338
+ "data-fp": "tt-exit-tracing",
2339
+ onClick: tracing.onExit,
2340
+ "aria-label": "Exit tracing",
2341
+ style: { ...btnStyle(false), background: "transparent" },
2342
+ children: "Done \u2715"
2343
+ }
2222
2344
  )
2223
2345
  ]
2224
2346
  }
@@ -2226,7 +2348,7 @@ function TimeTravelControls({
2226
2348
  }
2227
2349
 
2228
2350
  // src/components/ExplainableShell/ExplainableShell.tsx
2229
- import { memo as memo8, useState as useState14, useCallback as useCallback8, useMemo as useMemo12, useRef as useRef9, useEffect as useEffect11 } from "react";
2351
+ import { memo as memo9, useState as useState15, useCallback as useCallback8, useMemo as useMemo14, useRef as useRef9, useEffect as useEffect11 } from "react";
2230
2352
 
2231
2353
  // src/components/ExplainableShell/_internal/dataTrace.ts
2232
2354
  function readsByStep(tree) {
@@ -2285,9 +2407,592 @@ function buildDataTrace(commitLog, executionTree, targetRuntimeStageId, maxDepth
2285
2407
  queue.push([writerIdx, depth + 1, key]);
2286
2408
  }
2287
2409
  }
2288
- }
2289
- return { frames, readsAvailable };
2290
- }
2410
+ }
2411
+ return { frames, readsAvailable };
2412
+ }
2413
+
2414
+ // src/components/ExplainableShell/_internal/traceWalk.ts
2415
+ var DEFAULT_MAX_DEPTH = 10;
2416
+ var DEFAULT_MAX_FRAMES = 50;
2417
+ function buildTraceWalk(commitLog, executionTree, key, opts) {
2418
+ const log = commitLog ?? [];
2419
+ const cutoff = opts?.beforeCommitIdx ?? log.length;
2420
+ const maxDepth = opts?.maxDepth ?? DEFAULT_MAX_DEPTH;
2421
+ const maxFrames = opts?.maxFrames ?? DEFAULT_MAX_FRAMES;
2422
+ const writerOf = (k, beforeIdx) => {
2423
+ for (let i = Math.min(beforeIdx, log.length) - 1; i >= 0; i--) {
2424
+ if (log[i].trace.some((t) => t.path === k)) return i;
2425
+ }
2426
+ return -1;
2427
+ };
2428
+ const anchorIdx = writerOf(key, cutoff);
2429
+ if (anchorIdx < 0) {
2430
+ const firstEver = log.findIndex((c) => c.trace.some((t) => t.path === key));
2431
+ const missing = firstEver < 0 ? { reason: "never-written" } : {
2432
+ reason: "not-yet-written",
2433
+ firstWriteCommitIdx: firstEver,
2434
+ firstWriterRuntimeStageId: log[firstEver].runtimeStageId,
2435
+ firstWriterStageName: log[firstEver].stage
2436
+ };
2437
+ return { key, stops: [], missing, inputTermini: [], readsAvailable: true, truncated: false };
2438
+ }
2439
+ const slice = buildDataTrace(
2440
+ log.slice(0, anchorIdx + 1),
2441
+ executionTree,
2442
+ log[anchorIdx].runtimeStageId,
2443
+ maxDepth,
2444
+ maxFrames + 1
2445
+ );
2446
+ const truncated = slice.frames.length > maxFrames;
2447
+ const frames = truncated ? slice.frames.slice(0, maxFrames) : slice.frames;
2448
+ const idxOf = /* @__PURE__ */ new Map();
2449
+ for (let i = 0; i < log.length; i++) idxOf.set(log[i].runtimeStageId, i);
2450
+ const readsOf = readKeysByStep(executionTree);
2451
+ const inputTermini = [];
2452
+ const terminiSeen = /* @__PURE__ */ new Set();
2453
+ const stops = frames.map((f) => {
2454
+ const commitIdx = idxOf.get(f.runtimeStageId) ?? -1;
2455
+ const ingredients = (readsOf.get(f.runtimeStageId) ?? []).map((k) => {
2456
+ const w = writerOf(k, commitIdx);
2457
+ if (w < 0 && !terminiSeen.has(k)) {
2458
+ terminiSeen.add(k);
2459
+ inputTermini.push(k);
2460
+ }
2461
+ return {
2462
+ key: k,
2463
+ writerRuntimeStageId: w >= 0 ? log[w].runtimeStageId : null,
2464
+ writerStageName: w >= 0 ? log[w].stage : null,
2465
+ writerCommitIdx: w >= 0 ? w : null
2466
+ };
2467
+ });
2468
+ return {
2469
+ runtimeStageId: f.runtimeStageId,
2470
+ stageId: f.stageId,
2471
+ stageName: f.stageName,
2472
+ commitIdx,
2473
+ contributedKeys: [],
2474
+ keysWritten: f.keysWritten,
2475
+ ingredients,
2476
+ depth: f.depth,
2477
+ loopPass: 0
2478
+ };
2479
+ });
2480
+ const stopById = new Map(stops.map((s) => [s.runtimeStageId, s]));
2481
+ const contributed = /* @__PURE__ */ new Map();
2482
+ contributed.set(log[anchorIdx].runtimeStageId, /* @__PURE__ */ new Set([key]));
2483
+ for (const s of stops) {
2484
+ for (const ing of s.ingredients) {
2485
+ if (!ing.writerRuntimeStageId || !stopById.has(ing.writerRuntimeStageId)) continue;
2486
+ const set = contributed.get(ing.writerRuntimeStageId) ?? /* @__PURE__ */ new Set();
2487
+ set.add(ing.key);
2488
+ contributed.set(ing.writerRuntimeStageId, set);
2489
+ }
2490
+ }
2491
+ for (const s of stops) s.contributedKeys = [...contributed.get(s.runtimeStageId) ?? []];
2492
+ stops.sort((a, b) => b.commitIdx - a.commitIdx);
2493
+ const byStagePart = /* @__PURE__ */ new Map();
2494
+ for (const s of stops) {
2495
+ const part = s.runtimeStageId.split("#")[0];
2496
+ const arr = byStagePart.get(part) ?? [];
2497
+ arr.push(s);
2498
+ byStagePart.set(part, arr);
2499
+ }
2500
+ for (const arr of byStagePart.values()) {
2501
+ if (arr.length < 2) continue;
2502
+ for (let i = 0; i < arr.length; i++) arr[i].loopPass = arr.length - i;
2503
+ }
2504
+ return { key, stops, missing: null, inputTermini, readsAvailable: slice.readsAvailable, truncated };
2505
+ }
2506
+ function readKeysByStep(tree) {
2507
+ const byStep = /* @__PURE__ */ new Map();
2508
+ const root = tree;
2509
+ if (!root) return byStep;
2510
+ const visited = /* @__PURE__ */ new Set();
2511
+ const stack = [root];
2512
+ while (stack.length > 0) {
2513
+ const node = stack.pop();
2514
+ if (visited.has(node)) continue;
2515
+ visited.add(node);
2516
+ if (node.runtimeStageId && node.stageReads) {
2517
+ const keys = Object.keys(node.stageReads);
2518
+ if (keys.length > 0) byStep.set(node.runtimeStageId, keys);
2519
+ }
2520
+ if (node.next) stack.push(node.next);
2521
+ if (node.children) for (const c of node.children) stack.push(c);
2522
+ }
2523
+ return byStep;
2524
+ }
2525
+ function formatTraceWalk(walk, stepNumberOf) {
2526
+ const lines = [];
2527
+ if (walk.missing) {
2528
+ if (walk.missing.reason === "never-written") {
2529
+ lines.push(
2530
+ `\`${walk.key}\` was never written in this run \u2014 it arrived with the run's inputs.`
2531
+ );
2532
+ } else {
2533
+ const at = walk.missing.firstWriterRuntimeStageId ? stepNumberOf(walk.missing.firstWriterRuntimeStageId) : null;
2534
+ lines.push(
2535
+ `\`${walk.key}\` has not been written yet at this moment \u2014 its first write happens later` + (walk.missing.firstWriterStageName ? `, at ${walk.missing.firstWriterStageName}${at ? ` (step ${at})` : ""}.` : ".")
2536
+ );
2537
+ }
2538
+ return lines.join("\n");
2539
+ }
2540
+ lines.push(`Tracing \`${walk.key}\` \u2014 ${walk.stops.length} stops, newest first.`);
2541
+ walk.stops.forEach((stop, i) => {
2542
+ const step = stepNumberOf(stop.runtimeStageId);
2543
+ const pass = stop.loopPass > 0 ? ` (pass ${stop.loopPass})` : "";
2544
+ const made = stop.ingredients.length > 0 ? ` \xB7 made from: ${stop.ingredients.map(
2545
+ (ing) => ing.writerRuntimeStageId ? `${ing.key} (\u2190 ${ing.writerStageName}${stepNumberOf(ing.writerRuntimeStageId) ? `, step ${stepNumberOf(ing.writerRuntimeStageId)}` : ""})` : `${ing.key} (run input \u2014 never written)`
2546
+ ).join(", ")}` : walk.readsAvailable ? " \xB7 reads nothing \u2014 origin" : "";
2547
+ lines.push(
2548
+ `stop ${i + 1}/${walk.stops.length} \xB7 ${step ? `step ${step} \xB7 ` : ""}${stop.stageName}${pass} wrote \`${stop.contributedKeys.join("`, `")}\`${made}`
2549
+ );
2550
+ });
2551
+ if (walk.inputTermini.length > 0) {
2552
+ lines.push(`run inputs (never written): ${walk.inputTermini.join(", ")}`);
2553
+ }
2554
+ if (!walk.readsAvailable) {
2555
+ lines.push("\u26A0 reads were not recorded \u2014 dependencies are unknowable, not absent.");
2556
+ }
2557
+ if (walk.truncated) {
2558
+ lines.push("\u26A0 walk truncated at its frame budget \u2014 the earliest stop may not be the true origin.");
2559
+ }
2560
+ return lines.join("\n");
2561
+ }
2562
+
2563
+ // src/components/DataTracePanel/TraceWalkCard.tsx
2564
+ import { memo, useMemo as useMemo8, useState as useState7 } from "react";
2565
+ import { Fragment as Fragment4, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
2566
+ var CHIP_COLORS = ["#0d9488", "#d97706", "#7c3aed", "#e11d48"];
2567
+ var TraceWalkCard = memo(function TraceWalkCard2({
2568
+ walk,
2569
+ cursorRuntimeStageId,
2570
+ viaKey,
2571
+ stepNumberOf,
2572
+ previewValueOf,
2573
+ onFollowIngredient,
2574
+ onJumpToStop,
2575
+ onShowAll,
2576
+ onExit
2577
+ }) {
2578
+ const [copied, setCopied] = useState7(false);
2579
+ const accent = "var(--fp-accent, #6366f1)";
2580
+ const currentIdx = useMemo8(() => {
2581
+ if (!cursorRuntimeStageId) return 0;
2582
+ const i = walk.stops.findIndex((s) => s.runtimeStageId === cursorRuntimeStageId);
2583
+ return i >= 0 ? i : 0;
2584
+ }, [walk, cursorRuntimeStageId]);
2585
+ const current = walk.stops[currentIdx];
2586
+ const copyStory = () => {
2587
+ const text = formatTraceWalk(walk, stepNumberOf);
2588
+ void navigator.clipboard?.writeText(text).then(() => {
2589
+ setCopied(true);
2590
+ setTimeout(() => setCopied(false), 1600);
2591
+ });
2592
+ };
2593
+ if (walk.missing) {
2594
+ return /* @__PURE__ */ jsxs10("div", { "data-fp": "trace-walk-card", "data-missing": walk.missing.reason, style: { padding: "14px", fontSize: 13, lineHeight: 1.55 }, children: [
2595
+ /* @__PURE__ */ jsx11(CardHeader, { label: `Why this value \u2014 \`${walk.key}\``, onExit }),
2596
+ /* @__PURE__ */ jsx11("div", { style: { color: theme.textPrimary, marginTop: 8 }, children: walk.missing.reason === "never-written" ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
2597
+ /* @__PURE__ */ jsx11("code", { style: { color: accent }, children: walk.key }),
2598
+ " was ",
2599
+ /* @__PURE__ */ jsx11("b", { children: "never written in this run" }),
2600
+ " \u2014 it arrived with the run's inputs."
2601
+ ] }) : /* @__PURE__ */ jsxs10(Fragment4, { children: [
2602
+ /* @__PURE__ */ jsx11("code", { style: { color: accent }, children: walk.key }),
2603
+ " has ",
2604
+ /* @__PURE__ */ jsx11("b", { children: "not been written yet at this moment" }),
2605
+ " \u2014 its first write happens later",
2606
+ walk.missing.firstWriterStageName && /* @__PURE__ */ jsxs10(Fragment4, { children: [
2607
+ ", at ",
2608
+ /* @__PURE__ */ jsx11("b", { children: walk.missing.firstWriterStageName }),
2609
+ walk.missing.firstWriterRuntimeStageId && stepNumberOf(walk.missing.firstWriterRuntimeStageId) && /* @__PURE__ */ jsxs10(Fragment4, { children: [
2610
+ " (step ",
2611
+ stepNumberOf(walk.missing.firstWriterRuntimeStageId),
2612
+ ")"
2613
+ ] })
2614
+ ] }),
2615
+ "."
2616
+ ] }) })
2617
+ ] });
2618
+ }
2619
+ if (!current) return null;
2620
+ const step = stepNumberOf(current.runtimeStageId);
2621
+ const preview = previewValueOf ? previewValue(previewValueOf(current.contributedKeys[0] ?? walk.key)) : null;
2622
+ return /* @__PURE__ */ jsxs10("div", { "data-fp": "trace-walk-card", style: { padding: "10px 14px 14px", fontSize: 13, lineHeight: 1.5 }, children: [
2623
+ /* @__PURE__ */ jsx11(
2624
+ CardHeader,
2625
+ {
2626
+ label: `Why this value \u2014 stop ${currentIdx + 1} of ${walk.stops.length}`,
2627
+ onExit
2628
+ }
2629
+ ),
2630
+ viaKey && /* @__PURE__ */ jsxs10("div", { "data-fp": "twc-breadcrumb", style: { fontSize: 11, color: theme.textMuted, marginTop: 4 }, children: [
2631
+ /* @__PURE__ */ jsx11("code", { style: { color: accent }, children: walk.key }),
2632
+ " \u25B8 via ",
2633
+ /* @__PURE__ */ jsx11("code", { children: viaKey }),
2634
+ onShowAll && /* @__PURE__ */ jsxs10(Fragment4, { children: [
2635
+ " \xB7 ",
2636
+ /* @__PURE__ */ jsx11(
2637
+ "button",
2638
+ {
2639
+ onClick: onShowAll,
2640
+ style: { border: "none", background: "transparent", color: accent, cursor: "pointer", fontSize: 11, textDecoration: "underline", padding: 0 },
2641
+ children: "show all ingredients"
2642
+ }
2643
+ )
2644
+ ] })
2645
+ ] }),
2646
+ /* @__PURE__ */ jsxs10("div", { "data-fp": "twc-stop-headline", style: { marginTop: 10, fontWeight: 600, color: theme.textPrimary }, children: [
2647
+ step && /* @__PURE__ */ jsxs10("span", { style: { color: theme.textMuted, fontWeight: 500 }, children: [
2648
+ "Step ",
2649
+ step,
2650
+ " \xB7 "
2651
+ ] }),
2652
+ current.stageName,
2653
+ current.loopPass > 0 && /* @__PURE__ */ jsxs10("span", { style: { color: theme.textMuted, fontWeight: 500 }, children: [
2654
+ " (pass ",
2655
+ current.loopPass,
2656
+ ")"
2657
+ ] })
2658
+ ] }),
2659
+ /* @__PURE__ */ jsxs10("div", { style: { marginTop: 2, color: theme.textSecondary }, children: [
2660
+ "wrote",
2661
+ " ",
2662
+ current.contributedKeys.map((k, i) => /* @__PURE__ */ jsxs10("code", { style: { color: accent }, children: [
2663
+ i > 0 && ", ",
2664
+ k
2665
+ ] }, k)),
2666
+ preview !== null && /* @__PURE__ */ jsxs10("span", { style: { color: theme.textMuted }, children: [
2667
+ " = ",
2668
+ preview
2669
+ ] })
2670
+ ] }),
2671
+ /* @__PURE__ */ jsx11("div", { style: { marginTop: 10 }, children: current.ingredients.length > 0 ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
2672
+ /* @__PURE__ */ jsxs10("div", { style: { fontSize: 11, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.5px", fontWeight: 600 }, children: [
2673
+ "Made from ",
2674
+ current.ingredients.length,
2675
+ " ingredient",
2676
+ current.ingredients.length > 1 ? "s" : ""
2677
+ ] }),
2678
+ /* @__PURE__ */ jsx11("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, marginTop: 6 }, children: current.ingredients.map((ing, i) => /* @__PURE__ */ jsx11(
2679
+ IngredientChip,
2680
+ {
2681
+ ing,
2682
+ color: i < CHIP_COLORS.length ? CHIP_COLORS[i] : theme.textMuted,
2683
+ step: ing.writerRuntimeStageId ? stepNumberOf(ing.writerRuntimeStageId) : null,
2684
+ onFollow: onFollowIngredient
2685
+ },
2686
+ ing.key
2687
+ )) })
2688
+ ] }) : walk.readsAvailable ? /* @__PURE__ */ jsx11("div", { "data-fp": "twc-origin", style: { fontSize: 12, color: theme.textMuted, fontStyle: "italic" }, children: "reads nothing \u2014 this is an origin." }) : /* @__PURE__ */ jsx11("div", { "data-fp": "twc-unknowable", style: { fontSize: 12, color: theme.textMuted, fontStyle: "italic" }, children: "\u26A0 reads were not recorded \u2014 ingredients are unknowable, not absent." }) }),
2689
+ /* @__PURE__ */ jsxs10("div", { style: { marginTop: 14 }, children: [
2690
+ /* @__PURE__ */ jsx11("div", { style: { fontSize: 11, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.5px", fontWeight: 600, marginBottom: 4 }, children: "The story, newest first" }),
2691
+ walk.stops.map((s, i) => {
2692
+ const isCurrent = i === currentIdx;
2693
+ return /* @__PURE__ */ jsxs10(
2694
+ "button",
2695
+ {
2696
+ "data-fp": "twc-itinerary-row",
2697
+ "data-current": isCurrent || void 0,
2698
+ onClick: () => onJumpToStop?.(s.runtimeStageId),
2699
+ style: {
2700
+ display: "block",
2701
+ width: "100%",
2702
+ textAlign: "left",
2703
+ border: "none",
2704
+ borderLeft: isCurrent ? `3px solid ${accent}` : "3px solid transparent",
2705
+ background: isCurrent ? "var(--fp-accent-bg, rgba(99,102,241,0.12))" : "transparent",
2706
+ padding: "4px 8px",
2707
+ cursor: onJumpToStop ? "pointer" : "default",
2708
+ color: "inherit",
2709
+ fontSize: 12
2710
+ },
2711
+ children: [
2712
+ /* @__PURE__ */ jsxs10("span", { style: { color: theme.textMuted }, children: [
2713
+ i + 1,
2714
+ "."
2715
+ ] }),
2716
+ " ",
2717
+ /* @__PURE__ */ jsx11("code", { style: { color: accent }, children: s.contributedKeys.join(", ") }),
2718
+ /* @__PURE__ */ jsx11("span", { style: { color: theme.textMuted }, children: " \u2190 " }),
2719
+ s.stageName,
2720
+ s.loopPass > 0 && /* @__PURE__ */ jsxs10("span", { style: { color: theme.textMuted }, children: [
2721
+ " (pass ",
2722
+ s.loopPass,
2723
+ ")"
2724
+ ] }),
2725
+ stepNumberOf(s.runtimeStageId) && /* @__PURE__ */ jsxs10("span", { style: { color: theme.textMuted }, children: [
2726
+ " \xB7 step ",
2727
+ stepNumberOf(s.runtimeStageId)
2728
+ ] }),
2729
+ s.ingredients.length > 1 && /* @__PURE__ */ jsxs10("span", { style: { color: "#d97706", fontWeight: 600 }, children: [
2730
+ " \u2442 ",
2731
+ s.ingredients.length
2732
+ ] })
2733
+ ]
2734
+ },
2735
+ s.runtimeStageId
2736
+ );
2737
+ })
2738
+ ] }),
2739
+ /* @__PURE__ */ jsxs10("div", { style: { marginTop: 12, display: "flex", flexDirection: "column", gap: 4 }, children: [
2740
+ walk.inputTermini.length > 0 && /* @__PURE__ */ jsxs10("div", { "data-fp": "twc-run-inputs", style: { fontSize: 11, color: theme.textMuted }, children: [
2741
+ "\u2691 run inputs (never written): ",
2742
+ walk.inputTermini.map((k, i) => /* @__PURE__ */ jsxs10("code", { children: [
2743
+ i > 0 && ", ",
2744
+ k
2745
+ ] }, k))
2746
+ ] }),
2747
+ walk.truncated && /* @__PURE__ */ jsx11("div", { "data-fp": "twc-truncated", style: { fontSize: 11, color: "#d97706" }, children: "\u26A0 walk truncated at its frame budget \u2014 the earliest stop may not be the true origin." }),
2748
+ /* @__PURE__ */ jsx11(
2749
+ "button",
2750
+ {
2751
+ "data-fp": "twc-copy-story",
2752
+ onClick: copyStory,
2753
+ style: {
2754
+ alignSelf: "flex-start",
2755
+ marginTop: 4,
2756
+ border: `1px solid ${theme.border}`,
2757
+ background: theme.bgTertiary,
2758
+ color: theme.textPrimary,
2759
+ borderRadius: 6,
2760
+ padding: "4px 10px",
2761
+ fontSize: 11,
2762
+ fontWeight: 600,
2763
+ cursor: "pointer"
2764
+ },
2765
+ children: copied ? "Copied \u2713" : "Copy story"
2766
+ }
2767
+ )
2768
+ ] })
2769
+ ] });
2770
+ });
2771
+ function CardHeader({ label, onExit }) {
2772
+ return /* @__PURE__ */ jsxs10("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
2773
+ /* @__PURE__ */ jsx11("div", { style: { fontSize: 11, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.5px", fontWeight: 600 }, children: label }),
2774
+ onExit && /* @__PURE__ */ jsx11(
2775
+ "button",
2776
+ {
2777
+ "data-fp": "twc-exit",
2778
+ onClick: onExit,
2779
+ "aria-label": "Exit tracing",
2780
+ style: { border: "none", background: "transparent", color: theme.textMuted, cursor: "pointer", fontSize: 12 },
2781
+ children: "Done \u2715"
2782
+ }
2783
+ )
2784
+ ] });
2785
+ }
2786
+ function IngredientChip({
2787
+ ing,
2788
+ color,
2789
+ step,
2790
+ onFollow
2791
+ }) {
2792
+ const terminus = !ing.writerRuntimeStageId;
2793
+ return /* @__PURE__ */ jsxs10(
2794
+ "button",
2795
+ {
2796
+ "data-fp": "twc-ingredient",
2797
+ "data-terminus": terminus || void 0,
2798
+ disabled: terminus || !onFollow,
2799
+ onClick: () => onFollow?.(ing),
2800
+ title: terminus ? `${ing.key} was never written \u2014 it came in with the run's inputs` : `Follow ${ing.key} \u2014 re-anchor the walk on its writer`,
2801
+ style: {
2802
+ display: "inline-flex",
2803
+ alignItems: "center",
2804
+ gap: 4,
2805
+ border: `1px solid ${terminus ? theme.border : color}`,
2806
+ background: "transparent",
2807
+ color: terminus ? theme.textMuted : color,
2808
+ borderRadius: 12,
2809
+ padding: "3px 10px",
2810
+ fontSize: 11,
2811
+ fontWeight: 600,
2812
+ cursor: terminus || !onFollow ? "default" : "pointer"
2813
+ },
2814
+ children: [
2815
+ /* @__PURE__ */ jsx11("code", { children: ing.key }),
2816
+ terminus ? /* @__PURE__ */ jsx11("span", { style: { fontWeight: 400 }, children: "\u2014 run input \u2691" }) : /* @__PURE__ */ jsxs10("span", { style: { fontWeight: 400 }, children: [
2817
+ "\u2190 ",
2818
+ ing.writerStageName,
2819
+ step && ` \xB7 step ${step}`
2820
+ ] })
2821
+ ]
2822
+ }
2823
+ );
2824
+ }
2825
+ function previewValue(v2) {
2826
+ if (v2 === void 0) return null;
2827
+ try {
2828
+ const s = typeof v2 === "string" ? JSON.stringify(v2) : JSON.stringify(v2);
2829
+ if (s === void 0) return null;
2830
+ return s.length > 60 ? `${s.slice(0, 57)}\u2026` : s;
2831
+ } catch {
2832
+ return null;
2833
+ }
2834
+ }
2835
+
2836
+ // src/components/DataTracePanel/DataTracePanel.tsx
2837
+ import { memo as memo2 } from "react";
2838
+ import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
2839
+ var DataTracePanel = memo2(function DataTracePanel2({
2840
+ frames,
2841
+ selectedStageId,
2842
+ onFrameClick,
2843
+ fromStageName,
2844
+ note
2845
+ }) {
2846
+ const noteLine = note ? /* @__PURE__ */ jsx12("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", marginBottom: 8 }, children: note }) : null;
2847
+ if (frames.length === 0) {
2848
+ return /* @__PURE__ */ jsxs11("div", { style: { padding: "14px 14px 12px", fontSize: 13, lineHeight: 1.55 }, children: [
2849
+ /* @__PURE__ */ jsx12(
2850
+ "div",
2851
+ {
2852
+ style: {
2853
+ fontSize: 11,
2854
+ color: theme.textMuted,
2855
+ textTransform: "uppercase",
2856
+ letterSpacing: "0.5px",
2857
+ fontWeight: 600,
2858
+ marginBottom: 6
2859
+ },
2860
+ children: "Backward causal chain"
2861
+ }
2862
+ ),
2863
+ /* @__PURE__ */ jsx12("div", { style: { color: theme.textSecondary, marginBottom: 10 }, children: "Trace any value back to the stage that created it \u2014 and everything upstream that influenced it." }),
2864
+ noteLine,
2865
+ /* @__PURE__ */ jsx12("div", { style: { color: theme.textMuted, fontSize: 12 }, children: "Select a stage above to see its dependency chain." })
2866
+ ] });
2867
+ }
2868
+ return /* @__PURE__ */ jsxs11("div", { style: { padding: "8px 0", fontSize: 13 }, children: [
2869
+ note && /* @__PURE__ */ jsx12("div", { style: { padding: "4px 12px 0", fontSize: 11, color: theme.textMuted, fontStyle: "italic" }, children: note }),
2870
+ fromStageName && /* @__PURE__ */ jsxs11("div", { style: { padding: "4px 12px 8px" }, children: [
2871
+ /* @__PURE__ */ jsxs11(
2872
+ "div",
2873
+ {
2874
+ style: {
2875
+ fontSize: 11,
2876
+ color: theme.textMuted,
2877
+ textTransform: "uppercase",
2878
+ letterSpacing: "0.5px",
2879
+ fontWeight: 600
2880
+ },
2881
+ children: [
2882
+ "Data trace from ",
2883
+ fromStageName
2884
+ ]
2885
+ }
2886
+ ),
2887
+ /* @__PURE__ */ jsx12(
2888
+ "div",
2889
+ {
2890
+ style: {
2891
+ fontSize: 11,
2892
+ color: theme.textMuted,
2893
+ fontStyle: "italic",
2894
+ marginTop: 3
2895
+ },
2896
+ children: "Every value here was derived from the stages below."
2897
+ }
2898
+ )
2899
+ ] }),
2900
+ frames.map((frame, i) => /* @__PURE__ */ jsx12(
2901
+ DataTraceFrame,
2902
+ {
2903
+ frame,
2904
+ isFirst: i === 0,
2905
+ isLast: i === frames.length - 1,
2906
+ isSelected: frame.runtimeStageId === selectedStageId,
2907
+ onClick: onFrameClick
2908
+ },
2909
+ frame.runtimeStageId
2910
+ ))
2911
+ ] });
2912
+ });
2913
+ var DataTraceFrame = memo2(function DataTraceFrame2({
2914
+ frame,
2915
+ isFirst,
2916
+ isLast,
2917
+ isSelected,
2918
+ onClick
2919
+ }) {
2920
+ return /* @__PURE__ */ jsxs11(
2921
+ "button",
2922
+ {
2923
+ onClick: () => onClick?.(frame.runtimeStageId),
2924
+ style: {
2925
+ display: "block",
2926
+ width: "100%",
2927
+ textAlign: "left",
2928
+ border: "none",
2929
+ background: isSelected ? "var(--fp-accent-bg, rgba(99,102,241,0.12))" : "transparent",
2930
+ padding: "6px 12px 6px 16px",
2931
+ cursor: onClick ? "pointer" : "default",
2932
+ borderLeft: isSelected ? "3px solid var(--fp-accent, #6366f1)" : "3px solid transparent",
2933
+ color: "inherit",
2934
+ fontSize: 13
2935
+ },
2936
+ children: [
2937
+ /* @__PURE__ */ jsxs11("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
2938
+ !isFirst && /* @__PURE__ */ jsx12("span", { style: { color: theme.textMuted, fontSize: 11 }, children: "\u2191" }),
2939
+ /* @__PURE__ */ jsx12(
2940
+ "span",
2941
+ {
2942
+ style: {
2943
+ fontWeight: isFirst ? 600 : 400,
2944
+ color: isFirst ? "var(--fp-accent, #6366f1)" : theme.textPrimary
2945
+ },
2946
+ children: frame.stageName
2947
+ }
2948
+ ),
2949
+ isLast && !isFirst && /* @__PURE__ */ jsx12(
2950
+ "span",
2951
+ {
2952
+ style: {
2953
+ fontSize: 10,
2954
+ color: theme.textMuted,
2955
+ fontStyle: "italic"
2956
+ },
2957
+ children: "(origin)"
2958
+ }
2959
+ )
2960
+ ] }),
2961
+ frame.keysWritten.length > 0 && /* @__PURE__ */ jsxs11(
2962
+ "div",
2963
+ {
2964
+ style: {
2965
+ fontSize: 11,
2966
+ color: theme.textMuted,
2967
+ paddingLeft: isFirst ? 0 : 18,
2968
+ marginTop: 2
2969
+ },
2970
+ children: [
2971
+ "wrote:",
2972
+ " ",
2973
+ /* @__PURE__ */ jsx12("span", { style: { color: theme.textSecondary }, children: frame.keysWritten.join(", ") })
2974
+ ]
2975
+ }
2976
+ ),
2977
+ frame.linkedBy && /* @__PURE__ */ jsxs11(
2978
+ "div",
2979
+ {
2980
+ style: {
2981
+ fontSize: 11,
2982
+ color: "var(--fp-accent, #6366f1)",
2983
+ paddingLeft: 18,
2984
+ marginTop: 1
2985
+ },
2986
+ children: [
2987
+ "\u2190 via ",
2988
+ frame.linkedBy
2989
+ ]
2990
+ }
2991
+ )
2992
+ ]
2993
+ }
2994
+ );
2995
+ });
2291
2996
 
2292
2997
  // src/utils/narrativeSync.ts
2293
2998
  function buildEntryRangeIndex(entries) {
@@ -2610,7 +3315,7 @@ function createSnapshots(stages) {
2610
3315
  }
2611
3316
 
2612
3317
  // src/components/MemoryPanel/MemoryPanel.tsx
2613
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
3318
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
2614
3319
  function MemoryPanel({
2615
3320
  snapshots,
2616
3321
  selectedIndex,
@@ -2622,12 +3327,12 @@ function MemoryPanel({
2622
3327
  const prevMemory = selectedIndex > 0 ? snapshots[selectedIndex - 1]?.memory ?? null : null;
2623
3328
  const currMemory = snapshots[selectedIndex]?.memory ?? {};
2624
3329
  if (unstyled) {
2625
- return /* @__PURE__ */ jsxs10("div", { className, style, "data-fp": "memory-panel", children: [
2626
- /* @__PURE__ */ jsx11(MemoryInspector, { snapshots, selectedIndex, unstyled: true }),
2627
- /* @__PURE__ */ jsx11(ScopeDiff, { previous: prevMemory, current: currMemory, unstyled: true })
3330
+ return /* @__PURE__ */ jsxs12("div", { className, style, "data-fp": "memory-panel", children: [
3331
+ /* @__PURE__ */ jsx13(MemoryInspector, { snapshots, selectedIndex, unstyled: true }),
3332
+ /* @__PURE__ */ jsx13(ScopeDiff, { previous: prevMemory, current: currMemory, unstyled: true })
2628
3333
  ] });
2629
3334
  }
2630
- return /* @__PURE__ */ jsxs10(
3335
+ return /* @__PURE__ */ jsxs12(
2631
3336
  "div",
2632
3337
  {
2633
3338
  className,
@@ -2639,19 +3344,19 @@ function MemoryPanel({
2639
3344
  },
2640
3345
  "data-fp": "memory-panel",
2641
3346
  children: [
2642
- /* @__PURE__ */ jsx11(MemoryInspector, { snapshots, selectedIndex, size }),
2643
- /* @__PURE__ */ jsx11("div", { style: { borderTop: `1px solid ${theme.border}` }, children: /* @__PURE__ */ jsx11(ScopeDiff, { previous: prevMemory, current: currMemory, hideUnchanged: true, size }) })
3347
+ /* @__PURE__ */ jsx13(MemoryInspector, { snapshots, selectedIndex, size }),
3348
+ /* @__PURE__ */ jsx13("div", { style: { borderTop: `1px solid ${theme.border}` }, children: /* @__PURE__ */ jsx13(ScopeDiff, { previous: prevMemory, current: currMemory, hideUnchanged: true, size }) })
2644
3349
  ]
2645
3350
  }
2646
3351
  );
2647
3352
  }
2648
3353
 
2649
3354
  // src/components/NarrativePanel/NarrativePanel.tsx
2650
- import { useMemo as useMemo8, useState as useState7, useCallback as useCallback4 } from "react";
3355
+ import { useMemo as useMemo11, useState as useState8, useCallback as useCallback4 } from "react";
2651
3356
 
2652
3357
  // src/components/StoryNarrative/StoryNarrative.tsx
2653
- import { useMemo as useMemo7, useRef as useRef5, useEffect as useEffect5 } from "react";
2654
- import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
3358
+ import { useMemo as useMemo10, useRef as useRef5, useEffect as useEffect5 } from "react";
3359
+ import { Fragment as Fragment5, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
2655
3360
  var ENTRY_ICONS = {
2656
3361
  stage: { icon: "\u25B8", color: theme.primary, label: "Stage" },
2657
3362
  step: { icon: "\xB7", color: theme.textMuted, label: "Data operation" },
@@ -2674,7 +3379,7 @@ function StoryNarrative({
2674
3379
  const fs = fontSize[size];
2675
3380
  const pad = padding[size];
2676
3381
  const revealedCount = revealedEntryCount;
2677
- const revealed = useMemo7(() => {
3382
+ const revealed = useMemo10(() => {
2678
3383
  const raw = entries.slice(0, revealedCount);
2679
3384
  return raw.filter((e) => {
2680
3385
  const sfId = e.subflowId;
@@ -2683,7 +3388,7 @@ function StoryNarrative({
2683
3388
  return false;
2684
3389
  });
2685
3390
  }, [entries, revealedCount]);
2686
- const futureCount = useMemo7(() => {
3391
+ const futureCount = useMemo10(() => {
2687
3392
  let count = 0;
2688
3393
  for (let i = revealedCount; i < entries.length; i++) {
2689
3394
  const e = entries[i];
@@ -2695,7 +3400,7 @@ function StoryNarrative({
2695
3400
  useEffect5(() => {
2696
3401
  latestRef.current?.scrollIntoView({ behavior: "smooth", block: "nearest" });
2697
3402
  }, [revealed.length]);
2698
- const numberedEntries = useMemo7(() => {
3403
+ const numberedEntries = useMemo10(() => {
2699
3404
  let counter = 0;
2700
3405
  const subflowSeen = /* @__PURE__ */ new Set();
2701
3406
  let prevType = "";
@@ -2743,13 +3448,13 @@ function StoryNarrative({
2743
3448
  });
2744
3449
  }, [revealed]);
2745
3450
  if (unstyled) {
2746
- return /* @__PURE__ */ jsx12("div", { className, style: outerStyle, "data-fp": "story-narrative", role: "log", children: numberedEntries.map((entry, i) => {
3451
+ return /* @__PURE__ */ jsx14("div", { className, style: outerStyle, "data-fp": "story-narrative", role: "log", children: numberedEntries.map((entry, i) => {
2747
3452
  if (entry.isSubflowExit) return null;
2748
3453
  const ht = entry.headingType;
2749
- return /* @__PURE__ */ jsx12("div", { "data-fp": "narrative-entry", "data-type": entry.type, children: entry.heading ? entry.text.startsWith("[") ? `${entry.heading}. ${entry.text}` : `${entry.heading}. [${ht}: ${entry.stageName ?? ""}] ${entry.text}` : entry.text }, i);
3454
+ return /* @__PURE__ */ jsx14("div", { "data-fp": "narrative-entry", "data-type": entry.type, children: entry.heading ? entry.text.startsWith("[") ? `${entry.heading}. ${entry.text}` : `${entry.heading}. [${ht}: ${entry.stageName ?? ""}] ${entry.text}` : entry.text }, i);
2750
3455
  }) });
2751
3456
  }
2752
- return /* @__PURE__ */ jsxs11(
3457
+ return /* @__PURE__ */ jsxs13(
2753
3458
  "div",
2754
3459
  {
2755
3460
  className,
@@ -2774,7 +3479,7 @@ function StoryNarrative({
2774
3479
  const isSubflow = entry.isSubflow;
2775
3480
  const isLast = i === numberedEntries.length - 1;
2776
3481
  const headingType = entry.headingType;
2777
- return /* @__PURE__ */ jsxs11(
3482
+ return /* @__PURE__ */ jsxs13(
2778
3483
  "div",
2779
3484
  {
2780
3485
  ref: isLast ? latestRef : void 0,
@@ -2787,7 +3492,7 @@ function StoryNarrative({
2787
3492
  marginTop: isHeading && i > 0 ? 8 : 0
2788
3493
  },
2789
3494
  children: [
2790
- /* @__PURE__ */ jsx12(
3495
+ /* @__PURE__ */ jsx14(
2791
3496
  "span",
2792
3497
  {
2793
3498
  style: {
@@ -2803,7 +3508,7 @@ function StoryNarrative({
2803
3508
  children: meta.icon
2804
3509
  }
2805
3510
  ),
2806
- /* @__PURE__ */ jsx12(
3511
+ /* @__PURE__ */ jsx14(
2807
3512
  "span",
2808
3513
  {
2809
3514
  style: {
@@ -2813,15 +3518,15 @@ function StoryNarrative({
2813
3518
  lineHeight: 1.6,
2814
3519
  fontFamily: entry.type === "step" ? theme.fontMono : theme.fontSans
2815
3520
  },
2816
- children: entry.heading && headingType ? entry.text.startsWith("[") ? /* @__PURE__ */ jsxs11(Fragment3, { children: [
2817
- /* @__PURE__ */ jsxs11("strong", { children: [
3521
+ children: entry.heading && headingType ? entry.text.startsWith("[") ? /* @__PURE__ */ jsxs13(Fragment5, { children: [
3522
+ /* @__PURE__ */ jsxs13("strong", { children: [
2818
3523
  entry.heading,
2819
3524
  "."
2820
3525
  ] }),
2821
3526
  " ",
2822
3527
  entry.text
2823
- ] }) : /* @__PURE__ */ jsxs11(Fragment3, { children: [
2824
- /* @__PURE__ */ jsxs11("strong", { children: [
3528
+ ] }) : /* @__PURE__ */ jsxs13(Fragment5, { children: [
3529
+ /* @__PURE__ */ jsxs13("strong", { children: [
2825
3530
  entry.heading,
2826
3531
  ". [",
2827
3532
  headingType,
@@ -2838,7 +3543,7 @@ function StoryNarrative({
2838
3543
  i
2839
3544
  );
2840
3545
  }),
2841
- futureCount > 0 && /* @__PURE__ */ jsxs11("div", { style: {
3546
+ futureCount > 0 && /* @__PURE__ */ jsxs13("div", { style: {
2842
3547
  opacity: 0.3,
2843
3548
  fontSize: fs.small,
2844
3549
  color: theme.textMuted,
@@ -2856,7 +3561,7 @@ function StoryNarrative({
2856
3561
  }
2857
3562
 
2858
3563
  // src/components/NarrativePanel/NarrativePanel.tsx
2859
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
3564
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
2860
3565
  function safeJsonStringify(value) {
2861
3566
  const seen = /* @__PURE__ */ new WeakSet();
2862
3567
  const MAX_CHARS = 5e5;
@@ -2894,7 +3599,7 @@ function NarrativePanel({
2894
3599
  }) {
2895
3600
  const fs = fontSize[size];
2896
3601
  const pad = padding[size];
2897
- const narrative = useMemo8(() => {
3602
+ const narrative = useMemo11(() => {
2898
3603
  const lines = [];
2899
3604
  for (const snap of snapshots) {
2900
3605
  const stageLines = (snap.narrative ?? "").split("\n").filter(Boolean);
@@ -2902,7 +3607,7 @@ function NarrativePanel({
2902
3607
  }
2903
3608
  return lines;
2904
3609
  }, [snapshots]);
2905
- const revealedCount = useMemo8(() => {
3610
+ const revealedCount = useMemo11(() => {
2906
3611
  if (snapshots.length === 0 || narrative.length === 0) return narrative.length;
2907
3612
  const stageBoundaries = [];
2908
3613
  for (let i = 0; i < narrative.length; i++) {
@@ -2919,16 +3624,16 @@ function NarrativePanel({
2919
3624
  const endIdx = groupsToShow < stageBoundaries.length ? stageBoundaries[groupsToShow] : narrative.length;
2920
3625
  return Math.max(1, endIdx);
2921
3626
  }, [snapshots.length, selectedIndex, narrative]);
2922
- const rangeIndex = useMemo8(
3627
+ const rangeIndex = useMemo11(
2923
3628
  () => narrativeEntries?.length ? buildEntryRangeIndex(narrativeEntries) : void 0,
2924
3629
  [narrativeEntries]
2925
3630
  );
2926
- const revealedEntryCount = useMemo8(
3631
+ const revealedEntryCount = useMemo11(
2927
3632
  () => narrativeEntries?.length ? computeRevealedEntryCount(narrativeEntries, snapshots, selectedIndex, rangeIndex) : 0,
2928
3633
  [narrativeEntries, snapshots, selectedIndex, rangeIndex]
2929
3634
  );
2930
3635
  const hasStructured = narrativeEntries && narrativeEntries.length > 0;
2931
- const [copied, setCopied] = useState7(false);
3636
+ const [copied, setCopied] = useState8(false);
2932
3637
  const buildLLMNarrative = useCallback4(() => {
2933
3638
  if (!narrativeEntries?.length) {
2934
3639
  return narrative.join("\n");
@@ -3048,9 +3753,9 @@ function NarrativePanel({
3048
3753
  setTimeout(() => setCopied(false), 2e3);
3049
3754
  }, [buildLLMNarrative]);
3050
3755
  if (unstyled) {
3051
- return /* @__PURE__ */ jsx13("div", { className, style, "data-fp": "narrative-panel", children: hasStructured ? /* @__PURE__ */ jsx13(StoryNarrative, { entries: narrativeEntries, revealedEntryCount, unstyled: true }) : /* @__PURE__ */ jsx13(NarrativeTrace, { narrative, revealedCount, unstyled: true }) });
3756
+ return /* @__PURE__ */ jsx15("div", { className, style, "data-fp": "narrative-panel", children: hasStructured ? /* @__PURE__ */ jsx15(StoryNarrative, { entries: narrativeEntries, revealedEntryCount, unstyled: true }) : /* @__PURE__ */ jsx15(NarrativeTrace, { narrative, revealedCount, unstyled: true }) });
3052
3757
  }
3053
- return /* @__PURE__ */ jsxs12(
3758
+ return /* @__PURE__ */ jsxs14(
3054
3759
  "div",
3055
3760
  {
3056
3761
  className,
@@ -3062,7 +3767,7 @@ function NarrativePanel({
3062
3767
  },
3063
3768
  "data-fp": "narrative-panel",
3064
3769
  children: [
3065
- /* @__PURE__ */ jsxs12(
3770
+ /* @__PURE__ */ jsxs14(
3066
3771
  "div",
3067
3772
  {
3068
3773
  style: {
@@ -3076,8 +3781,8 @@ function NarrativePanel({
3076
3781
  alignItems: "center"
3077
3782
  },
3078
3783
  children: [
3079
- /* @__PURE__ */ jsx13("span", { style: { fontStyle: "italic" }, children: "What happened at each stage, what data flowed, what decisions were made, and why." }),
3080
- /* @__PURE__ */ jsx13(
3784
+ /* @__PURE__ */ jsx15("span", { style: { fontStyle: "italic" }, children: "What happened at each stage, what data flowed, what decisions were made, and why." }),
3785
+ /* @__PURE__ */ jsx15(
3081
3786
  "button",
3082
3787
  {
3083
3788
  onClick: handleCopy,
@@ -3100,7 +3805,7 @@ function NarrativePanel({
3100
3805
  ]
3101
3806
  }
3102
3807
  ),
3103
- hasStructured ? /* @__PURE__ */ jsx13(
3808
+ hasStructured ? /* @__PURE__ */ jsx15(
3104
3809
  StoryNarrative,
3105
3810
  {
3106
3811
  entries: narrativeEntries,
@@ -3108,7 +3813,7 @@ function NarrativePanel({
3108
3813
  size,
3109
3814
  style: { flex: 1 }
3110
3815
  }
3111
- ) : /* @__PURE__ */ jsx13(
3816
+ ) : /* @__PURE__ */ jsx15(
3112
3817
  NarrativeTrace,
3113
3818
  {
3114
3819
  narrative,
@@ -3123,8 +3828,8 @@ function NarrativePanel({
3123
3828
  }
3124
3829
 
3125
3830
  // src/components/FlowchartView/SubflowTree.tsx
3126
- import { memo, useState as useState8, useCallback as useCallback5, useMemo as useMemo9 } from "react";
3127
- import { Fragment as Fragment4, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
3831
+ import { memo as memo3, useState as useState9, useCallback as useCallback5, useMemo as useMemo12 } from "react";
3832
+ import { Fragment as Fragment6, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
3128
3833
  function graphToSubflowEntries(graph) {
3129
3834
  if (!graph?.nodes?.length) return [];
3130
3835
  const entries = [];
@@ -3140,14 +3845,14 @@ function graphToSubflowEntries(graph) {
3140
3845
  }
3141
3846
  return entries;
3142
3847
  }
3143
- var TreeNode = memo(function TreeNode2({
3848
+ var TreeNode = memo3(function TreeNode2({
3144
3849
  entry,
3145
3850
  depth,
3146
3851
  activeStage,
3147
3852
  doneStages,
3148
3853
  onNodeSelect
3149
3854
  }) {
3150
- const [expanded, setExpanded] = useState8(true);
3855
+ const [expanded, setExpanded] = useState9(true);
3151
3856
  const hasChildren = entry.children && entry.children.length > 0;
3152
3857
  const isActive = activeStage === entry.name;
3153
3858
  const isDone = doneStages?.has(entry.name);
@@ -3157,8 +3862,8 @@ var TreeNode = memo(function TreeNode2({
3157
3862
  }
3158
3863
  onNodeSelect?.(entry.name, !!entry.isSubflow);
3159
3864
  }, [hasChildren, onNodeSelect, entry.name, entry.isSubflow]);
3160
- return /* @__PURE__ */ jsxs13(Fragment4, { children: [
3161
- /* @__PURE__ */ jsxs13(
3865
+ return /* @__PURE__ */ jsxs15(Fragment6, { children: [
3866
+ /* @__PURE__ */ jsxs15(
3162
3867
  "button",
3163
3868
  {
3164
3869
  onClick: handleClick,
@@ -3189,7 +3894,7 @@ var TreeNode = memo(function TreeNode2({
3189
3894
  }
3190
3895
  },
3191
3896
  children: [
3192
- hasChildren ? /* @__PURE__ */ jsx14(
3897
+ hasChildren ? /* @__PURE__ */ jsx16(
3193
3898
  "span",
3194
3899
  {
3195
3900
  style: {
@@ -3204,8 +3909,8 @@ var TreeNode = memo(function TreeNode2({
3204
3909
  },
3205
3910
  children: "\u25B6"
3206
3911
  }
3207
- ) : /* @__PURE__ */ jsx14("span", { style: { width: 12, flexShrink: 0 } }),
3208
- /* @__PURE__ */ jsx14(
3912
+ ) : /* @__PURE__ */ jsx16("span", { style: { width: 12, flexShrink: 0 } }),
3913
+ /* @__PURE__ */ jsx16(
3209
3914
  "span",
3210
3915
  {
3211
3916
  style: {
@@ -3217,8 +3922,8 @@ var TreeNode = memo(function TreeNode2({
3217
3922
  }
3218
3923
  }
3219
3924
  ),
3220
- /* @__PURE__ */ jsxs13("span", { style: { display: "flex", flexDirection: "column", minWidth: 0 }, children: [
3221
- /* @__PURE__ */ jsxs13(
3925
+ /* @__PURE__ */ jsxs15("span", { style: { display: "flex", flexDirection: "column", minWidth: 0 }, children: [
3926
+ /* @__PURE__ */ jsxs15(
3222
3927
  "span",
3223
3928
  {
3224
3929
  style: {
@@ -3230,11 +3935,11 @@ var TreeNode = memo(function TreeNode2({
3230
3935
  },
3231
3936
  children: [
3232
3937
  entry.name,
3233
- entry.isSubflow && /* @__PURE__ */ jsx14("span", { style: { opacity: 0.5, marginLeft: 4, fontSize: 10 }, children: "\u229E" })
3938
+ entry.isSubflow && /* @__PURE__ */ jsx16("span", { style: { opacity: 0.5, marginLeft: 4, fontSize: 10 }, children: "\u229E" })
3234
3939
  ]
3235
3940
  }
3236
3941
  ),
3237
- entry.description && /* @__PURE__ */ jsx14(
3942
+ entry.description && /* @__PURE__ */ jsx16(
3238
3943
  "span",
3239
3944
  {
3240
3945
  style: {
@@ -3251,7 +3956,7 @@ var TreeNode = memo(function TreeNode2({
3251
3956
  ]
3252
3957
  }
3253
3958
  ),
3254
- hasChildren && expanded && /* @__PURE__ */ jsx14("div", { children: entry.children.map((child, i) => /* @__PURE__ */ jsx14(
3959
+ hasChildren && expanded && /* @__PURE__ */ jsx16("div", { children: entry.children.map((child, i) => /* @__PURE__ */ jsx16(
3255
3960
  TreeNode2,
3256
3961
  {
3257
3962
  entry: child,
@@ -3264,8 +3969,8 @@ var TreeNode = memo(function TreeNode2({
3264
3969
  )) })
3265
3970
  ] });
3266
3971
  });
3267
- var SectionLabel = memo(function SectionLabel2({ children }) {
3268
- return /* @__PURE__ */ jsx14(
3972
+ var SectionLabel = memo3(function SectionLabel2({ children }) {
3973
+ return /* @__PURE__ */ jsx16(
3269
3974
  "div",
3270
3975
  {
3271
3976
  style: {
@@ -3280,7 +3985,7 @@ var SectionLabel = memo(function SectionLabel2({ children }) {
3280
3985
  }
3281
3986
  );
3282
3987
  });
3283
- var SubflowTree = memo(function SubflowTree2({
3988
+ var SubflowTree = memo3(function SubflowTree2({
3284
3989
  graph,
3285
3990
  activeStage,
3286
3991
  doneStages,
@@ -3289,9 +3994,9 @@ var SubflowTree = memo(function SubflowTree2({
3289
3994
  className,
3290
3995
  style
3291
3996
  }) {
3292
- const subflowStages = useMemo9(() => graphToSubflowEntries(graph), [graph]);
3997
+ const subflowStages = useMemo12(() => graphToSubflowEntries(graph), [graph]);
3293
3998
  if (subflowStages.length === 0) return null;
3294
- return /* @__PURE__ */ jsxs13(
3999
+ return /* @__PURE__ */ jsxs15(
3295
4000
  "div",
3296
4001
  {
3297
4002
  className,
@@ -3309,8 +4014,8 @@ var SubflowTree = memo(function SubflowTree2({
3309
4014
  ...style
3310
4015
  },
3311
4016
  children: [
3312
- !unstyled && /* @__PURE__ */ jsx14(SectionLabel, { children: "Subflows" }),
3313
- subflowStages.map((entry, i) => /* @__PURE__ */ jsx14(
4017
+ !unstyled && /* @__PURE__ */ jsx16(SectionLabel, { children: "Subflows" }),
4018
+ subflowStages.map((entry, i) => /* @__PURE__ */ jsx16(
3314
4019
  TreeNode,
3315
4020
  {
3316
4021
  entry,
@@ -3327,14 +4032,14 @@ var SubflowTree = memo(function SubflowTree2({
3327
4032
  });
3328
4033
 
3329
4034
  // src/components/FlowchartView/SubflowBreadcrumb.tsx
3330
- import { memo as memo2 } from "react";
3331
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
3332
- var SubflowBreadcrumb = memo2(function SubflowBreadcrumb2({
4035
+ import { memo as memo4 } from "react";
4036
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
4037
+ var SubflowBreadcrumb = memo4(function SubflowBreadcrumb2({
3333
4038
  breadcrumbs,
3334
4039
  onNavigate
3335
4040
  }) {
3336
4041
  if (breadcrumbs.length <= 1) return null;
3337
- return /* @__PURE__ */ jsx15(
4042
+ return /* @__PURE__ */ jsx17(
3338
4043
  "div",
3339
4044
  {
3340
4045
  style: {
@@ -3351,10 +4056,10 @@ var SubflowBreadcrumb = memo2(function SubflowBreadcrumb2({
3351
4056
  },
3352
4057
  children: breadcrumbs.map((crumb, i) => {
3353
4058
  const isLast = i === breadcrumbs.length - 1;
3354
- return /* @__PURE__ */ jsxs14("span", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
3355
- i > 0 && /* @__PURE__ */ jsx15("span", { style: { color: theme.textMuted, fontSize: 10 }, children: "\u203A" }),
3356
- isLast ? /* @__PURE__ */ jsxs14("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
3357
- /* @__PURE__ */ jsx15(
4059
+ return /* @__PURE__ */ jsxs16("span", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
4060
+ i > 0 && /* @__PURE__ */ jsx17("span", { style: { color: theme.textMuted, fontSize: 10 }, children: "\u203A" }),
4061
+ isLast ? /* @__PURE__ */ jsxs16("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
4062
+ /* @__PURE__ */ jsx17(
3358
4063
  "span",
3359
4064
  {
3360
4065
  style: {
@@ -3364,7 +4069,7 @@ var SubflowBreadcrumb = memo2(function SubflowBreadcrumb2({
3364
4069
  children: crumb.label
3365
4070
  }
3366
4071
  ),
3367
- crumb.description && /* @__PURE__ */ jsxs14(
4072
+ crumb.description && /* @__PURE__ */ jsxs16(
3368
4073
  "span",
3369
4074
  {
3370
4075
  style: {
@@ -3378,7 +4083,7 @@ var SubflowBreadcrumb = memo2(function SubflowBreadcrumb2({
3378
4083
  ]
3379
4084
  }
3380
4085
  )
3381
- ] }) : /* @__PURE__ */ jsx15(
4086
+ ] }) : /* @__PURE__ */ jsx17(
3382
4087
  "button",
3383
4088
  {
3384
4089
  onClick: () => onNavigate(i),
@@ -3410,7 +4115,7 @@ var SubflowBreadcrumb = memo2(function SubflowBreadcrumb2({
3410
4115
  });
3411
4116
 
3412
4117
  // src/components/FlowchartView/TracedFlow.tsx
3413
- import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo10, useRef as useRef8, useState as useState10 } from "react";
4118
+ import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo13, useRef as useRef8, useState as useState11 } from "react";
3414
4119
  import {
3415
4120
  ReactFlow,
3416
4121
  Background,
@@ -3757,9 +4462,9 @@ function sliceOverlay(overlay, index) {
3757
4462
  }
3758
4463
 
3759
4464
  // src/components/StageNode/StageNode.tsx
3760
- import { memo as memo3, useEffect as useEffect6, useRef as useRef6 } from "react";
4465
+ import { memo as memo5, useEffect as useEffect6, useRef as useRef6 } from "react";
3761
4466
  import { Handle, Position } from "@xyflow/react";
3762
- import { Fragment as Fragment5, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
4467
+ import { Fragment as Fragment7, jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
3763
4468
  var KEYFRAMES_ID = "fp-stage-node-keyframes";
3764
4469
  var KEYFRAMES_CSS = `
3765
4470
  @media (prefers-reduced-motion: no-preference) {
@@ -3785,128 +4490,128 @@ function StageIcon({ type, color }) {
3785
4490
  // LLM / AI call — brain/sparkle
3786
4491
  case "llm":
3787
4492
  case "ai":
3788
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3789
- /* @__PURE__ */ jsx16("circle", { cx: "8", cy: "8", r: "6", stroke: color, strokeWidth: "1.5" }),
3790
- /* @__PURE__ */ jsx16("path", { d: "M5.5 8C5.5 6.5 6.5 5 8 5S10.5 6.5 10.5 8", stroke: color, strokeWidth: "1.2", strokeLinecap: "round" }),
3791
- /* @__PURE__ */ jsx16("circle", { cx: "8", cy: "9.5", r: "1", fill: color }),
3792
- /* @__PURE__ */ jsx16("line", { x1: "8", y1: "2", x2: "8", y2: "3.5", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
3793
- /* @__PURE__ */ jsx16("line", { x1: "12.5", y1: "4", x2: "11.2", y2: "5", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
3794
- /* @__PURE__ */ jsx16("line", { x1: "3.5", y1: "4", x2: "4.8", y2: "5", stroke: color, strokeWidth: "1", strokeLinecap: "round" })
4493
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4494
+ /* @__PURE__ */ jsx18("circle", { cx: "8", cy: "8", r: "6", stroke: color, strokeWidth: "1.5" }),
4495
+ /* @__PURE__ */ jsx18("path", { d: "M5.5 8C5.5 6.5 6.5 5 8 5S10.5 6.5 10.5 8", stroke: color, strokeWidth: "1.2", strokeLinecap: "round" }),
4496
+ /* @__PURE__ */ jsx18("circle", { cx: "8", cy: "9.5", r: "1", fill: color }),
4497
+ /* @__PURE__ */ jsx18("line", { x1: "8", y1: "2", x2: "8", y2: "3.5", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
4498
+ /* @__PURE__ */ jsx18("line", { x1: "12.5", y1: "4", x2: "11.2", y2: "5", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
4499
+ /* @__PURE__ */ jsx18("line", { x1: "3.5", y1: "4", x2: "4.8", y2: "5", stroke: color, strokeWidth: "1", strokeLinecap: "round" })
3795
4500
  ] });
3796
4501
  // Tool / function call — gear
3797
4502
  case "tool":
3798
4503
  case "function":
3799
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3800
- /* @__PURE__ */ jsx16("circle", { cx: "8", cy: "8", r: "3", stroke: color, strokeWidth: "1.5" }),
4504
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4505
+ /* @__PURE__ */ jsx18("circle", { cx: "8", cy: "8", r: "3", stroke: color, strokeWidth: "1.5" }),
3801
4506
  [0, 45, 90, 135, 180, 225, 270, 315].map((angle) => {
3802
4507
  const rad = angle * Math.PI / 180;
3803
4508
  const x1 = 8 + Math.cos(rad) * 4.5;
3804
4509
  const y1 = 8 + Math.sin(rad) * 4.5;
3805
4510
  const x2 = 8 + Math.cos(rad) * 6;
3806
4511
  const y2 = 8 + Math.sin(rad) * 6;
3807
- return /* @__PURE__ */ jsx16("line", { x1, y1, x2, y2, stroke: color, strokeWidth: "1.5", strokeLinecap: "round" }, angle);
4512
+ return /* @__PURE__ */ jsx18("line", { x1, y1, x2, y2, stroke: color, strokeWidth: "1.5", strokeLinecap: "round" }, angle);
3808
4513
  })
3809
4514
  ] });
3810
4515
  // RAG / retrieval — magnifying glass + doc
3811
4516
  case "rag":
3812
4517
  case "search":
3813
4518
  case "retrieval":
3814
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3815
- /* @__PURE__ */ jsx16("circle", { cx: "7", cy: "7", r: "4", stroke: color, strokeWidth: "1.5" }),
3816
- /* @__PURE__ */ jsx16("line", { x1: "10", y1: "10", x2: "13.5", y2: "13.5", stroke: color, strokeWidth: "1.5", strokeLinecap: "round" }),
3817
- /* @__PURE__ */ jsx16("line", { x1: "5.5", y1: "6", x2: "8.5", y2: "6", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
3818
- /* @__PURE__ */ jsx16("line", { x1: "5.5", y1: "8", x2: "7.5", y2: "8", stroke: color, strokeWidth: "1", strokeLinecap: "round" })
4519
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4520
+ /* @__PURE__ */ jsx18("circle", { cx: "7", cy: "7", r: "4", stroke: color, strokeWidth: "1.5" }),
4521
+ /* @__PURE__ */ jsx18("line", { x1: "10", y1: "10", x2: "13.5", y2: "13.5", stroke: color, strokeWidth: "1.5", strokeLinecap: "round" }),
4522
+ /* @__PURE__ */ jsx18("line", { x1: "5.5", y1: "6", x2: "8.5", y2: "6", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
4523
+ /* @__PURE__ */ jsx18("line", { x1: "5.5", y1: "8", x2: "7.5", y2: "8", stroke: color, strokeWidth: "1", strokeLinecap: "round" })
3819
4524
  ] });
3820
4525
  // Parse / process — diamond with arrows
3821
4526
  case "parse":
3822
4527
  case "process":
3823
4528
  case "transform":
3824
- return /* @__PURE__ */ jsx16("svg", { ...props, children: /* @__PURE__ */ jsx16("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: color, strokeWidth: "1.5", transform: "rotate(45 8 8)" }) });
4529
+ return /* @__PURE__ */ jsx18("svg", { ...props, children: /* @__PURE__ */ jsx18("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", stroke: color, strokeWidth: "1.5", transform: "rotate(45 8 8)" }) });
3825
4530
  // Start / seed — play triangle
3826
4531
  case "start":
3827
4532
  case "seed":
3828
4533
  case "init":
3829
- return /* @__PURE__ */ jsx16("svg", { ...props, children: /* @__PURE__ */ jsx16("path", { d: "M5 3.5L12.5 8L5 12.5V3.5Z", fill: color, opacity: "0.8" }) });
4534
+ return /* @__PURE__ */ jsx18("svg", { ...props, children: /* @__PURE__ */ jsx18("path", { d: "M5 3.5L12.5 8L5 12.5V3.5Z", fill: color, opacity: "0.8" }) });
3830
4535
  // End / finalize — stop square
3831
4536
  case "end":
3832
4537
  case "finalize":
3833
4538
  case "output":
3834
- return /* @__PURE__ */ jsx16("svg", { ...props, children: /* @__PURE__ */ jsx16("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", fill: color, opacity: "0.8" }) });
4539
+ return /* @__PURE__ */ jsx18("svg", { ...props, children: /* @__PURE__ */ jsx18("rect", { x: "4", y: "4", width: "8", height: "8", rx: "1.5", fill: color, opacity: "0.8" }) });
3835
4540
  // Agent — person silhouette
3836
4541
  case "agent":
3837
4542
  case "orchestrator":
3838
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3839
- /* @__PURE__ */ jsx16("circle", { cx: "8", cy: "5", r: "2.5", stroke: color, strokeWidth: "1.5" }),
3840
- /* @__PURE__ */ jsx16("path", { d: "M3.5 14C3.5 11 5.5 9 8 9S12.5 11 12.5 14", stroke: color, strokeWidth: "1.5", strokeLinecap: "round" })
4543
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4544
+ /* @__PURE__ */ jsx18("circle", { cx: "8", cy: "5", r: "2.5", stroke: color, strokeWidth: "1.5" }),
4545
+ /* @__PURE__ */ jsx18("path", { d: "M3.5 14C3.5 11 5.5 9 8 9S12.5 11 12.5 14", stroke: color, strokeWidth: "1.5", strokeLinecap: "round" })
3841
4546
  ] });
3842
4547
  // Swarm — multi-agent
3843
4548
  case "swarm":
3844
4549
  case "multi-agent":
3845
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3846
- /* @__PURE__ */ jsx16("circle", { cx: "5", cy: "5", r: "2", stroke: color, strokeWidth: "1.2" }),
3847
- /* @__PURE__ */ jsx16("circle", { cx: "11", cy: "5", r: "2", stroke: color, strokeWidth: "1.2" }),
3848
- /* @__PURE__ */ jsx16("circle", { cx: "8", cy: "11", r: "2", stroke: color, strokeWidth: "1.2" }),
3849
- /* @__PURE__ */ jsx16("line", { x1: "5", y1: "7", x2: "8", y2: "9", stroke: color, strokeWidth: "1", opacity: "0.5" }),
3850
- /* @__PURE__ */ jsx16("line", { x1: "11", y1: "7", x2: "8", y2: "9", stroke: color, strokeWidth: "1", opacity: "0.5" })
4550
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4551
+ /* @__PURE__ */ jsx18("circle", { cx: "5", cy: "5", r: "2", stroke: color, strokeWidth: "1.2" }),
4552
+ /* @__PURE__ */ jsx18("circle", { cx: "11", cy: "5", r: "2", stroke: color, strokeWidth: "1.2" }),
4553
+ /* @__PURE__ */ jsx18("circle", { cx: "8", cy: "11", r: "2", stroke: color, strokeWidth: "1.2" }),
4554
+ /* @__PURE__ */ jsx18("line", { x1: "5", y1: "7", x2: "8", y2: "9", stroke: color, strokeWidth: "1", opacity: "0.5" }),
4555
+ /* @__PURE__ */ jsx18("line", { x1: "11", y1: "7", x2: "8", y2: "9", stroke: color, strokeWidth: "1", opacity: "0.5" })
3851
4556
  ] });
3852
4557
  // Guard / guardrail — shield
3853
4558
  case "guard":
3854
4559
  case "guardrail":
3855
4560
  case "validate":
3856
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3857
- /* @__PURE__ */ jsx16("path", { d: "M8 2L3 5V9C3 11.5 5 13.5 8 14.5C11 13.5 13 11.5 13 9V5L8 2Z", stroke: color, strokeWidth: "1.5", strokeLinejoin: "round" }),
3858
- /* @__PURE__ */ jsx16("path", { d: "M6 8L7.5 9.5L10 6.5", stroke: color, strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
4561
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4562
+ /* @__PURE__ */ jsx18("path", { d: "M8 2L3 5V9C3 11.5 5 13.5 8 14.5C11 13.5 13 11.5 13 9V5L8 2Z", stroke: color, strokeWidth: "1.5", strokeLinejoin: "round" }),
4563
+ /* @__PURE__ */ jsx18("path", { d: "M6 8L7.5 9.5L10 6.5", stroke: color, strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round" })
3859
4564
  ] });
3860
4565
  // Stream — wave
3861
4566
  case "stream":
3862
4567
  case "streaming":
3863
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3864
- /* @__PURE__ */ jsx16("path", { d: "M2 8C4 5 6 11 8 8S12 5 14 8", stroke: color, strokeWidth: "1.5", strokeLinecap: "round", fill: "none" }),
3865
- /* @__PURE__ */ jsx16("path", { d: "M2 11C4 8 6 14 8 11S12 8 14 11", stroke: color, strokeWidth: "1", strokeLinecap: "round", fill: "none", opacity: "0.5" })
4568
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4569
+ /* @__PURE__ */ jsx18("path", { d: "M2 8C4 5 6 11 8 8S12 5 14 8", stroke: color, strokeWidth: "1.5", strokeLinecap: "round", fill: "none" }),
4570
+ /* @__PURE__ */ jsx18("path", { d: "M2 11C4 8 6 14 8 11S12 8 14 11", stroke: color, strokeWidth: "1", strokeLinecap: "round", fill: "none", opacity: "0.5" })
3866
4571
  ] });
3867
4572
  // Memory / state — database cylinder
3868
4573
  case "memory":
3869
4574
  case "state":
3870
4575
  case "db":
3871
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3872
- /* @__PURE__ */ jsx16("ellipse", { cx: "8", cy: "4.5", rx: "5", ry: "2", stroke: color, strokeWidth: "1.3" }),
3873
- /* @__PURE__ */ jsx16("line", { x1: "3", y1: "4.5", x2: "3", y2: "11.5", stroke: color, strokeWidth: "1.3" }),
3874
- /* @__PURE__ */ jsx16("line", { x1: "13", y1: "4.5", x2: "13", y2: "11.5", stroke: color, strokeWidth: "1.3" }),
3875
- /* @__PURE__ */ jsx16("ellipse", { cx: "8", cy: "11.5", rx: "5", ry: "2", stroke: color, strokeWidth: "1.3" })
4576
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4577
+ /* @__PURE__ */ jsx18("ellipse", { cx: "8", cy: "4.5", rx: "5", ry: "2", stroke: color, strokeWidth: "1.3" }),
4578
+ /* @__PURE__ */ jsx18("line", { x1: "3", y1: "4.5", x2: "3", y2: "11.5", stroke: color, strokeWidth: "1.3" }),
4579
+ /* @__PURE__ */ jsx18("line", { x1: "13", y1: "4.5", x2: "13", y2: "11.5", stroke: color, strokeWidth: "1.3" }),
4580
+ /* @__PURE__ */ jsx18("ellipse", { cx: "8", cy: "11.5", rx: "5", ry: "2", stroke: color, strokeWidth: "1.3" })
3876
4581
  ] });
3877
4582
  // System prompt — document with lines
3878
4583
  case "system-prompt":
3879
4584
  case "prompt":
3880
4585
  case "instructions":
3881
4586
  case "document":
3882
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3883
- /* @__PURE__ */ jsx16("rect", { x: "3.5", y: "2", width: "9", height: "12", rx: "1.5", stroke: color, strokeWidth: "1.3", fill: "none" }),
3884
- /* @__PURE__ */ jsx16("line", { x1: "5.5", y1: "5", x2: "10.5", y2: "5", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
3885
- /* @__PURE__ */ jsx16("line", { x1: "5.5", y1: "7.5", x2: "10.5", y2: "7.5", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
3886
- /* @__PURE__ */ jsx16("line", { x1: "5.5", y1: "10", x2: "8.5", y2: "10", stroke: color, strokeWidth: "1", strokeLinecap: "round" })
4587
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4588
+ /* @__PURE__ */ jsx18("rect", { x: "3.5", y: "2", width: "9", height: "12", rx: "1.5", stroke: color, strokeWidth: "1.3", fill: "none" }),
4589
+ /* @__PURE__ */ jsx18("line", { x1: "5.5", y1: "5", x2: "10.5", y2: "5", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
4590
+ /* @__PURE__ */ jsx18("line", { x1: "5.5", y1: "7.5", x2: "10.5", y2: "7.5", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
4591
+ /* @__PURE__ */ jsx18("line", { x1: "5.5", y1: "10", x2: "8.5", y2: "10", stroke: color, strokeWidth: "1", strokeLinecap: "round" })
3887
4592
  ] });
3888
4593
  // Messages / conversation — chat bubble
3889
4594
  case "messages":
3890
4595
  case "chat":
3891
4596
  case "conversation":
3892
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3893
- /* @__PURE__ */ jsx16("rect", { x: "2.5", y: "3", width: "11", height: "8", rx: "2", stroke: color, strokeWidth: "1.3", fill: "none" }),
3894
- /* @__PURE__ */ jsx16("path", { d: "M5.5 11L5.5 13.5L8.5 11", stroke: color, strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }),
3895
- /* @__PURE__ */ jsx16("line", { x1: "5", y1: "6", x2: "11", y2: "6", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
3896
- /* @__PURE__ */ jsx16("line", { x1: "5", y1: "8.5", x2: "9", y2: "8.5", stroke: color, strokeWidth: "1", strokeLinecap: "round" })
4597
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4598
+ /* @__PURE__ */ jsx18("rect", { x: "2.5", y: "3", width: "11", height: "8", rx: "2", stroke: color, strokeWidth: "1.3", fill: "none" }),
4599
+ /* @__PURE__ */ jsx18("path", { d: "M5.5 11L5.5 13.5L8.5 11", stroke: color, strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }),
4600
+ /* @__PURE__ */ jsx18("line", { x1: "5", y1: "6", x2: "11", y2: "6", stroke: color, strokeWidth: "1", strokeLinecap: "round" }),
4601
+ /* @__PURE__ */ jsx18("line", { x1: "5", y1: "8.5", x2: "9", y2: "8.5", stroke: color, strokeWidth: "1", strokeLinecap: "round" })
3897
4602
  ] });
3898
4603
  // Loop — circular arrow
3899
4604
  case "loop":
3900
4605
  case "retry":
3901
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3902
- /* @__PURE__ */ jsx16("path", { d: "M12 8A4 4 0 1 1 8 4", stroke: color, strokeWidth: "1.5", strokeLinecap: "round", fill: "none" }),
3903
- /* @__PURE__ */ jsx16("path", { d: "M8 1.5L10.5 4L8 6.5", stroke: color, strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" })
4606
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4607
+ /* @__PURE__ */ jsx18("path", { d: "M12 8A4 4 0 1 1 8 4", stroke: color, strokeWidth: "1.5", strokeLinecap: "round", fill: "none" }),
4608
+ /* @__PURE__ */ jsx18("path", { d: "M8 1.5L10.5 4L8 6.5", stroke: color, strokeWidth: "1.3", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" })
3904
4609
  ] });
3905
4610
  // Lazy / service — cloud (deferred resolution, loaded on demand)
3906
4611
  case "lazy":
3907
4612
  case "service":
3908
4613
  case "cloud":
3909
- return /* @__PURE__ */ jsx16("svg", { ...props, children: /* @__PURE__ */ jsx16(
4614
+ return /* @__PURE__ */ jsx18("svg", { ...props, children: /* @__PURE__ */ jsx18(
3910
4615
  "path",
3911
4616
  {
3912
4617
  d: "M4.5 12C2.8 12 1.5 10.7 1.5 9C1.5 7.5 2.5 6.3 3.8 6C4 4 5.8 2.5 8 2.5C9.8 2.5 11.3 3.5 11.9 5C13.9 5.2 15.5 6.8 15.5 8.8C15.5 10.8 13.9 12.5 11.8 12.5H4.5",
@@ -3919,15 +4624,15 @@ function StageIcon({ type, color }) {
3919
4624
  // Decision — diamond (already handled by isDecider shape)
3920
4625
  case "decision":
3921
4626
  case "router":
3922
- return /* @__PURE__ */ jsxs15("svg", { ...props, children: [
3923
- /* @__PURE__ */ jsx16("path", { d: "M8 2L14 8L8 14L2 8Z", stroke: color, strokeWidth: "1.5", fill: "none" }),
3924
- /* @__PURE__ */ jsx16("circle", { cx: "8", cy: "8", r: "1.5", fill: color })
4627
+ return /* @__PURE__ */ jsxs17("svg", { ...props, children: [
4628
+ /* @__PURE__ */ jsx18("path", { d: "M8 2L14 8L8 14L2 8Z", stroke: color, strokeWidth: "1.5", fill: "none" }),
4629
+ /* @__PURE__ */ jsx18("circle", { cx: "8", cy: "8", r: "1.5", fill: color })
3925
4630
  ] });
3926
4631
  default:
3927
4632
  return null;
3928
4633
  }
3929
4634
  }
3930
- var StageNode = memo3(function StageNode2({
4635
+ var StageNode = memo5(function StageNode2({
3931
4636
  data
3932
4637
  }) {
3933
4638
  const { label, active, done, error, linked, icon, stepNumbers, dimmed, isSubflow, isLazy, isDecider, isFork, description, stageId, showStageId } = data;
@@ -3955,9 +4660,9 @@ var StageNode = memo3(function StageNode2({
3955
4660
  const borderColor = active ? theme.nodeCursor : isHero && done ? theme.nodeMain : done ? theme.nodeVisited : error ? theme.error : restingBorder;
3956
4661
  const shadow = active ? `0 0 22px color-mix(in srgb, ${theme.nodeCursor} 55%, transparent)` : isHero && done ? `0 0 12px color-mix(in srgb, ${theme.nodeMain} 30%, transparent)` : done ? `0 0 8px color-mix(in srgb, ${theme.nodeVisited} 20%, transparent)` : error ? `0 0 12px color-mix(in srgb, ${theme.error} 30%, transparent)` : restingShadow;
3957
4662
  const textColor = active ? "#1a1a1a" : done || error ? "#fff" : theme.textPrimary;
3958
- return /* @__PURE__ */ jsxs15(Fragment5, { children: [
3959
- /* @__PURE__ */ jsx16(Handle, { type: "target", position: Position.Top, style: { opacity: 0 } }),
3960
- /* @__PURE__ */ jsx16("div", { style: { width: "100%", display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsxs15(
4663
+ return /* @__PURE__ */ jsxs17(Fragment7, { children: [
4664
+ /* @__PURE__ */ jsx18(Handle, { type: "target", position: Position.Top, style: { opacity: 0 } }),
4665
+ /* @__PURE__ */ jsx18("div", { style: { width: "100%", display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsxs17(
3961
4666
  "div",
3962
4667
  {
3963
4668
  style: {
@@ -3970,7 +4675,7 @@ var StageNode = memo3(function StageNode2({
3970
4675
  opacity: isMuted ? 0.5 : void 0
3971
4676
  },
3972
4677
  children: [
3973
- stepNumbers && stepNumbers.length > 0 && isOnPath && /* @__PURE__ */ jsx16(
4678
+ stepNumbers && stepNumbers.length > 0 && isOnPath && /* @__PURE__ */ jsx18(
3974
4679
  "div",
3975
4680
  {
3976
4681
  style: {
@@ -3985,7 +4690,7 @@ var StageNode = memo3(function StageNode2({
3985
4690
  const isLatest = i === stepNumbers.length - 1;
3986
4691
  const badgeBg = isLatest && active ? theme.nodeCursor : theme.nodeVisited;
3987
4692
  const glow = isLatest && active ? `color-mix(in srgb, ${theme.nodeCursor} 50%, transparent)` : `color-mix(in srgb, ${theme.nodeVisited} 40%, transparent)`;
3988
- return /* @__PURE__ */ jsx16(
4693
+ return /* @__PURE__ */ jsx18(
3989
4694
  "div",
3990
4695
  {
3991
4696
  style: {
@@ -4008,7 +4713,7 @@ var StageNode = memo3(function StageNode2({
4008
4713
  })
4009
4714
  }
4010
4715
  ),
4011
- linked && /* @__PURE__ */ jsx16(
4716
+ linked && /* @__PURE__ */ jsx18(
4012
4717
  "div",
4013
4718
  {
4014
4719
  style: {
@@ -4022,7 +4727,7 @@ var StageNode = memo3(function StageNode2({
4022
4727
  }
4023
4728
  }
4024
4729
  ),
4025
- active && /* @__PURE__ */ jsx16(
4730
+ active && /* @__PURE__ */ jsx18(
4026
4731
  "div",
4027
4732
  {
4028
4733
  style: {
@@ -4036,7 +4741,7 @@ var StageNode = memo3(function StageNode2({
4036
4741
  }
4037
4742
  }
4038
4743
  ),
4039
- active && /* @__PURE__ */ jsx16(
4744
+ active && /* @__PURE__ */ jsx18(
4040
4745
  "div",
4041
4746
  {
4042
4747
  style: {
@@ -4056,8 +4761,8 @@ var StageNode = memo3(function StageNode2({
4056
4761
  children: "NOW"
4057
4762
  }
4058
4763
  ),
4059
- isDecider ? /* @__PURE__ */ jsxs15("div", { style: { position: "relative", width: 120, height: 72 }, children: [
4060
- /* @__PURE__ */ jsx16(
4764
+ isDecider ? /* @__PURE__ */ jsxs17("div", { style: { position: "relative", width: 120, height: 72 }, children: [
4765
+ /* @__PURE__ */ jsx18(
4061
4766
  "div",
4062
4767
  {
4063
4768
  style: {
@@ -4071,7 +4776,7 @@ var StageNode = memo3(function StageNode2({
4071
4776
  }
4072
4777
  }
4073
4778
  ),
4074
- /* @__PURE__ */ jsx16(
4779
+ /* @__PURE__ */ jsx18(
4075
4780
  "div",
4076
4781
  {
4077
4782
  style: {
@@ -4087,7 +4792,7 @@ var StageNode = memo3(function StageNode2({
4087
4792
  }
4088
4793
  }
4089
4794
  ),
4090
- /* @__PURE__ */ jsxs15(
4795
+ /* @__PURE__ */ jsxs17(
4091
4796
  "div",
4092
4797
  {
4093
4798
  style: {
@@ -4102,10 +4807,10 @@ var StageNode = memo3(function StageNode2({
4102
4807
  zIndex: 1
4103
4808
  },
4104
4809
  children: [
4105
- /* @__PURE__ */ jsxs15("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
4106
- effectiveIcon && /* @__PURE__ */ jsx16(StageIcon, { type: effectiveIcon, color: textColor }),
4107
- !effectiveIcon && /* @__PURE__ */ jsx16("span", { style: { fontSize: 9, color: textColor }, children: "\u25C7" }),
4108
- /* @__PURE__ */ jsx16(
4810
+ /* @__PURE__ */ jsxs17("div", { style: { display: "flex", alignItems: "center", gap: 4 }, children: [
4811
+ effectiveIcon && /* @__PURE__ */ jsx18(StageIcon, { type: effectiveIcon, color: textColor }),
4812
+ !effectiveIcon && /* @__PURE__ */ jsx18("span", { style: { fontSize: 9, color: textColor }, children: "\u25C7" }),
4813
+ /* @__PURE__ */ jsx18(
4109
4814
  "span",
4110
4815
  {
4111
4816
  style: {
@@ -4118,7 +4823,7 @@ var StageNode = memo3(function StageNode2({
4118
4823
  }
4119
4824
  )
4120
4825
  ] }),
4121
- description && /* @__PURE__ */ jsx16(
4826
+ description && /* @__PURE__ */ jsx18(
4122
4827
  "span",
4123
4828
  {
4124
4829
  style: {
@@ -4134,7 +4839,7 @@ var StageNode = memo3(function StageNode2({
4134
4839
  children: description
4135
4840
  }
4136
4841
  ),
4137
- showStageId && stageId && /* @__PURE__ */ jsx16(
4842
+ showStageId && stageId && /* @__PURE__ */ jsx18(
4138
4843
  "span",
4139
4844
  {
4140
4845
  style: {
@@ -4156,7 +4861,7 @@ var StageNode = memo3(function StageNode2({
4156
4861
  )
4157
4862
  ] }) : (
4158
4863
  /* Standard rectangular node */
4159
- /* @__PURE__ */ jsxs15(
4864
+ /* @__PURE__ */ jsxs17(
4160
4865
  "div",
4161
4866
  {
4162
4867
  style: {
@@ -4175,10 +4880,10 @@ var StageNode = memo3(function StageNode2({
4175
4880
  justifyContent: "center"
4176
4881
  },
4177
4882
  children: [
4178
- /* @__PURE__ */ jsxs15("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
4179
- effectiveIcon && /* @__PURE__ */ jsx16(StageIcon, { type: effectiveIcon, color: textColor }),
4180
- done && !effectiveIcon && /* @__PURE__ */ jsx16("span", { style: { fontSize: 10, color: textColor }, children: "\u2713" }),
4181
- active && !effectiveIcon && /* @__PURE__ */ jsx16(
4883
+ /* @__PURE__ */ jsxs17("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
4884
+ effectiveIcon && /* @__PURE__ */ jsx18(StageIcon, { type: effectiveIcon, color: textColor }),
4885
+ done && !effectiveIcon && /* @__PURE__ */ jsx18("span", { style: { fontSize: 10, color: textColor }, children: "\u2713" }),
4886
+ active && !effectiveIcon && /* @__PURE__ */ jsx18(
4182
4887
  "span",
4183
4888
  {
4184
4889
  style: {
@@ -4191,8 +4896,8 @@ var StageNode = memo3(function StageNode2({
4191
4896
  }
4192
4897
  }
4193
4898
  ),
4194
- error && !effectiveIcon && /* @__PURE__ */ jsx16("span", { style: { fontSize: 10, color: textColor }, children: "\u2717" }),
4195
- /* @__PURE__ */ jsx16(
4899
+ error && !effectiveIcon && /* @__PURE__ */ jsx18("span", { style: { fontSize: 10, color: textColor }, children: "\u2717" }),
4900
+ /* @__PURE__ */ jsx18(
4196
4901
  "span",
4197
4902
  {
4198
4903
  style: {
@@ -4204,7 +4909,7 @@ var StageNode = memo3(function StageNode2({
4204
4909
  children: label
4205
4910
  }
4206
4911
  ),
4207
- isSubflow && /* @__PURE__ */ jsx16(
4912
+ isSubflow && /* @__PURE__ */ jsx18(
4208
4913
  "span",
4209
4914
  {
4210
4915
  style: {
@@ -4219,7 +4924,7 @@ var StageNode = memo3(function StageNode2({
4219
4924
  opacity: 0.7,
4220
4925
  flexShrink: 0
4221
4926
  },
4222
- children: /* @__PURE__ */ jsx16(
4927
+ children: /* @__PURE__ */ jsx18(
4223
4928
  "span",
4224
4929
  {
4225
4930
  style: {
@@ -4233,7 +4938,7 @@ var StageNode = memo3(function StageNode2({
4233
4938
  }
4234
4939
  )
4235
4940
  ] }),
4236
- description && /* @__PURE__ */ jsx16(
4941
+ description && /* @__PURE__ */ jsx18(
4237
4942
  "span",
4238
4943
  {
4239
4944
  style: {
@@ -4249,7 +4954,7 @@ var StageNode = memo3(function StageNode2({
4249
4954
  children: description
4250
4955
  }
4251
4956
  ),
4252
- showStageId && stageId && /* @__PURE__ */ jsx16(
4957
+ showStageId && stageId && /* @__PURE__ */ jsx18(
4253
4958
  "span",
4254
4959
  {
4255
4960
  style: {
@@ -4273,7 +4978,7 @@ var StageNode = memo3(function StageNode2({
4273
4978
  ]
4274
4979
  }
4275
4980
  ) }),
4276
- /* @__PURE__ */ jsx16(Handle, { type: "source", position: Position.Bottom, style: { opacity: 0 } })
4981
+ /* @__PURE__ */ jsx18(Handle, { type: "source", position: Position.Bottom, style: { opacity: 0 } })
4277
4982
  ] });
4278
4983
  });
4279
4984
 
@@ -4325,9 +5030,9 @@ function aggregateMountStatus(slice, graph, currentSubflowId) {
4325
5030
  }
4326
5031
 
4327
5032
  // src/components/FlowchartView/_internal/useSubflowDrill.ts
4328
- import { useCallback as useCallback6, useEffect as useEffect7, useRef as useRef7, useState as useState9 } from "react";
5033
+ import { useCallback as useCallback6, useEffect as useEffect7, useRef as useRef7, useState as useState10 } from "react";
4329
5034
  function useSubflowDrill(graph, onSubflowChange) {
4330
- const [currentSubflowId, setCurrentSubflowId] = useState9(null);
5035
+ const [currentSubflowId, setCurrentSubflowId] = useState10(null);
4331
5036
  const lastGraphRef = useRef7(null);
4332
5037
  if (lastGraphRef.current !== graph) {
4333
5038
  lastGraphRef.current = graph;
@@ -4396,9 +5101,9 @@ function useChartAutoRefit(wrapperRef, rfInstance, options = {}) {
4396
5101
  }
4397
5102
 
4398
5103
  // src/components/FlowchartView/SubflowBreadcrumbBar.tsx
4399
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
5104
+ import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
4400
5105
  function SubflowBreadcrumbBar({ entries, onNavigate }) {
4401
- return /* @__PURE__ */ jsx17(
5106
+ return /* @__PURE__ */ jsx19(
4402
5107
  "div",
4403
5108
  {
4404
5109
  style: {
@@ -4414,12 +5119,12 @@ function SubflowBreadcrumbBar({ entries, onNavigate }) {
4414
5119
  "aria-label": "Subflow breadcrumb",
4415
5120
  children: entries.map((entry, i) => {
4416
5121
  const isLast = i === entries.length - 1;
4417
- return /* @__PURE__ */ jsxs16(
5122
+ return /* @__PURE__ */ jsxs18(
4418
5123
  "span",
4419
5124
  {
4420
5125
  style: { display: "inline-flex", alignItems: "center", gap: 6 },
4421
5126
  children: [
4422
- /* @__PURE__ */ jsx17(
5127
+ /* @__PURE__ */ jsx19(
4423
5128
  "button",
4424
5129
  {
4425
5130
  type: "button",
@@ -4439,7 +5144,7 @@ function SubflowBreadcrumbBar({ entries, onNavigate }) {
4439
5144
  children: entry.label
4440
5145
  }
4441
5146
  ),
4442
- !isLast && /* @__PURE__ */ jsx17("span", { style: { color: theme.textMuted }, children: "\u203A" })
5147
+ !isLast && /* @__PURE__ */ jsx19("span", { style: { color: theme.textMuted }, children: "\u203A" })
4443
5148
  ]
4444
5149
  },
4445
5150
  entry.subflowId ?? "__top__"
@@ -4451,11 +5156,11 @@ function SubflowBreadcrumbBar({ entries, onNavigate }) {
4451
5156
 
4452
5157
  // src/components/GroupContainerNode/GroupContainerNode.tsx
4453
5158
  import { Handle as Handle2, Position as Position2 } from "@xyflow/react";
4454
- import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
5159
+ import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
4455
5160
  function GroupContainerNode({ data }) {
4456
5161
  const d = data;
4457
5162
  const borderColor = d.error ? theme.error : d.active ? theme.primary : d.done ? theme.nodeVisited : theme.border;
4458
- return /* @__PURE__ */ jsxs17(
5163
+ return /* @__PURE__ */ jsxs19(
4459
5164
  "div",
4460
5165
  {
4461
5166
  style: {
@@ -4471,7 +5176,7 @@ function GroupContainerNode({ data }) {
4471
5176
  position: "relative"
4472
5177
  },
4473
5178
  children: [
4474
- /* @__PURE__ */ jsxs17(
5179
+ /* @__PURE__ */ jsxs19(
4475
5180
  "div",
4476
5181
  {
4477
5182
  style: {
@@ -4485,13 +5190,13 @@ function GroupContainerNode({ data }) {
4485
5190
  letterSpacing: 0.2
4486
5191
  },
4487
5192
  children: [
4488
- d.icon ? /* @__PURE__ */ jsx18("span", { "aria-hidden": true, children: d.icon }) : null,
4489
- /* @__PURE__ */ jsx18("span", { children: d.label })
5193
+ d.icon ? /* @__PURE__ */ jsx20("span", { "aria-hidden": true, children: d.icon }) : null,
5194
+ /* @__PURE__ */ jsx20("span", { children: d.label })
4490
5195
  ]
4491
5196
  }
4492
5197
  ),
4493
- /* @__PURE__ */ jsx18(Handle2, { type: "target", position: Position2.Top, style: { opacity: 0 } }),
4494
- /* @__PURE__ */ jsx18(Handle2, { type: "source", position: Position2.Bottom, style: { opacity: 0 } })
5198
+ /* @__PURE__ */ jsx20(Handle2, { type: "target", position: Position2.Top, style: { opacity: 0 } }),
5199
+ /* @__PURE__ */ jsx20(Handle2, { type: "source", position: Position2.Bottom, style: { opacity: 0 } })
4495
5200
  ]
4496
5201
  }
4497
5202
  );
@@ -4717,7 +5422,7 @@ function wrapInMainChartBox(graph, opts) {
4717
5422
  }
4718
5423
 
4719
5424
  // src/components/LoopBackEdge/LoopBackEdge.tsx
4720
- import { jsx as jsx19 } from "react/jsx-runtime";
5425
+ import { jsx as jsx21 } from "react/jsx-runtime";
4721
5426
  var LOOP_DASH = "5 5";
4722
5427
  var LOOP_STROKE_OPACITY_CAP = 0.55;
4723
5428
  var LOOP_STROKE_WIDTH = 1.5;
@@ -4756,7 +5461,7 @@ function LoopBackEdge({ id, source, target, markerEnd, style }) {
4756
5461
  );
4757
5462
  });
4758
5463
  if (!path) return null;
4759
- return /* @__PURE__ */ jsx19(
5464
+ return /* @__PURE__ */ jsx21(
4760
5465
  BaseEdge,
4761
5466
  {
4762
5467
  id,
@@ -4794,7 +5499,7 @@ function resolveStepBendY(forkBend, staggeredBend) {
4794
5499
  }
4795
5500
 
4796
5501
  // src/components/SmartStepEdge/SmartStepEdge.tsx
4797
- import { jsx as jsx20 } from "react/jsx-runtime";
5502
+ import { jsx as jsx22 } from "react/jsx-runtime";
4798
5503
  function SmartStepEdge({
4799
5504
  id,
4800
5505
  source,
@@ -4845,7 +5550,7 @@ function SmartStepEdge({
4845
5550
  // use its default centerY (== the built-in `smoothstep` path, byte-for-byte).
4846
5551
  ...bendY !== null ? { centerY: bendY } : {}
4847
5552
  });
4848
- return /* @__PURE__ */ jsx20(BaseEdge2, { id, path, markerEnd, style });
5553
+ return /* @__PURE__ */ jsx22(BaseEdge2, { id, path, markerEnd, style });
4849
5554
  }
4850
5555
 
4851
5556
  // src/components/FlowchartView/_internal/MeasuredNodeSizes.tsx
@@ -4892,7 +5597,7 @@ function MeasuredNodeSizes({
4892
5597
  }
4893
5598
 
4894
5599
  // src/components/FlowchartView/TracedFlow.tsx
4895
- import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
5600
+ import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
4896
5601
  var DEFAULT_COLORS = {
4897
5602
  default: rawDefaults.colors.textMuted,
4898
5603
  done: rawDefaults.colors.success,
@@ -5038,21 +5743,21 @@ function TracedFlow({
5038
5743
  );
5039
5744
  }
5040
5745
  }, [layoutProp]);
5041
- const colors = useMemo10(
5746
+ const colors = useMemo13(
5042
5747
  () => ({ ...DEFAULT_COLORS, ...colorOverrides ?? {} }),
5043
5748
  [colorOverrides]
5044
5749
  );
5045
- const mergedNodeTypes = useMemo10(
5750
+ const mergedNodeTypes = useMemo13(
5046
5751
  () => userNodeTypes ? { ...DEFAULT_NODE_TYPES, ...userNodeTypes } : DEFAULT_NODE_TYPES,
5047
5752
  [userNodeTypes]
5048
5753
  );
5049
- const mergedEdgeTypes = useMemo10(
5754
+ const mergedEdgeTypes = useMemo13(
5050
5755
  () => userEdgeTypes ? { ...DEFAULT_EDGE_TYPES, ...userEdgeTypes } : DEFAULT_EDGE_TYPES,
5051
5756
  [userEdgeTypes]
5052
5757
  );
5053
5758
  const drill = useSubflowDrill(graph, onSubflowChange);
5054
- const groupedSet = useMemo10(() => new Set(groupedSubflows ?? []), [groupedSubflows]);
5055
- const filteredGraph = useMemo10(() => {
5759
+ const groupedSet = useMemo13(() => new Set(groupedSubflows ?? []), [groupedSubflows]);
5760
+ const filteredGraph = useMemo13(() => {
5056
5761
  const base = filterGraphForDrill(graph, drill.currentSubflowId);
5057
5762
  if (groupedSet.size === 0) return base;
5058
5763
  const baseIds = new Set(base.nodes.map((n) => n.id));
@@ -5067,12 +5772,12 @@ function TracedFlow({
5067
5772
  );
5068
5773
  return { nodes: [...base.nodes, ...extraNodes], edges: [...base.edges, ...extraEdges] };
5069
5774
  }, [graph, drill.currentSubflowId, groupedSet]);
5070
- const breadcrumb = useMemo10(
5775
+ const breadcrumb = useMemo13(
5071
5776
  () => buildSubflowBreadcrumb(graph, drill.currentSubflowId),
5072
5777
  [graph, drill.currentSubflowId]
5073
5778
  );
5074
- const [measuredSizes, setMeasuredSizes] = useState10(null);
5075
- const positioned = useMemo10(() => {
5779
+ const [measuredSizes, setMeasuredSizes] = useState11(null);
5780
+ const positioned = useMemo13(() => {
5076
5781
  const nodeSize = measuredSizes ? (n) => measuredSizes.get(n.id) : void 0;
5077
5782
  const sizeOpts = nodeSize ? { nodeSize } : {};
5078
5783
  const dagreBase = withForkCentering(
@@ -5096,7 +5801,7 @@ function TracedFlow({
5096
5801
  }
5097
5802
  return realBase(filteredGraph);
5098
5803
  }, [filteredGraph, layout, layoutProp, groupedSet, mainChartBox, measuredSizes]);
5099
- const slice = useMemo10(() => {
5804
+ const slice = useMemo13(() => {
5100
5805
  const empty = {
5101
5806
  doneStageIds: /* @__PURE__ */ new Set(),
5102
5807
  activeStageId: null,
@@ -5108,7 +5813,7 @@ function TracedFlow({
5108
5813
  const idx = scrubIndex ?? Math.max(0, overlay.executionOrder.length - 1);
5109
5814
  return aggregateMountStatus(sliceOverlay(overlay, idx), graph, drill.currentSubflowId);
5110
5815
  }, [overlay, scrubIndex, graph, drill.currentSubflowId]);
5111
- const reactFlowNodes = useMemo10(
5816
+ const reactFlowNodes = useMemo13(
5112
5817
  () => positioned.nodes.map(
5113
5818
  (n) => toStageNodeWithOverlay(
5114
5819
  n,
@@ -5121,20 +5826,20 @@ function TracedFlow({
5121
5826
  ),
5122
5827
  [positioned.nodes, slice, coActiveStageIds]
5123
5828
  );
5124
- const reactFlowEdges = useMemo10(
5829
+ const reactFlowEdges = useMemo13(
5125
5830
  () => positioned.edges.map(
5126
5831
  (e) => styleEdgeWithOverlay(e, slice.doneStageIds, slice.activeStageId, colors)
5127
5832
  ),
5128
5833
  [positioned.edges, slice, colors]
5129
5834
  );
5130
- const [coneRevealed, setConeRevealed] = useState10(false);
5835
+ const [coneRevealed, setConeRevealed] = useState11(false);
5131
5836
  useEffect10(() => {
5132
5837
  if (!sliceCone) return;
5133
5838
  setConeRevealed(false);
5134
5839
  const raf = requestAnimationFrame(() => setConeRevealed(true));
5135
5840
  return () => cancelAnimationFrame(raf);
5136
5841
  }, [sliceCone]);
5137
- const conedNodes = useMemo10(() => {
5842
+ const conedNodes = useMemo13(() => {
5138
5843
  if (!sliceCone || sliceCone.size === 0) return reactFlowNodes;
5139
5844
  return reactFlowNodes.map((n) => {
5140
5845
  const depth = sliceCone.get(n.id);
@@ -5152,7 +5857,7 @@ function TracedFlow({
5152
5857
  };
5153
5858
  });
5154
5859
  }, [reactFlowNodes, sliceCone, coneRevealed]);
5155
- const conedEdges = useMemo10(() => {
5860
+ const conedEdges = useMemo13(() => {
5156
5861
  if (!sliceCone || sliceCone.size === 0) return reactFlowEdges;
5157
5862
  return reactFlowEdges.map((e) => {
5158
5863
  const inCone = sliceCone.has(e.source) && sliceCone.has(e.target);
@@ -5170,13 +5875,13 @@ function TracedFlow({
5170
5875
  [drill, onNodeClick, groupedSet]
5171
5876
  );
5172
5877
  const wrapperRef = useRef8(null);
5173
- const [rfInstance, setRfInstance] = useState10(null);
5878
+ const [rfInstance, setRfInstance] = useState11(null);
5174
5879
  useChartAutoRefit(wrapperRef, rfInstance, {
5175
5880
  // Re-fit on drill AND after the measured-size re-layout settles.
5176
5881
  refitKey: `${drill.currentSubflowId ?? ""}:${measuredSizes ? "measured" : "estimated"}`,
5177
5882
  padding: 0.18
5178
5883
  });
5179
- return /* @__PURE__ */ jsxs18(
5884
+ return /* @__PURE__ */ jsxs20(
5180
5885
  "div",
5181
5886
  {
5182
5887
  ref: wrapperRef,
@@ -5190,14 +5895,14 @@ function TracedFlow({
5190
5895
  ...style
5191
5896
  },
5192
5897
  children: [
5193
- breadcrumb.length > 1 && /* @__PURE__ */ jsx21(
5898
+ breadcrumb.length > 1 && /* @__PURE__ */ jsx23(
5194
5899
  SubflowBreadcrumbBar,
5195
5900
  {
5196
5901
  entries: breadcrumb,
5197
5902
  onNavigate: drill.setCurrentSubflowId
5198
5903
  }
5199
5904
  ),
5200
- /* @__PURE__ */ jsx21("div", { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsxs18(
5905
+ /* @__PURE__ */ jsx23("div", { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsxs20(
5201
5906
  ReactFlow,
5202
5907
  {
5203
5908
  nodes: conedNodes,
@@ -5211,8 +5916,8 @@ function TracedFlow({
5211
5916
  minZoom: 0.1,
5212
5917
  proOptions: { hideAttribution: true },
5213
5918
  children: [
5214
- /* @__PURE__ */ jsx21(MeasuredNodeSizes, { onSizes: setMeasuredSizes }),
5215
- /* @__PURE__ */ jsx21(Background, { variant: BackgroundVariant.Dots, gap: 20, size: 1 }),
5919
+ /* @__PURE__ */ jsx23(MeasuredNodeSizes, { onSizes: setMeasuredSizes }),
5920
+ /* @__PURE__ */ jsx23(Background, { variant: BackgroundVariant.Dots, gap: 20, size: 1 }),
5216
5921
  children
5217
5922
  ]
5218
5923
  }
@@ -5223,187 +5928,27 @@ function TracedFlow({
5223
5928
  }
5224
5929
 
5225
5930
  // src/components/InspectorPanel/InspectorPanel.tsx
5226
- import { memo as memo5, useState as useState11 } from "react";
5227
-
5228
- // src/components/DataTracePanel/DataTracePanel.tsx
5229
- import { memo as memo4 } from "react";
5230
- import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
5231
- var DataTracePanel = memo4(function DataTracePanel2({
5232
- frames,
5233
- selectedStageId,
5234
- onFrameClick,
5235
- fromStageName,
5236
- note
5237
- }) {
5238
- const noteLine = note ? /* @__PURE__ */ jsx22("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", marginBottom: 8 }, children: note }) : null;
5239
- if (frames.length === 0) {
5240
- return /* @__PURE__ */ jsxs19("div", { style: { padding: "14px 14px 12px", fontSize: 13, lineHeight: 1.55 }, children: [
5241
- /* @__PURE__ */ jsx22(
5242
- "div",
5243
- {
5244
- style: {
5245
- fontSize: 11,
5246
- color: theme.textMuted,
5247
- textTransform: "uppercase",
5248
- letterSpacing: "0.5px",
5249
- fontWeight: 600,
5250
- marginBottom: 6
5251
- },
5252
- children: "Backward causal chain"
5253
- }
5254
- ),
5255
- /* @__PURE__ */ jsx22("div", { style: { color: theme.textSecondary, marginBottom: 10 }, children: "Trace any value back to the stage that created it \u2014 and everything upstream that influenced it." }),
5256
- noteLine,
5257
- /* @__PURE__ */ jsx22("div", { style: { color: theme.textMuted, fontSize: 12 }, children: "Select a stage above to see its dependency chain." })
5258
- ] });
5259
- }
5260
- return /* @__PURE__ */ jsxs19("div", { style: { padding: "8px 0", fontSize: 13 }, children: [
5261
- note && /* @__PURE__ */ jsx22("div", { style: { padding: "4px 12px 0", fontSize: 11, color: theme.textMuted, fontStyle: "italic" }, children: note }),
5262
- fromStageName && /* @__PURE__ */ jsxs19("div", { style: { padding: "4px 12px 8px" }, children: [
5263
- /* @__PURE__ */ jsxs19(
5264
- "div",
5265
- {
5266
- style: {
5267
- fontSize: 11,
5268
- color: theme.textMuted,
5269
- textTransform: "uppercase",
5270
- letterSpacing: "0.5px",
5271
- fontWeight: 600
5272
- },
5273
- children: [
5274
- "Data trace from ",
5275
- fromStageName
5276
- ]
5277
- }
5278
- ),
5279
- /* @__PURE__ */ jsx22(
5280
- "div",
5281
- {
5282
- style: {
5283
- fontSize: 11,
5284
- color: theme.textMuted,
5285
- fontStyle: "italic",
5286
- marginTop: 3
5287
- },
5288
- children: "Every value here was derived from the stages below."
5289
- }
5290
- )
5291
- ] }),
5292
- frames.map((frame, i) => /* @__PURE__ */ jsx22(
5293
- DataTraceFrame,
5294
- {
5295
- frame,
5296
- isFirst: i === 0,
5297
- isLast: i === frames.length - 1,
5298
- isSelected: frame.runtimeStageId === selectedStageId,
5299
- onClick: onFrameClick
5300
- },
5301
- frame.runtimeStageId
5302
- ))
5303
- ] });
5304
- });
5305
- var DataTraceFrame = memo4(function DataTraceFrame2({
5306
- frame,
5307
- isFirst,
5308
- isLast,
5309
- isSelected,
5310
- onClick
5311
- }) {
5312
- return /* @__PURE__ */ jsxs19(
5313
- "button",
5314
- {
5315
- onClick: () => onClick?.(frame.runtimeStageId),
5316
- style: {
5317
- display: "block",
5318
- width: "100%",
5319
- textAlign: "left",
5320
- border: "none",
5321
- background: isSelected ? "var(--fp-accent-bg, rgba(99,102,241,0.12))" : "transparent",
5322
- padding: "6px 12px 6px 16px",
5323
- cursor: onClick ? "pointer" : "default",
5324
- borderLeft: isSelected ? "3px solid var(--fp-accent, #6366f1)" : "3px solid transparent",
5325
- color: "inherit",
5326
- fontSize: 13
5327
- },
5328
- children: [
5329
- /* @__PURE__ */ jsxs19("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
5330
- !isFirst && /* @__PURE__ */ jsx22("span", { style: { color: theme.textMuted, fontSize: 11 }, children: "\u2191" }),
5331
- /* @__PURE__ */ jsx22(
5332
- "span",
5333
- {
5334
- style: {
5335
- fontWeight: isFirst ? 600 : 400,
5336
- color: isFirst ? "var(--fp-accent, #6366f1)" : theme.textPrimary
5337
- },
5338
- children: frame.stageName
5339
- }
5340
- ),
5341
- isLast && !isFirst && /* @__PURE__ */ jsx22(
5342
- "span",
5343
- {
5344
- style: {
5345
- fontSize: 10,
5346
- color: theme.textMuted,
5347
- fontStyle: "italic"
5348
- },
5349
- children: "(origin)"
5350
- }
5351
- )
5352
- ] }),
5353
- frame.keysWritten.length > 0 && /* @__PURE__ */ jsxs19(
5354
- "div",
5355
- {
5356
- style: {
5357
- fontSize: 11,
5358
- color: theme.textMuted,
5359
- paddingLeft: isFirst ? 0 : 18,
5360
- marginTop: 2
5361
- },
5362
- children: [
5363
- "wrote:",
5364
- " ",
5365
- /* @__PURE__ */ jsx22("span", { style: { color: theme.textSecondary }, children: frame.keysWritten.join(", ") })
5366
- ]
5367
- }
5368
- ),
5369
- frame.linkedBy && /* @__PURE__ */ jsxs19(
5370
- "div",
5371
- {
5372
- style: {
5373
- fontSize: 11,
5374
- color: "var(--fp-accent, #6366f1)",
5375
- paddingLeft: 18,
5376
- marginTop: 1
5377
- },
5378
- children: [
5379
- "\u2190 via ",
5380
- frame.linkedBy
5381
- ]
5382
- }
5383
- )
5384
- ]
5385
- }
5386
- );
5387
- });
5388
-
5389
- // src/components/InspectorPanel/InspectorPanel.tsx
5390
- import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
5391
- var InspectorPanel = memo5(function InspectorPanel2({
5931
+ import { memo as memo6, useState as useState12 } from "react";
5932
+ import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
5933
+ var InspectorPanel = memo6(function InspectorPanel2({
5392
5934
  snapshots,
5393
5935
  selectedIndex,
5394
5936
  dataTraceFrames,
5395
5937
  dataTraceNote,
5396
5938
  selectedStageId,
5397
5939
  onNavigateToStage,
5398
- onTabChange
5940
+ onTabChange,
5941
+ tab: controlledTab,
5942
+ traceContent
5399
5943
  }) {
5400
- const [tab, setTabState] = useState11("state");
5944
+ const [internalTab, setTabState] = useState12("state");
5945
+ const tab = controlledTab ?? internalTab;
5401
5946
  const setTab = (t) => {
5402
5947
  setTabState(t);
5403
5948
  onTabChange?.(t);
5404
5949
  };
5405
5950
  const currentSnapshot = snapshots[selectedIndex];
5406
- return /* @__PURE__ */ jsxs20(
5951
+ return /* @__PURE__ */ jsxs21(
5407
5952
  "div",
5408
5953
  {
5409
5954
  style: {
@@ -5413,7 +5958,7 @@ var InspectorPanel = memo5(function InspectorPanel2({
5413
5958
  overflow: "hidden"
5414
5959
  },
5415
5960
  children: [
5416
- /* @__PURE__ */ jsxs20(
5961
+ /* @__PURE__ */ jsxs21(
5417
5962
  "div",
5418
5963
  {
5419
5964
  style: {
@@ -5422,7 +5967,7 @@ var InspectorPanel = memo5(function InspectorPanel2({
5422
5967
  flexShrink: 0
5423
5968
  },
5424
5969
  children: [
5425
- /* @__PURE__ */ jsx23(
5970
+ /* @__PURE__ */ jsx24(
5426
5971
  TabButton,
5427
5972
  {
5428
5973
  active: tab === "state",
@@ -5430,7 +5975,7 @@ var InspectorPanel = memo5(function InspectorPanel2({
5430
5975
  label: "State"
5431
5976
  }
5432
5977
  ),
5433
- /* @__PURE__ */ jsx23(
5978
+ /* @__PURE__ */ jsx24(
5434
5979
  TabButton,
5435
5980
  {
5436
5981
  active: tab === "trace",
@@ -5442,15 +5987,15 @@ var InspectorPanel = memo5(function InspectorPanel2({
5442
5987
  ]
5443
5988
  }
5444
5989
  ),
5445
- /* @__PURE__ */ jsxs20("div", { style: { flex: 1, overflow: "auto" }, children: [
5446
- tab === "state" && /* @__PURE__ */ jsx23(
5990
+ /* @__PURE__ */ jsxs21("div", { style: { flex: 1, overflow: "auto" }, children: [
5991
+ tab === "state" && /* @__PURE__ */ jsx24(
5447
5992
  MemoryPanel,
5448
5993
  {
5449
5994
  snapshots,
5450
5995
  selectedIndex
5451
5996
  }
5452
5997
  ),
5453
- tab === "trace" && /* @__PURE__ */ jsx23(
5998
+ tab === "trace" && (traceContent ?? /* @__PURE__ */ jsx24(
5454
5999
  DataTracePanel,
5455
6000
  {
5456
6001
  frames: dataTraceFrames,
@@ -5459,7 +6004,7 @@ var InspectorPanel = memo5(function InspectorPanel2({
5459
6004
  onFrameClick: onNavigateToStage,
5460
6005
  fromStageName: currentSnapshot?.stageName
5461
6006
  }
5462
- )
6007
+ ))
5463
6008
  ] })
5464
6009
  ]
5465
6010
  }
@@ -5471,7 +6016,7 @@ function TabButton({
5471
6016
  label,
5472
6017
  badge
5473
6018
  }) {
5474
- return /* @__PURE__ */ jsxs20(
6019
+ return /* @__PURE__ */ jsxs21(
5475
6020
  "button",
5476
6021
  {
5477
6022
  onClick,
@@ -5490,7 +6035,7 @@ function TabButton({
5490
6035
  },
5491
6036
  children: [
5492
6037
  label,
5493
- badge && /* @__PURE__ */ jsx23(
6038
+ badge && /* @__PURE__ */ jsx24(
5494
6039
  "span",
5495
6040
  {
5496
6041
  style: {
@@ -5510,28 +6055,28 @@ function TabButton({
5510
6055
  }
5511
6056
 
5512
6057
  // src/components/InsightPanel/InsightPanel.tsx
5513
- import { memo as memo6, useState as useState12 } from "react";
5514
- import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
5515
- var InsightPanel = memo6(function InsightPanel2({
6058
+ import { memo as memo7, useState as useState13 } from "react";
6059
+ import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
6060
+ var InsightPanel = memo7(function InsightPanel2({
5516
6061
  insights,
5517
6062
  expandedId,
5518
6063
  mode
5519
6064
  }) {
5520
6065
  if (insights.length === 0) {
5521
- return /* @__PURE__ */ jsx24("div", { style: { padding: 12, color: theme.textMuted, fontSize: 13 }, children: "No insights available. Attach recorders to see data." });
6066
+ return /* @__PURE__ */ jsx25("div", { style: { padding: 12, color: theme.textMuted, fontSize: 13 }, children: "No insights available. Attach recorders to see data." });
5522
6067
  }
5523
6068
  if (mode === "grid") {
5524
- return /* @__PURE__ */ jsx24(InsightGrid, { insights });
6069
+ return /* @__PURE__ */ jsx25(InsightGrid, { insights });
5525
6070
  }
5526
- return /* @__PURE__ */ jsx24(InsightTabs, { insights, defaultId: expandedId });
6071
+ return /* @__PURE__ */ jsx25(InsightTabs, { insights, defaultId: expandedId });
5527
6072
  });
5528
- var InsightTabs = memo6(function InsightTabs2({
6073
+ var InsightTabs = memo7(function InsightTabs2({
5529
6074
  insights,
5530
6075
  defaultId
5531
6076
  }) {
5532
- const [activeId, setActiveId] = useState12(defaultId ?? insights[0]?.id);
6077
+ const [activeId, setActiveId] = useState13(defaultId ?? insights[0]?.id);
5533
6078
  const active = insights.find((i) => i.id === activeId) ?? insights[0];
5534
- return /* @__PURE__ */ jsxs21(
6079
+ return /* @__PURE__ */ jsxs22(
5535
6080
  "div",
5536
6081
  {
5537
6082
  style: {
@@ -5541,7 +6086,7 @@ var InsightTabs = memo6(function InsightTabs2({
5541
6086
  overflow: "hidden"
5542
6087
  },
5543
6088
  children: [
5544
- /* @__PURE__ */ jsx24(
6089
+ /* @__PURE__ */ jsx25(
5545
6090
  "div",
5546
6091
  {
5547
6092
  style: {
@@ -5550,7 +6095,7 @@ var InsightTabs = memo6(function InsightTabs2({
5550
6095
  flexShrink: 0,
5551
6096
  overflowX: "auto"
5552
6097
  },
5553
- children: insights.map((insight) => /* @__PURE__ */ jsx24(
6098
+ children: insights.map((insight) => /* @__PURE__ */ jsx25(
5554
6099
  "button",
5555
6100
  {
5556
6101
  onClick: () => setActiveId(insight.id),
@@ -5571,16 +6116,16 @@ var InsightTabs = memo6(function InsightTabs2({
5571
6116
  ))
5572
6117
  }
5573
6118
  ),
5574
- /* @__PURE__ */ jsx24("div", { style: { flex: 1, overflow: "auto" }, children: active?.render() })
6119
+ /* @__PURE__ */ jsx25("div", { style: { flex: 1, overflow: "auto" }, children: active?.render() })
5575
6120
  ]
5576
6121
  }
5577
6122
  );
5578
6123
  });
5579
- var InsightGrid = memo6(function InsightGrid2({
6124
+ var InsightGrid = memo7(function InsightGrid2({
5580
6125
  insights
5581
6126
  }) {
5582
6127
  const cols = insights.length <= 2 ? 1 : 2;
5583
- return /* @__PURE__ */ jsx24(
6128
+ return /* @__PURE__ */ jsx25(
5584
6129
  "div",
5585
6130
  {
5586
6131
  style: {
@@ -5591,7 +6136,7 @@ var InsightGrid = memo6(function InsightGrid2({
5591
6136
  gap: 1,
5592
6137
  background: theme.border
5593
6138
  },
5594
- children: insights.map((insight) => /* @__PURE__ */ jsxs21(
6139
+ children: insights.map((insight) => /* @__PURE__ */ jsxs22(
5595
6140
  "div",
5596
6141
  {
5597
6142
  style: {
@@ -5601,7 +6146,7 @@ var InsightGrid = memo6(function InsightGrid2({
5601
6146
  overflow: "hidden"
5602
6147
  },
5603
6148
  children: [
5604
- /* @__PURE__ */ jsxs21(
6149
+ /* @__PURE__ */ jsxs22(
5605
6150
  "div",
5606
6151
  {
5607
6152
  style: {
@@ -5616,7 +6161,7 @@ var InsightGrid = memo6(function InsightGrid2({
5616
6161
  },
5617
6162
  children: [
5618
6163
  insight.name,
5619
- insight.summary && /* @__PURE__ */ jsx24(
6164
+ insight.summary && /* @__PURE__ */ jsx25(
5620
6165
  "span",
5621
6166
  {
5622
6167
  style: {
@@ -5631,7 +6176,7 @@ var InsightGrid = memo6(function InsightGrid2({
5631
6176
  ]
5632
6177
  }
5633
6178
  ),
5634
- /* @__PURE__ */ jsx24("div", { style: { flex: 1, overflow: "auto" }, children: insight.render() })
6179
+ /* @__PURE__ */ jsx25("div", { style: { flex: 1, overflow: "auto" }, children: insight.render() })
5635
6180
  ]
5636
6181
  },
5637
6182
  insight.id
@@ -5641,17 +6186,17 @@ var InsightGrid = memo6(function InsightGrid2({
5641
6186
  });
5642
6187
 
5643
6188
  // src/components/CompactTimeline/CompactTimeline.tsx
5644
- import { memo as memo7, useState as useState13 } from "react";
5645
- import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
5646
- var CompactTimeline = memo7(function CompactTimeline2({
6189
+ import { memo as memo8, useState as useState14 } from "react";
6190
+ import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
6191
+ var CompactTimeline = memo8(function CompactTimeline2({
5647
6192
  snapshots,
5648
6193
  selectedIndex,
5649
6194
  defaultExpanded = false
5650
6195
  }) {
5651
- const [expanded, setExpanded] = useState13(defaultExpanded);
6196
+ const [expanded, setExpanded] = useState14(defaultExpanded);
5652
6197
  if (snapshots.length === 0) return null;
5653
- return /* @__PURE__ */ jsxs22("div", { style: { borderTop: `1px solid ${theme.border}` }, children: [
5654
- /* @__PURE__ */ jsxs22(
6198
+ return /* @__PURE__ */ jsxs23("div", { style: { borderTop: `1px solid ${theme.border}` }, children: [
6199
+ /* @__PURE__ */ jsxs23(
5655
6200
  "button",
5656
6201
  {
5657
6202
  onClick: () => setExpanded((e) => !e),
@@ -5671,13 +6216,13 @@ var CompactTimeline = memo7(function CompactTimeline2({
5671
6216
  letterSpacing: "0.5px"
5672
6217
  },
5673
6218
  children: [
5674
- /* @__PURE__ */ jsx25("span", { style: { fontSize: 10 }, children: expanded ? "\u25BC" : "\u25B8" }),
6219
+ /* @__PURE__ */ jsx26("span", { style: { fontSize: 10 }, children: expanded ? "\u25BC" : "\u25B8" }),
5675
6220
  "Timeline",
5676
- /* @__PURE__ */ jsxs22("span", { style: { fontWeight: 400, fontSize: 10 }, children: [
6221
+ /* @__PURE__ */ jsxs23("span", { style: { fontWeight: 400, fontSize: 10 }, children: [
5677
6222
  snapshots.length,
5678
6223
  " stages"
5679
6224
  ] }),
5680
- !expanded && /* @__PURE__ */ jsxs22(
6225
+ !expanded && /* @__PURE__ */ jsxs23(
5681
6226
  "div",
5682
6227
  {
5683
6228
  style: {
@@ -5688,7 +6233,7 @@ var CompactTimeline = memo7(function CompactTimeline2({
5688
6233
  marginLeft: 8
5689
6234
  },
5690
6235
  children: [
5691
- snapshots.map((snap, i) => /* @__PURE__ */ jsx25(
6236
+ snapshots.map((snap, i) => /* @__PURE__ */ jsx26(
5692
6237
  "div",
5693
6238
  {
5694
6239
  style: {
@@ -5703,7 +6248,7 @@ var CompactTimeline = memo7(function CompactTimeline2({
5703
6248
  },
5704
6249
  i
5705
6250
  )),
5706
- /* @__PURE__ */ jsx25(
6251
+ /* @__PURE__ */ jsx26(
5707
6252
  "div",
5708
6253
  {
5709
6254
  style: {
@@ -5721,7 +6266,7 @@ var CompactTimeline = memo7(function CompactTimeline2({
5721
6266
  ]
5722
6267
  }
5723
6268
  ),
5724
- expanded && /* @__PURE__ */ jsx25("div", { style: { padding: "0 12px 8px" }, children: /* @__PURE__ */ jsx25(
6269
+ expanded && /* @__PURE__ */ jsx26("div", { style: { padding: "0 12px 8px" }, children: /* @__PURE__ */ jsx26(
5725
6270
  GanttTimeline,
5726
6271
  {
5727
6272
  snapshots,
@@ -5732,21 +6277,21 @@ var CompactTimeline = memo7(function CompactTimeline2({
5732
6277
  });
5733
6278
 
5734
6279
  // src/components/ExplainableShell/ExplainableShell.tsx
5735
- import { Fragment as Fragment6, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
5736
- var HLinePill = memo8(function HLinePill2({
6280
+ import { Fragment as Fragment8, jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
6281
+ var HLinePill = memo9(function HLinePill2({
5737
6282
  label,
5738
6283
  detail,
5739
6284
  expanded,
5740
6285
  onClick
5741
6286
  }) {
5742
- return /* @__PURE__ */ jsxs23("div", { style: {
6287
+ return /* @__PURE__ */ jsxs24("div", { style: {
5743
6288
  display: "flex",
5744
6289
  alignItems: "center",
5745
6290
  gap: 0,
5746
6291
  padding: "0"
5747
6292
  }, children: [
5748
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, height: 1, background: theme.border } }),
5749
- /* @__PURE__ */ jsxs23(
6293
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, height: 1, background: theme.border } }),
6294
+ /* @__PURE__ */ jsxs24(
5750
6295
  "button",
5751
6296
  {
5752
6297
  onClick,
@@ -5770,31 +6315,31 @@ var HLinePill = memo8(function HLinePill2({
5770
6315
  transition: "color 0.15s ease"
5771
6316
  },
5772
6317
  children: [
5773
- /* @__PURE__ */ jsx26("span", { style: { fontSize: 7 }, children: expanded ? "\u25BC" : "\u25B6" }),
6318
+ /* @__PURE__ */ jsx27("span", { style: { fontSize: 7 }, children: expanded ? "\u25BC" : "\u25B6" }),
5774
6319
  label,
5775
- detail && /* @__PURE__ */ jsx26("span", { style: { fontWeight: 400, opacity: 0.5, fontSize: 9 }, children: detail })
6320
+ detail && /* @__PURE__ */ jsx27("span", { style: { fontWeight: 400, opacity: 0.5, fontSize: 9 }, children: detail })
5776
6321
  ]
5777
6322
  }
5778
6323
  ),
5779
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, height: 1, background: theme.border } })
6324
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, height: 1, background: theme.border } })
5780
6325
  ] });
5781
6326
  });
5782
- var VLinePill = memo8(function VLinePill2({
6327
+ var VLinePill = memo9(function VLinePill2({
5783
6328
  label,
5784
6329
  expanded,
5785
6330
  side = "right",
5786
6331
  onClick
5787
6332
  }) {
5788
6333
  const arrow = side === "right" ? expanded ? "\u25B6" : "\u25C0" : expanded ? "\u25C0" : "\u25B6";
5789
- return /* @__PURE__ */ jsxs23("div", { style: {
6334
+ return /* @__PURE__ */ jsxs24("div", { style: {
5790
6335
  display: "flex",
5791
6336
  flexDirection: "column",
5792
6337
  alignItems: "center",
5793
6338
  gap: 0,
5794
6339
  padding: "0"
5795
6340
  }, children: [
5796
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, width: 1, background: theme.border } }),
5797
- /* @__PURE__ */ jsxs23(
6341
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, width: 1, background: theme.border } }),
6342
+ /* @__PURE__ */ jsxs24(
5798
6343
  "button",
5799
6344
  {
5800
6345
  onClick,
@@ -5819,12 +6364,12 @@ var VLinePill = memo8(function VLinePill2({
5819
6364
  transition: "color 0.15s ease"
5820
6365
  },
5821
6366
  children: [
5822
- /* @__PURE__ */ jsx26("span", { style: { fontSize: 7, writingMode: "horizontal-tb" }, children: arrow }),
6367
+ /* @__PURE__ */ jsx27("span", { style: { fontSize: 7, writingMode: "horizontal-tb" }, children: arrow }),
5823
6368
  label
5824
6369
  ]
5825
6370
  }
5826
6371
  ),
5827
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, width: 1, background: theme.border } })
6372
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, width: 1, background: theme.border } })
5828
6373
  ] });
5829
6374
  });
5830
6375
  function detectKeyedSteps(data) {
@@ -5861,9 +6406,9 @@ function KeyedRecorderView({
5861
6406
  snapshots,
5862
6407
  selectedIndex
5863
6408
  }) {
5864
- const [showAggregate, setShowAggregate] = useState14(false);
5865
- const detected = useMemo12(() => detectKeyedSteps(data), [data]);
5866
- const visibleKeys = useMemo12(() => {
6409
+ const [showAggregate, setShowAggregate] = useState15(false);
6410
+ const detected = useMemo14(() => detectKeyedSteps(data), [data]);
6411
+ const visibleKeys = useMemo14(() => {
5867
6412
  const keys = /* @__PURE__ */ new Set();
5868
6413
  for (let i = 0; i <= selectedIndex && i < snapshots.length; i++) {
5869
6414
  const snap = snapshots[i];
@@ -5878,7 +6423,7 @@ function KeyedRecorderView({
5878
6423
  }, [snapshots, selectedIndex, detected?.keyType]);
5879
6424
  const isAtEnd = selectedIndex >= snapshots.length - 1;
5880
6425
  if (!detected) {
5881
- return /* @__PURE__ */ jsx26("div", { style: { padding: 12, fontFamily: theme.fontMono, fontSize: 11, whiteSpace: "pre-wrap", overflow: "auto", height: "100%" }, children: typeof data === "string" ? data : JSON.stringify(data, null, 2) });
6426
+ return /* @__PURE__ */ jsx27("div", { style: { padding: 12, fontFamily: theme.fontMono, fontSize: 11, whiteSpace: "pre-wrap", overflow: "auto", height: "100%" }, children: typeof data === "string" ? data : JSON.stringify(data, null, 2) });
5882
6427
  }
5883
6428
  const steps = detected.steps;
5884
6429
  const hints = extractRenderHints(data);
@@ -5892,13 +6437,13 @@ function KeyedRecorderView({
5892
6437
  }
5893
6438
  }
5894
6439
  const grandTotal = hints?.grandTotal ?? 0;
5895
- return /* @__PURE__ */ jsxs23("div", { style: { overflow: "auto", height: "100%", display: "flex", flexDirection: "column" }, children: [
5896
- description && /* @__PURE__ */ jsx26("div", { style: { padding: "6px 12px", fontSize: 11, color: theme.textMuted, fontStyle: "italic", borderBottom: `1px solid ${theme.border}`, flexShrink: 0 }, children: description }),
5897
- /* @__PURE__ */ jsxs23("div", { style: { padding: 12, flex: 1, overflow: "auto" }, children: [
6440
+ return /* @__PURE__ */ jsxs24("div", { style: { overflow: "auto", height: "100%", display: "flex", flexDirection: "column" }, children: [
6441
+ description && /* @__PURE__ */ jsx27("div", { style: { padding: "6px 12px", fontSize: 11, color: theme.textMuted, fontStyle: "italic", borderBottom: `1px solid ${theme.border}`, flexShrink: 0 }, children: description }),
6442
+ /* @__PURE__ */ jsxs24("div", { style: { padding: 12, flex: 1, overflow: "auto" }, children: [
5898
6443
  preferredOperation === "aggregate" ? (
5899
6444
  /* AGGREGATE: collect silently during scrub, button at end to reveal total */
5900
- /* @__PURE__ */ jsxs23(Fragment6, { children: [
5901
- isAtEnd ? /* @__PURE__ */ jsx26("div", { style: { marginBottom: 16 }, children: !showAggregate ? /* @__PURE__ */ jsx26(
6445
+ /* @__PURE__ */ jsxs24(Fragment8, { children: [
6446
+ isAtEnd ? /* @__PURE__ */ jsx27("div", { style: { marginBottom: 16 }, children: !showAggregate ? /* @__PURE__ */ jsx27(
5902
6447
  "button",
5903
6448
  {
5904
6449
  onClick: () => setShowAggregate(true),
@@ -5916,35 +6461,35 @@ function KeyedRecorderView({
5916
6461
  },
5917
6462
  children: "Aggregate \u2014 Show Grand Total"
5918
6463
  }
5919
- ) : /* @__PURE__ */ jsxs23("div", { style: { padding: "14px 16px", background: `color-mix(in srgb, ${theme.success} 12%, transparent)`, borderRadius: 8, border: `1px solid ${theme.success}44` }, children: [
5920
- /* @__PURE__ */ jsx26("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Aggregate \u2014 grand total" }),
5921
- numFieldKey && /* @__PURE__ */ jsxs23("div", { style: { fontSize: 26, fontWeight: 700, color: theme.success }, children: [
6464
+ ) : /* @__PURE__ */ jsxs24("div", { style: { padding: "14px 16px", background: `color-mix(in srgb, ${theme.success} 12%, transparent)`, borderRadius: 8, border: `1px solid ${theme.success}44` }, children: [
6465
+ /* @__PURE__ */ jsx27("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Aggregate \u2014 grand total" }),
6466
+ numFieldKey && /* @__PURE__ */ jsxs24("div", { style: { fontSize: 26, fontWeight: 700, color: theme.success }, children: [
5922
6467
  grandTotal < 1 ? grandTotal.toFixed(3) : grandTotal.toFixed(1),
5923
- /* @__PURE__ */ jsxs23("span", { style: { fontSize: 11, color: theme.textMuted, fontWeight: 400, marginLeft: 8 }, children: [
6468
+ /* @__PURE__ */ jsxs24("span", { style: { fontSize: 11, color: theme.textMuted, fontWeight: 400, marginLeft: 8 }, children: [
5924
6469
  numFieldKey,
5925
6470
  " \xB7 ",
5926
6471
  allKeys.length,
5927
6472
  " steps"
5928
6473
  ] })
5929
6474
  ] })
5930
- ] }) }) : /* @__PURE__ */ jsxs23("div", { style: { padding: "10px 14px", background: `color-mix(in srgb, ${theme.textMuted} 6%, transparent)`, borderRadius: 6, marginBottom: 16, border: `1px dashed ${theme.border}` }, children: [
5931
- /* @__PURE__ */ jsx26("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 600 }, children: "Collecting data..." }),
5932
- /* @__PURE__ */ jsxs23("div", { style: { fontSize: 11, color: theme.textMuted, marginTop: 4 }, children: [
6475
+ ] }) }) : /* @__PURE__ */ jsxs24("div", { style: { padding: "10px 14px", background: `color-mix(in srgb, ${theme.textMuted} 6%, transparent)`, borderRadius: 6, marginBottom: 16, border: `1px dashed ${theme.border}` }, children: [
6476
+ /* @__PURE__ */ jsx27("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 600 }, children: "Collecting data..." }),
6477
+ /* @__PURE__ */ jsxs24("div", { style: { fontSize: 11, color: theme.textMuted, marginTop: 4 }, children: [
5933
6478
  visibleEntries.length,
5934
6479
  " of ",
5935
6480
  allKeys.length,
5936
6481
  " steps collected. Scrub to end to aggregate."
5937
6482
  ] })
5938
6483
  ] }),
5939
- /* @__PURE__ */ jsx26("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Per-step detail" })
6484
+ /* @__PURE__ */ jsx27("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Per-step detail" })
5940
6485
  ] })
5941
6486
  ) : preferredOperation === "accumulate" ? (
5942
6487
  /* ACCUMULATE: running total grows with slider — IS the total at end, no button */
5943
- /* @__PURE__ */ jsxs23(Fragment6, { children: [
5944
- numFieldKey && visibleEntries.length > 0 && /* @__PURE__ */ jsxs23("div", { style: { padding: "10px 14px", background: `color-mix(in srgb, ${theme.primary} 8%, transparent)`, borderRadius: 6, marginBottom: 16 }, children: [
5945
- /* @__PURE__ */ jsx26("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 4, fontWeight: 600 }, children: "Accumulate \u2014 running total up to this step" }),
5946
- /* @__PURE__ */ jsx26("span", { style: { fontWeight: 700, fontSize: 18, color: theme.primary }, children: runningTotal < 1 ? runningTotal.toFixed(3) : runningTotal.toFixed(1) }),
5947
- /* @__PURE__ */ jsxs23("span", { style: { color: theme.textMuted, marginLeft: 8, fontSize: 10 }, children: [
6488
+ /* @__PURE__ */ jsxs24(Fragment8, { children: [
6489
+ numFieldKey && visibleEntries.length > 0 && /* @__PURE__ */ jsxs24("div", { style: { padding: "10px 14px", background: `color-mix(in srgb, ${theme.primary} 8%, transparent)`, borderRadius: 6, marginBottom: 16 }, children: [
6490
+ /* @__PURE__ */ jsx27("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 4, fontWeight: 600 }, children: "Accumulate \u2014 running total up to this step" }),
6491
+ /* @__PURE__ */ jsx27("span", { style: { fontWeight: 700, fontSize: 18, color: theme.primary }, children: runningTotal < 1 ? runningTotal.toFixed(3) : runningTotal.toFixed(1) }),
6492
+ /* @__PURE__ */ jsxs24("span", { style: { color: theme.textMuted, marginLeft: 8, fontSize: 10 }, children: [
5948
6493
  numFieldKey,
5949
6494
  " \xB7 ",
5950
6495
  visibleEntries.length,
@@ -5953,27 +6498,27 @@ function KeyedRecorderView({
5953
6498
  " steps"
5954
6499
  ] })
5955
6500
  ] }),
5956
- /* @__PURE__ */ jsx26("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Per-step detail" })
6501
+ /* @__PURE__ */ jsx27("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Per-step detail" })
5957
6502
  ] })
5958
6503
  ) : (
5959
6504
  /* TRANSLATE: per-step entries prominent, no totals */
5960
- /* @__PURE__ */ jsx26("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Translate \u2014 per-step detail" })
6505
+ /* @__PURE__ */ jsx27("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Translate \u2014 per-step detail" })
5961
6506
  ),
5962
6507
  visibleEntries.map((key) => {
5963
6508
  const entry = steps[key];
5964
6509
  const label = entry.stageName ?? key;
5965
6510
  const numVal = numFieldKey ? entry[numFieldKey] : void 0;
5966
- return /* @__PURE__ */ jsxs23("div", { style: { display: "flex", alignItems: "center", padding: "4px 0", fontSize: 12, fontFamily: theme.fontMono, borderBottom: `1px solid ${theme.border}22` }, children: [
5967
- /* @__PURE__ */ jsx26("span", { style: { color: theme.textMuted, width: 140, flexShrink: 0, fontSize: 10 }, children: key }),
5968
- /* @__PURE__ */ jsx26("span", { style: { fontWeight: 600, flex: 1 }, children: label }),
5969
- numVal !== void 0 && /* @__PURE__ */ jsx26("span", { style: { color: theme.primary, fontWeight: 700, marginLeft: 8 }, children: numVal < 1 ? numVal.toFixed(3) : numVal.toFixed(1) })
6511
+ return /* @__PURE__ */ jsxs24("div", { style: { display: "flex", alignItems: "center", padding: "4px 0", fontSize: 12, fontFamily: theme.fontMono, borderBottom: `1px solid ${theme.border}22` }, children: [
6512
+ /* @__PURE__ */ jsx27("span", { style: { color: theme.textMuted, width: 140, flexShrink: 0, fontSize: 10 }, children: key }),
6513
+ /* @__PURE__ */ jsx27("span", { style: { fontWeight: 600, flex: 1 }, children: label }),
6514
+ numVal !== void 0 && /* @__PURE__ */ jsx27("span", { style: { color: theme.primary, fontWeight: 700, marginLeft: 8 }, children: numVal < 1 ? numVal.toFixed(3) : numVal.toFixed(1) })
5970
6515
  ] }, key);
5971
6516
  }),
5972
- visibleEntries.length === 0 && /* @__PURE__ */ jsx26("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", padding: "8px 0" }, children: "Scrub the slider to reveal entries..." })
6517
+ visibleEntries.length === 0 && /* @__PURE__ */ jsx27("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", padding: "8px 0" }, children: "Scrub the slider to reveal entries..." })
5973
6518
  ] })
5974
6519
  ] });
5975
6520
  }
5976
- var DetailsContent = memo8(function DetailsContent2({
6521
+ var DetailsContent = memo9(function DetailsContent2({
5977
6522
  snapshots,
5978
6523
  selectedIndex,
5979
6524
  narrativeEntries,
@@ -5985,16 +6530,16 @@ var DetailsContent = memo8(function DetailsContent2({
5985
6530
  {
5986
6531
  id: "memory",
5987
6532
  name: "Memory",
5988
- render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ jsx26(MemoryPanel, { snapshots: snaps, selectedIndex: idx, size, style: fillHeight ? { height: "100%" } : void 0 })
6533
+ render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ jsx27(MemoryPanel, { snapshots: snaps, selectedIndex: idx, size, style: fillHeight ? { height: "100%" } : void 0 })
5989
6534
  },
5990
6535
  {
5991
6536
  id: "narrative",
5992
6537
  name: "Narrative",
5993
- render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ jsx26(NarrativePanel, { snapshots: snaps, selectedIndex: idx, narrativeEntries, size, style: fillHeight ? { height: "100%" } : void 0 })
6538
+ render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ jsx27(NarrativePanel, { snapshots: snaps, selectedIndex: idx, narrativeEntries, size, style: fillHeight ? { height: "100%" } : void 0 })
5994
6539
  }
5995
6540
  ];
5996
6541
  const allViews = [...builtInViews, ...extraViews ?? []];
5997
- const [activeViewId, setActiveViewId] = useState14(allViews[0]?.id ?? "memory");
6542
+ const [activeViewId, setActiveViewId] = useState15(allViews[0]?.id ?? "memory");
5998
6543
  const viewIds = allViews.map((v2) => v2.id).join(",");
5999
6544
  useEffect11(() => {
6000
6545
  if (!allViews.find((v2) => v2.id === activeViewId)) {
@@ -6002,10 +6547,10 @@ var DetailsContent = memo8(function DetailsContent2({
6002
6547
  }
6003
6548
  }, [viewIds]);
6004
6549
  const activeView = allViews.find((v2) => v2.id === activeViewId) ?? allViews[0];
6005
- return /* @__PURE__ */ jsxs23("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: [
6006
- /* @__PURE__ */ jsx26("div", { style: { display: "flex", borderBottom: `1px solid ${theme.border}`, flexShrink: 0, overflowX: "auto" }, children: allViews.map((view) => {
6550
+ return /* @__PURE__ */ jsxs24("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: [
6551
+ /* @__PURE__ */ jsx27("div", { style: { display: "flex", borderBottom: `1px solid ${theme.border}`, flexShrink: 0, overflowX: "auto" }, children: allViews.map((view) => {
6007
6552
  const active = view.id === activeViewId;
6008
- return /* @__PURE__ */ jsx26(
6553
+ return /* @__PURE__ */ jsx27(
6009
6554
  "button",
6010
6555
  {
6011
6556
  onClick: () => setActiveViewId(view.id),
@@ -6029,7 +6574,7 @@ var DetailsContent = memo8(function DetailsContent2({
6029
6574
  view.id
6030
6575
  );
6031
6576
  }) }),
6032
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflow: "auto" }, children: activeView?.render({ snapshots, selectedIndex }) })
6577
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, overflow: "auto" }, children: activeView?.render({ snapshots, selectedIndex }) })
6033
6578
  ] });
6034
6579
  });
6035
6580
  function resolveSubflowFromRuntime(parentSnapshots, subflowId, narrativeEntries) {
@@ -6046,7 +6591,7 @@ function resolveSubflowFromRuntime(parentSnapshots, subflowId, narrativeEntries)
6046
6591
  if (sfSnapshots.length === 0) return null;
6047
6592
  return { subflowId, label, spec: null, snapshots: sfSnapshots, narrative: sfNarrative };
6048
6593
  }
6049
- var RightPanel = memo8(function RightPanel2({
6594
+ var RightPanel = memo9(function RightPanel2({
6050
6595
  mode,
6051
6596
  onModeChange,
6052
6597
  snapshots,
@@ -6060,15 +6605,17 @@ var RightPanel = memo8(function RightPanel2({
6060
6605
  size,
6061
6606
  onNavigateToStage,
6062
6607
  dataTrace,
6063
- onInspectorTabChange
6608
+ onInspectorTabChange,
6609
+ inspectorTab,
6610
+ traceContent
6064
6611
  }) {
6065
- return /* @__PURE__ */ jsxs23(Fragment6, { children: [
6066
- /* @__PURE__ */ jsx26("div", { style: {
6612
+ return /* @__PURE__ */ jsxs24(Fragment8, { children: [
6613
+ /* @__PURE__ */ jsx27("div", { style: {
6067
6614
  display: "flex",
6068
6615
  borderBottom: `1px solid ${theme.border}`,
6069
6616
  flexShrink: 0,
6070
6617
  background: theme.bgSecondary
6071
- }, children: ["insights", "what"].map((m) => /* @__PURE__ */ jsx26(
6618
+ }, children: ["insights", "what"].map((m) => /* @__PURE__ */ jsx27(
6072
6619
  "button",
6073
6620
  {
6074
6621
  onClick: () => onModeChange(m),
@@ -6090,7 +6637,7 @@ var RightPanel = memo8(function RightPanel2({
6090
6637
  },
6091
6638
  m
6092
6639
  )) }),
6093
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflow: "hidden" }, children: mode === "insights" ? /* @__PURE__ */ jsx26(
6640
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, overflow: "hidden" }, children: mode === "insights" ? /* @__PURE__ */ jsx27(
6094
6641
  InsightPanel,
6095
6642
  {
6096
6643
  mode: "tabs",
@@ -6099,16 +6646,16 @@ var RightPanel = memo8(function RightPanel2({
6099
6646
  id: tab.id,
6100
6647
  name: insightName(tab.name),
6101
6648
  render: () => {
6102
- if (tab.id === "narrative") return /* @__PURE__ */ jsx26(NarrativePanel, { snapshots, selectedIndex, narrativeEntries: activeNarrativeEntries, runtimeSnapshot, size, style: { height: "100%" } });
6649
+ if (tab.id === "narrative") return /* @__PURE__ */ jsx27(NarrativePanel, { snapshots, selectedIndex, narrativeEntries: activeNarrativeEntries, runtimeSnapshot, size, style: { height: "100%" } });
6103
6650
  const customView = recorderViews?.find((v2) => v2.id === tab.id);
6104
6651
  if (customView?.render) return customView.render({ snapshots, selectedIndex });
6105
6652
  const autoView = autoRecorderViews.find((v2) => v2.id === tab.id);
6106
- if (autoView) return /* @__PURE__ */ jsx26(KeyedRecorderView, { data: autoView.data, description: autoView.description, preferredOperation: autoView.preferredOperation, snapshots, selectedIndex });
6653
+ if (autoView) return /* @__PURE__ */ jsx27(KeyedRecorderView, { data: autoView.data, description: autoView.description, preferredOperation: autoView.preferredOperation, snapshots, selectedIndex });
6107
6654
  return null;
6108
6655
  }
6109
6656
  }))
6110
6657
  }
6111
- ) : /* @__PURE__ */ jsx26(
6658
+ ) : /* @__PURE__ */ jsx27(
6112
6659
  InspectorPanel,
6113
6660
  {
6114
6661
  snapshots,
@@ -6116,6 +6663,8 @@ var RightPanel = memo8(function RightPanel2({
6116
6663
  dataTraceFrames: dataTrace.frames,
6117
6664
  dataTraceNote: dataTrace.readsAvailable ? void 0 : "\u26A0 reads were not recorded (readTracking off) \u2014 dependencies are unknowable, not absent.",
6118
6665
  onTabChange: onInspectorTabChange,
6666
+ tab: inspectorTab,
6667
+ traceContent,
6119
6668
  selectedStageId: snapshots[selectedIndex]?.runtimeStageId,
6120
6669
  onNavigateToStage
6121
6670
  }
@@ -6156,7 +6705,7 @@ function ExplainableShell({
6156
6705
  className,
6157
6706
  style
6158
6707
  }) {
6159
- const derivedFromRuntime = useMemo12(() => {
6708
+ const derivedFromRuntime = useMemo14(() => {
6160
6709
  if (!runtimeSnapshot) return null;
6161
6710
  try {
6162
6711
  const snaps = toVisualizationSnapshots(runtimeSnapshot, narrativeEntries);
@@ -6167,7 +6716,7 @@ function ExplainableShell({
6167
6716
  }, [runtimeSnapshot, narrativeEntries]);
6168
6717
  const snapshots = snapshotsProp ?? derivedFromRuntime?.snapshots ?? [];
6169
6718
  const resultData = resultDataProp ?? derivedFromRuntime?.resultData ?? null;
6170
- const tracedFlowRenderer = useMemo12(() => {
6719
+ const tracedFlowRenderer = useMemo14(() => {
6171
6720
  if (!traceGraph) return void 0;
6172
6721
  return ({ selectedIndex, snapshots: snapshots2, onNodeClick, sliceCone: sliceCone2 }) => {
6173
6722
  const activeRsid = snapshots2[selectedIndex]?.runtimeStageId;
@@ -6188,7 +6737,7 @@ function ExplainableShell({
6188
6737
  ...traceTheme.current !== void 0 && { active: traceTheme.current },
6189
6738
  ...traceTheme.mode !== void 0 && { default: traceTheme.mode === "dark" ? "#94a3b8" : "#64748b" }
6190
6739
  };
6191
- return /* @__PURE__ */ jsx26(
6740
+ return /* @__PURE__ */ jsx27(
6192
6741
  TracedFlow,
6193
6742
  {
6194
6743
  graph: traceGraph,
@@ -6209,8 +6758,8 @@ function ExplainableShell({
6209
6758
  const rightLabel = panelLabels?.details ?? "Details";
6210
6759
  const bottomLabel = panelLabels?.timeline ?? "Timeline";
6211
6760
  const shellRef = useRef9(null);
6212
- const [isNarrow, setIsNarrow] = useState14(false);
6213
- const [isMedium, setIsMedium] = useState14(false);
6761
+ const [isNarrow, setIsNarrow] = useState15(false);
6762
+ const [isMedium, setIsMedium] = useState15(false);
6214
6763
  useEffect11(() => {
6215
6764
  const el = shellRef.current;
6216
6765
  if (!el) return;
@@ -6223,14 +6772,14 @@ function ExplainableShell({
6223
6772
  ro.observe(el);
6224
6773
  return () => ro.disconnect();
6225
6774
  }, []);
6226
- const autoRecorderViews = useMemo12(() => {
6775
+ const autoRecorderViews = useMemo14(() => {
6227
6776
  const recorders = runtimeSnapshot?.recorders;
6228
6777
  if (!recorders?.length) return [];
6229
6778
  const explicitIds = new Set((recorderViews ?? []).map((v2) => v2.id));
6230
6779
  return recorders.filter((r) => !explicitIds.has(r.id)).map((r) => ({ id: r.id, name: r.name, description: r.description, preferredOperation: r.preferredOperation, data: r.data }));
6231
6780
  }, [runtimeSnapshot, recorderViews]);
6232
6781
  const hasNarrative = !!narrativeEntries?.length;
6233
- const allTabs = useMemo12(() => {
6782
+ const allTabs = useMemo14(() => {
6234
6783
  const tabs2 = [
6235
6784
  { id: "result", name: "Result", description: "Final output and console logs" },
6236
6785
  { id: "memory", name: "Memory", description: "Accumulator \u2014 progressive shared state at each stage" }
@@ -6249,14 +6798,15 @@ function ExplainableShell({
6249
6798
  }, [hasNarrative, recorderViews, autoRecorderViews, hideTabsProp]);
6250
6799
  const validTabIds = new Set(allTabs.map((t) => t.id));
6251
6800
  const resolvedDefault = defaultTab && validTabIds.has(defaultTab) ? defaultTab : allTabs[0]?.id ?? "result";
6252
- const [activeTab, setActiveTab] = useState14(resolvedDefault);
6253
- const [snapshotIdx, setSnapshotIdx] = useState14(0);
6254
- const [drillDownStack, setDrillDownStack] = useState14([]);
6255
- const [rightExpanded, setRightExpanded] = useState14(defaultExpanded?.details ?? true);
6256
- const [rightPanelMode, setRightPanelMode] = useState14("insights");
6257
- const [inspectorTab, setInspectorTab] = useState14("state");
6258
- const [leftExpanded, setLeftExpanded] = useState14(defaultExpanded?.topology ?? false);
6259
- const [timelineExpanded, setTimelineExpanded] = useState14(defaultExpanded?.timeline ?? false);
6801
+ const [activeTab, setActiveTab] = useState15(resolvedDefault);
6802
+ const [snapshotIdx, setSnapshotIdx] = useState15(0);
6803
+ const [drillDownStack, setDrillDownStack] = useState15([]);
6804
+ const [rightExpanded, setRightExpanded] = useState15(defaultExpanded?.details ?? true);
6805
+ const [rightPanelMode, setRightPanelMode] = useState15("insights");
6806
+ const [inspectorTab, setInspectorTab] = useState15("state");
6807
+ const [tracing, setTracing] = useState15(null);
6808
+ const [leftExpanded, setLeftExpanded] = useState15(defaultExpanded?.topology ?? false);
6809
+ const [timelineExpanded, setTimelineExpanded] = useState15(defaultExpanded?.timeline ?? false);
6260
6810
  useEffect11(() => {
6261
6811
  if (isNarrow) {
6262
6812
  setLeftExpanded(false);
@@ -6281,7 +6831,7 @@ function ExplainableShell({
6281
6831
  triggerReflow();
6282
6832
  }, [triggerReflow]);
6283
6833
  const isInSubflow = drillDownStack.length > 0;
6284
- const currentLevel = useMemo12(() => {
6834
+ const currentLevel = useMemo14(() => {
6285
6835
  if (drillDownStack.length > 0) {
6286
6836
  const top = drillDownStack[drillDownStack.length - 1];
6287
6837
  return { spec: top.spec, snapshots: top.snapshots, narrative: top.narrative };
@@ -6290,11 +6840,32 @@ function ExplainableShell({
6290
6840
  }, [drillDownStack, snapshots]);
6291
6841
  const activeSnapshots = currentLevel.snapshots;
6292
6842
  const safeIdx = activeSnapshots.length > 0 ? Math.max(0, Math.min(snapshotIdx, activeSnapshots.length - 1)) : 0;
6293
- const shellDataTrace = useMemo12(
6843
+ const shellDataTrace = useMemo14(
6294
6844
  () => runtimeSnapshot?.commitLog ? buildDataTrace(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, activeSnapshots[safeIdx]?.runtimeStageId ?? "") : { frames: [], readsAvailable: true },
6295
6845
  [runtimeSnapshot, activeSnapshots, safeIdx]
6296
6846
  );
6297
- const sliceCone = useMemo12(() => {
6847
+ const traceWalk = useMemo14(() => {
6848
+ if (!tracing || !runtimeSnapshot?.commitLog) return null;
6849
+ const scope = tracing.via.length > 0 ? tracing.via[tracing.via.length - 1] : tracing;
6850
+ return buildTraceWalk(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, scope.key, {
6851
+ beforeCommitIdx: scope.beforeCommitIdx
6852
+ });
6853
+ }, [tracing, runtimeSnapshot]);
6854
+ const traceStopIndices = useMemo14(() => {
6855
+ if (!traceWalk || traceWalk.missing || isInSubflow) return [];
6856
+ const idxByRsid = new Map(activeSnapshots.map((sn, i) => [sn.runtimeStageId, i]));
6857
+ return traceWalk.stops.map((stop) => idxByRsid.get(stop.runtimeStageId)).filter((i) => i !== void 0).sort((a, b) => a - b);
6858
+ }, [traceWalk, activeSnapshots, isInSubflow]);
6859
+ const sliceCone = useMemo14(() => {
6860
+ if (traceWalk && !traceWalk.missing && traceWalk.stops.length >= 2) {
6861
+ const cone2 = /* @__PURE__ */ new Map();
6862
+ for (const stop of traceWalk.stops) {
6863
+ const stagePart = stop.runtimeStageId.split("#")[0];
6864
+ const prev = cone2.get(stagePart);
6865
+ if (prev === void 0 || stop.depth < prev) cone2.set(stagePart, stop.depth);
6866
+ }
6867
+ return cone2;
6868
+ }
6298
6869
  if (rightPanelMode !== "what" || inspectorTab !== "trace") return void 0;
6299
6870
  if (shellDataTrace.frames.length < 2) return void 0;
6300
6871
  const cone = /* @__PURE__ */ new Map();
@@ -6304,19 +6875,19 @@ function ExplainableShell({
6304
6875
  if (prev === void 0 || f.depth < prev) cone.set(stagePart, f.depth);
6305
6876
  }
6306
6877
  return cone;
6307
- }, [rightPanelMode, inspectorTab, shellDataTrace]);
6878
+ }, [traceWalk, rightPanelMode, inspectorTab, shellDataTrace]);
6308
6879
  const activeNarrativeEntries = isInSubflow ? currentLevel.narrative : narrativeEntries;
6309
- const breadcrumbs = useMemo12(() => {
6880
+ const breadcrumbs = useMemo14(() => {
6310
6881
  const root = { label: title || "Flowchart", spec: null, description: void 0 };
6311
6882
  return [root, ...drillDownStack.map((e) => ({ label: e.label, spec: e.spec, description: void 0 }))];
6312
6883
  }, [title, drillDownStack]);
6313
- const showTreeSidebar = useMemo12(() => {
6884
+ const showTreeSidebar = useMemo14(() => {
6314
6885
  if (traceGraph?.nodes?.length) {
6315
6886
  return traceGraph.nodes.some((n) => n.data?.isSubflow === true);
6316
6887
  }
6317
6888
  return false;
6318
6889
  }, [traceGraph]);
6319
- const rootOverlay = useMemo12(() => {
6890
+ const rootOverlay = useMemo14(() => {
6320
6891
  if (isInSubflow || !snapshots.length) return { activeStage: void 0, doneStages: void 0 };
6321
6892
  const doneStages = new Set(snapshots.slice(0, safeIdx).map((s) => s.stageLabel));
6322
6893
  const activeStage = snapshots[safeIdx]?.stageLabel ?? null;
@@ -6329,10 +6900,59 @@ function ExplainableShell({
6329
6900
  const handleSnapshotChange = useCallback8((idx) => {
6330
6901
  if (typeof idx === "number") setSnapshotIdx(idx);
6331
6902
  }, []);
6903
+ const jumpToAnchor = useCallback8(
6904
+ (walk) => {
6905
+ const anchor = walk.stops[0];
6906
+ if (!anchor) return;
6907
+ const idx = activeSnapshots.findIndex((sn) => sn.runtimeStageId === anchor.runtimeStageId);
6908
+ if (idx >= 0) setSnapshotIdx(idx);
6909
+ },
6910
+ [activeSnapshots]
6911
+ );
6912
+ const handleStartTracing = useCallback8(
6913
+ (key) => {
6914
+ if (!runtimeSnapshot?.commitLog || isInSubflow) return;
6915
+ const log = runtimeSnapshot.commitLog;
6916
+ const cursorRsid = activeSnapshots[safeIdx]?.runtimeStageId;
6917
+ const cursorCommitIdx = log.findIndex((c) => c.runtimeStageId === cursorRsid);
6918
+ const beforeCommitIdx = cursorCommitIdx >= 0 ? cursorCommitIdx + 1 : void 0;
6919
+ setTracing({ key, beforeCommitIdx, via: [] });
6920
+ setRightPanelMode("what");
6921
+ setInspectorTab("trace");
6922
+ jumpToAnchor(
6923
+ buildTraceWalk(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, key, { beforeCommitIdx })
6924
+ );
6925
+ },
6926
+ [runtimeSnapshot, isInSubflow, activeSnapshots, safeIdx, jumpToAnchor]
6927
+ );
6928
+ const handleFollowIngredient = useCallback8(
6929
+ (ing) => {
6930
+ if (!tracing || !runtimeSnapshot?.commitLog || ing.writerCommitIdx === null) return;
6931
+ const scope = { key: ing.key, beforeCommitIdx: ing.writerCommitIdx + 1 };
6932
+ setTracing({ ...tracing, via: [...tracing.via, scope] });
6933
+ jumpToAnchor(
6934
+ buildTraceWalk(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, scope.key, {
6935
+ beforeCommitIdx: scope.beforeCommitIdx
6936
+ })
6937
+ );
6938
+ },
6939
+ [tracing, runtimeSnapshot, jumpToAnchor]
6940
+ );
6941
+ const handleShowAllIngredients = useCallback8(() => {
6942
+ if (!tracing || !runtimeSnapshot?.commitLog) return;
6943
+ setTracing({ ...tracing, via: [] });
6944
+ jumpToAnchor(
6945
+ buildTraceWalk(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, tracing.key, {
6946
+ beforeCommitIdx: tracing.beforeCommitIdx
6947
+ })
6948
+ );
6949
+ }, [tracing, runtimeSnapshot, jumpToAnchor]);
6950
+ const handleExitTracing = useCallback8(() => setTracing(null), []);
6332
6951
  const handleDrillDown = useCallback8(
6333
6952
  (nodeName) => {
6334
6953
  const entry = resolveSubflowFromRuntime(activeSnapshots, nodeName, narrativeEntries);
6335
6954
  if (entry) {
6955
+ setTracing(null);
6336
6956
  setDrillDownStack((prev) => [...prev, { ...entry, parentSnapshotIdx: snapshotIdx }]);
6337
6957
  setSnapshotIdx(0);
6338
6958
  }
@@ -6379,33 +6999,112 @@ function ExplainableShell({
6379
6999
  },
6380
7000
  [snapshots, narrativeEntries, snapshotIdx]
6381
7001
  );
7002
+ const navigateToStage = useCallback8(
7003
+ (id) => {
7004
+ const idx = activeSnapshots.findIndex((sn) => sn.runtimeStageId === id);
7005
+ if (idx >= 0) setSnapshotIdx(idx);
7006
+ },
7007
+ [activeSnapshots]
7008
+ );
7009
+ const activeViaKey = tracing && tracing.via.length > 0 ? tracing.via[tracing.via.length - 1].key : null;
7010
+ const stepNumberOf = useCallback8(
7011
+ (rsid) => {
7012
+ const i = activeSnapshots.findIndex((sn) => sn.runtimeStageId === rsid);
7013
+ return i >= 0 ? i + 1 : null;
7014
+ },
7015
+ [activeSnapshots]
7016
+ );
7017
+ const tracingRail = useMemo14(() => {
7018
+ if (!tracing || !traceWalk || traceWalk.missing || traceStopIndices.length === 0) return null;
7019
+ const cursorRsid = activeSnapshots[safeIdx]?.runtimeStageId;
7020
+ const walkIdx = traceWalk.stops.findIndex((st) => st.runtimeStageId === cursorRsid);
7021
+ return {
7022
+ tracedKey: tracing.key,
7023
+ viaKey: activeViaKey,
7024
+ stopIndices: traceStopIndices,
7025
+ stopOrdinal: walkIdx >= 0 ? walkIdx + 1 : 1,
7026
+ totalStops: traceWalk.stops.length,
7027
+ onExit: handleExitTracing,
7028
+ onShowAll: activeViaKey ? handleShowAllIngredients : void 0
7029
+ };
7030
+ }, [tracing, traceWalk, traceStopIndices, activeSnapshots, safeIdx, activeViaKey, handleExitTracing, handleShowAllIngredients]);
7031
+ const traceTabContent = useMemo14(() => tracing && traceWalk ? /* @__PURE__ */ jsx27(
7032
+ TraceWalkCard,
7033
+ {
7034
+ walk: traceWalk,
7035
+ cursorRuntimeStageId: activeSnapshots[safeIdx]?.runtimeStageId ?? null,
7036
+ viaKey: activeViaKey,
7037
+ stepNumberOf,
7038
+ previewValueOf: (k) => activeSnapshots[safeIdx]?.memory?.[k],
7039
+ onFollowIngredient: handleFollowIngredient,
7040
+ onJumpToStop: navigateToStage,
7041
+ onShowAll: activeViaKey ? handleShowAllIngredients : void 0,
7042
+ onExit: handleExitTracing
7043
+ }
7044
+ ) : /* @__PURE__ */ jsxs24(Fragment8, { children: [
7045
+ !isInSubflow && (shellDataTrace.frames[0]?.keysWritten?.length ?? 0) > 0 && /* @__PURE__ */ jsxs24("div", { "data-fp": "trace-entry", style: { padding: "10px 14px 0", fontSize: 12 }, children: [
7046
+ /* @__PURE__ */ jsx27("span", { style: { color: theme.textMuted, marginRight: 6 }, children: "Trace a value:" }),
7047
+ shellDataTrace.frames[0].keysWritten.map((k) => /* @__PURE__ */ jsx27(
7048
+ "button",
7049
+ {
7050
+ "data-fp": "trace-entry-chip",
7051
+ onClick: () => handleStartTracing(k),
7052
+ title: "Where did " + k + " come from? Walk its causes on the timeline.",
7053
+ style: {
7054
+ border: "1px solid var(--fp-accent, #6366f1)",
7055
+ background: "transparent",
7056
+ color: "var(--fp-accent, #6366f1)",
7057
+ borderRadius: 12,
7058
+ padding: "2px 10px",
7059
+ margin: "0 6px 6px 0",
7060
+ fontSize: 11,
7061
+ fontWeight: 600,
7062
+ fontFamily: "monospace",
7063
+ cursor: "pointer"
7064
+ },
7065
+ children: k
7066
+ },
7067
+ k
7068
+ ))
7069
+ ] }),
7070
+ /* @__PURE__ */ jsx27(
7071
+ DataTracePanel,
7072
+ {
7073
+ frames: shellDataTrace.frames,
7074
+ note: shellDataTrace.readsAvailable ? void 0 : "\u26A0 reads were not recorded (readTracking off) \u2014 dependencies are unknowable, not absent.",
7075
+ selectedStageId: activeSnapshots[safeIdx]?.runtimeStageId,
7076
+ onFrameClick: navigateToStage,
7077
+ fromStageName: activeSnapshots[safeIdx]?.stageName
7078
+ }
7079
+ )
7080
+ ] }), [tracing, traceWalk, activeSnapshots, safeIdx, activeViaKey, stepNumberOf, handleFollowIngredient, navigateToStage, handleShowAllIngredients, handleExitTracing, handleStartTracing, isInSubflow, shellDataTrace]);
6382
7081
  const tabLabels = new Map(allTabs.map((t) => [t.id, t.name]));
6383
7082
  if (unstyled) {
6384
- return /* @__PURE__ */ jsxs23("div", { className, style, "data-fp": "explainable-shell", children: [
6385
- /* @__PURE__ */ jsx26("div", { "data-fp": "shell-tabs", children: allTabs.map((tab) => /* @__PURE__ */ jsx26("button", { "data-fp": "shell-tab", "data-active": tab.id === activeTab, onClick: () => handleTabChange(tab.id), children: tab.name }, tab.id)) }),
6386
- /* @__PURE__ */ jsxs23("div", { "data-fp": "shell-content", "data-tab": activeTab, children: [
6387
- activeTab === "result" && /* @__PURE__ */ jsx26(ResultPanel, { data: resultData ?? null, logs, hideConsole, unstyled: true }),
6388
- (activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ jsxs23(Fragment6, { children: [
6389
- /* @__PURE__ */ jsx26(TimeTravelControls, { snapshots: activeSnapshots, selectedIndex: safeIdx, onIndexChange: handleSnapshotChange, unstyled: true }),
6390
- isInSubflow && /* @__PURE__ */ jsx26(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
7083
+ return /* @__PURE__ */ jsxs24("div", { className, style, "data-fp": "explainable-shell", children: [
7084
+ /* @__PURE__ */ jsx27("div", { "data-fp": "shell-tabs", children: allTabs.map((tab) => /* @__PURE__ */ jsx27("button", { "data-fp": "shell-tab", "data-active": tab.id === activeTab, onClick: () => handleTabChange(tab.id), children: tab.name }, tab.id)) }),
7085
+ /* @__PURE__ */ jsxs24("div", { "data-fp": "shell-content", "data-tab": activeTab, children: [
7086
+ activeTab === "result" && /* @__PURE__ */ jsx27(ResultPanel, { data: resultData ?? null, logs, hideConsole, unstyled: true }),
7087
+ (activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ jsxs24(Fragment8, { children: [
7088
+ /* @__PURE__ */ jsx27(TimeTravelControls, { snapshots: activeSnapshots, selectedIndex: safeIdx, onIndexChange: handleSnapshotChange, unstyled: true, tracing: tracingRail }),
7089
+ isInSubflow && /* @__PURE__ */ jsx27(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
6391
7090
  traceGraph && effectiveRenderFlowchart?.({ spec: null, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick, showStageId, ...sliceCone && { sliceCone } }),
6392
- /* @__PURE__ */ jsx26(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, unstyled: true }),
6393
- /* @__PURE__ */ jsx26(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, unstyled: true }),
6394
- /* @__PURE__ */ jsx26(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, unstyled: true })
7091
+ /* @__PURE__ */ jsx27(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, unstyled: true }),
7092
+ /* @__PURE__ */ jsx27(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, unstyled: true }),
7093
+ /* @__PURE__ */ jsx27(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, unstyled: true })
6395
7094
  ] })
6396
7095
  ] })
6397
7096
  ] });
6398
7097
  }
6399
7098
  const showTopology = !!effectiveRenderFlowchart && !!traceGraph;
6400
- const detailsContent = useMemo12(() => {
7099
+ const detailsContent = useMemo14(() => {
6401
7100
  if (activeTab === "result") {
6402
- return /* @__PURE__ */ jsx26(ResultPanel, { data: resultData ?? null, logs, hideConsole, size });
7101
+ return /* @__PURE__ */ jsx27(ResultPanel, { data: resultData ?? null, logs, hideConsole, size });
6403
7102
  }
6404
7103
  if (activeTab === "memory") {
6405
- return /* @__PURE__ */ jsx26(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, size, style: { height: "100%" } });
7104
+ return /* @__PURE__ */ jsx27(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, size, style: { height: "100%" } });
6406
7105
  }
6407
7106
  if (activeTab === "narrative") {
6408
- return /* @__PURE__ */ jsx26(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, size, style: { height: "100%" } });
7107
+ return /* @__PURE__ */ jsx27(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, size, style: { height: "100%" } });
6409
7108
  }
6410
7109
  const customView = recorderViews?.find((v2) => v2.id === activeTab);
6411
7110
  if (customView?.render) {
@@ -6413,7 +7112,7 @@ function ExplainableShell({
6413
7112
  }
6414
7113
  const autoView = autoRecorderViews.find((v2) => v2.id === activeTab);
6415
7114
  if (autoView) {
6416
- return /* @__PURE__ */ jsx26(
7115
+ return /* @__PURE__ */ jsx27(
6417
7116
  KeyedRecorderView,
6418
7117
  {
6419
7118
  data: autoView.data,
@@ -6426,8 +7125,8 @@ function ExplainableShell({
6426
7125
  }
6427
7126
  return null;
6428
7127
  }, [activeTab, resultData, logs, hideConsole, size, activeSnapshots, safeIdx, activeNarrativeEntries, recorderViews, autoRecorderViews]);
6429
- const detailsPanel = /* @__PURE__ */ jsxs23("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflow: "hidden" }, children: [
6430
- /* @__PURE__ */ jsx26("div", { style: {
7128
+ const detailsPanel = /* @__PURE__ */ jsxs24("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflow: "hidden" }, children: [
7129
+ /* @__PURE__ */ jsx27("div", { style: {
6431
7130
  display: "flex",
6432
7131
  borderBottom: `1px solid ${theme.border}`,
6433
7132
  background: theme.bgSecondary,
@@ -6435,7 +7134,7 @@ function ExplainableShell({
6435
7134
  overflowX: "auto"
6436
7135
  }, children: allTabs.map((tab) => {
6437
7136
  const active = tab.id === activeTab;
6438
- return /* @__PURE__ */ jsx26(
7137
+ return /* @__PURE__ */ jsx27(
6439
7138
  "button",
6440
7139
  {
6441
7140
  onClick: () => handleTabChange(tab.id),
@@ -6459,9 +7158,9 @@ function ExplainableShell({
6459
7158
  tab.id
6460
7159
  );
6461
7160
  }) }),
6462
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflow: "auto" }, children: detailsContent })
7161
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, overflow: "auto" }, children: detailsContent })
6463
7162
  ] });
6464
- const shellThemeVars = useMemo12(() => {
7163
+ const shellThemeVars = useMemo14(() => {
6465
7164
  if (!traceTheme) return {};
6466
7165
  const base = traceTheme.mode ? tokensToCSSVars(traceTheme.mode === "light" ? coolLight : coolDark) : {};
6467
7166
  return {
@@ -6470,7 +7169,7 @@ function ExplainableShell({
6470
7169
  ...traceTheme.current !== void 0 && { ["--fp-node-cursor"]: traceTheme.current }
6471
7170
  };
6472
7171
  }, [traceTheme]);
6473
- return /* @__PURE__ */ jsxs23(
7172
+ return /* @__PURE__ */ jsxs24(
6474
7173
  "div",
6475
7174
  {
6476
7175
  ref: shellRef,
@@ -6489,20 +7188,21 @@ function ExplainableShell({
6489
7188
  },
6490
7189
  "data-fp": "explainable-shell",
6491
7190
  children: [
6492
- /* @__PURE__ */ jsx26(
7191
+ /* @__PURE__ */ jsx27(
6493
7192
  TimeTravelControls,
6494
7193
  {
6495
7194
  snapshots: activeSnapshots,
6496
7195
  selectedIndex: safeIdx,
6497
7196
  onIndexChange: handleSnapshotChange,
6498
- size
7197
+ size,
7198
+ tracing: tracingRail
6499
7199
  }
6500
7200
  ),
6501
- isInSubflow && /* @__PURE__ */ jsx26(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
6502
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflow: isNarrow ? "auto" : "hidden", display: "flex", flexDirection: "column" }, children: isNarrow ? (
7201
+ isInSubflow && /* @__PURE__ */ jsx27(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
7202
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, overflow: isNarrow ? "auto" : "hidden", display: "flex", flexDirection: "column" }, children: isNarrow ? (
6503
7203
  /* ── Mobile: stacked vertical ── */
6504
- /* @__PURE__ */ jsxs23(Fragment6, { children: [
6505
- showTopology && /* @__PURE__ */ jsx26("div", { style: { height: 350, flexShrink: 0, overflow: "hidden" }, children: effectiveRenderFlowchart({
7204
+ /* @__PURE__ */ jsxs24(Fragment8, { children: [
7205
+ showTopology && /* @__PURE__ */ jsx27("div", { style: { height: 350, flexShrink: 0, overflow: "hidden" }, children: effectiveRenderFlowchart({
6506
7206
  spec: null,
6507
7207
  snapshots: activeSnapshots,
6508
7208
  selectedIndex: safeIdx,
@@ -6510,9 +7210,9 @@ function ExplainableShell({
6510
7210
  showStageId,
6511
7211
  ...sliceCone && { sliceCone }
6512
7212
  }) }),
6513
- showTreeSidebar && /* @__PURE__ */ jsxs23(Fragment6, { children: [
6514
- /* @__PURE__ */ jsx26(HLinePill, { label: leftLabel, expanded: leftExpanded, onClick: () => toggleLeft(!leftExpanded) }),
6515
- leftExpanded && /* @__PURE__ */ jsx26("div", { style: { maxHeight: 180, overflow: "auto", flexShrink: 0 }, children: /* @__PURE__ */ jsx26(
7213
+ showTreeSidebar && /* @__PURE__ */ jsxs24(Fragment8, { children: [
7214
+ /* @__PURE__ */ jsx27(HLinePill, { label: leftLabel, expanded: leftExpanded, onClick: () => toggleLeft(!leftExpanded) }),
7215
+ leftExpanded && /* @__PURE__ */ jsx27("div", { style: { maxHeight: 180, overflow: "auto", flexShrink: 0 }, children: /* @__PURE__ */ jsx27(
6516
7216
  SubflowTree,
6517
7217
  {
6518
7218
  graph: traceGraph ?? { nodes: [], edges: [] },
@@ -6522,17 +7222,17 @@ function ExplainableShell({
6522
7222
  }
6523
7223
  ) })
6524
7224
  ] }),
6525
- /* @__PURE__ */ jsx26(HLinePill, { label: rightLabel, expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
6526
- rightExpanded && /* @__PURE__ */ jsx26("div", { style: { maxHeight: 350, flexShrink: 0, overflow: "hidden" }, children: detailsPanel }),
6527
- /* @__PURE__ */ jsx26(HLinePill, { label: bottomLabel, detail: `${activeSnapshots.length} stages`, expanded: timelineExpanded, onClick: toggleTimeline }),
6528
- timelineExpanded && /* @__PURE__ */ jsx26("div", { style: { flexShrink: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx26(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, size }) })
7225
+ /* @__PURE__ */ jsx27(HLinePill, { label: rightLabel, expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
7226
+ rightExpanded && /* @__PURE__ */ jsx27("div", { style: { maxHeight: 350, flexShrink: 0, overflow: "hidden" }, children: detailsPanel }),
7227
+ /* @__PURE__ */ jsx27(HLinePill, { label: bottomLabel, detail: `${activeSnapshots.length} stages`, expanded: timelineExpanded, onClick: toggleTimeline }),
7228
+ timelineExpanded && /* @__PURE__ */ jsx27("div", { style: { flexShrink: 0, overflow: "hidden" }, children: /* @__PURE__ */ jsx27(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, size }) })
6529
7229
  ] })
6530
7230
  ) : (
6531
7231
  /* ── Desktop: two-column — Flowchart | Right Panel ── */
6532
- /* @__PURE__ */ jsxs23(Fragment6, { children: [
6533
- /* @__PURE__ */ jsxs23("div", { style: { flex: 1, display: "flex", overflow: "hidden" }, children: [
6534
- showTreeSidebar && (leftExpanded ? /* @__PURE__ */ jsxs23("div", { style: { width: 180, flexShrink: 0, display: "flex", flexDirection: "row", overflow: "hidden" }, children: [
6535
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflow: "auto" }, children: /* @__PURE__ */ jsx26(
7232
+ /* @__PURE__ */ jsxs24(Fragment8, { children: [
7233
+ /* @__PURE__ */ jsxs24("div", { style: { flex: 1, display: "flex", overflow: "hidden" }, children: [
7234
+ showTreeSidebar && (leftExpanded ? /* @__PURE__ */ jsxs24("div", { style: { width: 180, flexShrink: 0, display: "flex", flexDirection: "row", overflow: "hidden" }, children: [
7235
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, overflow: "auto" }, children: /* @__PURE__ */ jsx27(
6536
7236
  SubflowTree,
6537
7237
  {
6538
7238
  graph: traceGraph ?? { nodes: [], edges: [] },
@@ -6541,24 +7241,26 @@ function ExplainableShell({
6541
7241
  onNodeSelect: handleTreeNodeSelect
6542
7242
  }
6543
7243
  ) }),
6544
- /* @__PURE__ */ jsx26(VLinePill, { label: "Topology", expanded: true, side: "left", onClick: () => toggleLeft(false) })
6545
- ] }) : /* @__PURE__ */ jsx26(VLinePill, { label: "Topology", expanded: false, side: "left", onClick: () => toggleLeft(true) })),
6546
- showTopology ? /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflow: "hidden", minWidth: 0 }, children: effectiveRenderFlowchart({
7244
+ /* @__PURE__ */ jsx27(VLinePill, { label: "Topology", expanded: true, side: "left", onClick: () => toggleLeft(false) })
7245
+ ] }) : /* @__PURE__ */ jsx27(VLinePill, { label: "Topology", expanded: false, side: "left", onClick: () => toggleLeft(true) })),
7246
+ showTopology ? /* @__PURE__ */ jsx27("div", { style: { flex: 1, overflow: "hidden", minWidth: 0 }, children: effectiveRenderFlowchart({
6547
7247
  spec: null,
6548
7248
  snapshots: activeSnapshots,
6549
7249
  selectedIndex: safeIdx,
6550
7250
  onNodeClick: handleNodeClick,
6551
7251
  showStageId,
6552
7252
  ...sliceCone && { sliceCone }
6553
- }) }) : /* @__PURE__ */ jsx26("div", { style: { flex: 1 } }),
6554
- /* @__PURE__ */ jsx26(VLinePill, { label: "Details", expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
6555
- rightExpanded && /* @__PURE__ */ jsx26("div", { style: { width: "42%", minWidth: 320, maxWidth: 550, display: "flex", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ jsx26(
7253
+ }) }) : /* @__PURE__ */ jsx27("div", { style: { flex: 1 } }),
7254
+ /* @__PURE__ */ jsx27(VLinePill, { label: "Details", expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
7255
+ rightExpanded && /* @__PURE__ */ jsx27("div", { style: { width: "42%", minWidth: 320, maxWidth: 550, display: "flex", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ jsx27(
6556
7256
  RightPanel,
6557
7257
  {
6558
7258
  mode: rightPanelMode,
6559
7259
  onModeChange: setRightPanelMode,
6560
7260
  dataTrace: shellDataTrace,
6561
7261
  onInspectorTabChange: setInspectorTab,
7262
+ inspectorTab,
7263
+ traceContent: traceTabContent,
6562
7264
  snapshots: activeSnapshots,
6563
7265
  selectedIndex: safeIdx,
6564
7266
  runtimeSnapshot,
@@ -6568,14 +7270,11 @@ function ExplainableShell({
6568
7270
  recorderViews,
6569
7271
  autoRecorderViews,
6570
7272
  size,
6571
- onNavigateToStage: (id) => {
6572
- const idx = activeSnapshots.findIndex((s) => s.runtimeStageId === id);
6573
- if (idx >= 0) setSnapshotIdx(idx);
6574
- }
7273
+ onNavigateToStage: navigateToStage
6575
7274
  }
6576
7275
  ) })
6577
7276
  ] }),
6578
- /* @__PURE__ */ jsx26(
7277
+ /* @__PURE__ */ jsx27(
6579
7278
  CompactTimeline,
6580
7279
  {
6581
7280
  snapshots: activeSnapshots,
@@ -6592,8 +7291,8 @@ function ExplainableShell({
6592
7291
 
6593
7292
  // src/components/TraceViewer/TraceViewer.tsx
6594
7293
  import * as React from "react";
6595
- import { useMemo as useMemo13 } from "react";
6596
- import { jsx as jsx27 } from "react/jsx-runtime";
7294
+ import { useMemo as useMemo15 } from "react";
7295
+ import { jsx as jsx28 } from "react/jsx-runtime";
6597
7296
  function parseTrace(input) {
6598
7297
  if (input == null) {
6599
7298
  return {
@@ -6656,11 +7355,11 @@ function TraceViewer({
6656
7355
  recorderViews,
6657
7356
  renderFlowchart
6658
7357
  }) {
6659
- const parsed = useMemo13(() => parseTrace(trace), [trace]);
7358
+ const parsed = useMemo15(() => parseTrace(trace), [trace]);
6660
7359
  React.useEffect(() => {
6661
7360
  if (!parsed.ok && onError) onError(parsed.error);
6662
7361
  }, [parsed, onError]);
6663
- const snapshots = useMemo13(() => {
7362
+ const snapshots = useMemo15(() => {
6664
7363
  if (!parsed.ok || !parsed.trace.snapshot) return [];
6665
7364
  try {
6666
7365
  return toVisualizationSnapshots(
@@ -6674,7 +7373,7 @@ function TraceViewer({
6674
7373
  if (!parsed.ok || snapshots.length === 0) {
6675
7374
  return fallback ?? null;
6676
7375
  }
6677
- return /* @__PURE__ */ jsx27(
7376
+ return /* @__PURE__ */ jsx28(
6678
7377
  ExplainableShell,
6679
7378
  {
6680
7379
  snapshots,
@@ -6710,13 +7409,16 @@ export {
6710
7409
  SubflowTree,
6711
7410
  TimeTravelControls,
6712
7411
  TraceViewer,
7412
+ TraceWalkCard,
6713
7413
  buildEntryRangeIndex,
7414
+ buildTraceWalk,
6714
7415
  computeRevealedEntryCount,
6715
7416
  coolDark,
6716
7417
  coolLight,
6717
7418
  createSnapshots,
6718
7419
  defaultTokens,
6719
7420
  extractSubflowNarrative,
7421
+ formatTraceWalk,
6720
7422
  mergeWritePatch,
6721
7423
  rawDefaults,
6722
7424
  subflowResultToSnapshots,