footprint-explainable-ui 0.27.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,
@@ -5025,6 +5730,7 @@ function TracedFlow({
5025
5730
  nodeTypes: userNodeTypes,
5026
5731
  edgeTypes: userEdgeTypes,
5027
5732
  coActiveStageIds,
5733
+ sliceCone,
5028
5734
  children,
5029
5735
  className,
5030
5736
  style
@@ -5037,21 +5743,21 @@ function TracedFlow({
5037
5743
  );
5038
5744
  }
5039
5745
  }, [layoutProp]);
5040
- const colors = useMemo10(
5746
+ const colors = useMemo13(
5041
5747
  () => ({ ...DEFAULT_COLORS, ...colorOverrides ?? {} }),
5042
5748
  [colorOverrides]
5043
5749
  );
5044
- const mergedNodeTypes = useMemo10(
5750
+ const mergedNodeTypes = useMemo13(
5045
5751
  () => userNodeTypes ? { ...DEFAULT_NODE_TYPES, ...userNodeTypes } : DEFAULT_NODE_TYPES,
5046
5752
  [userNodeTypes]
5047
5753
  );
5048
- const mergedEdgeTypes = useMemo10(
5754
+ const mergedEdgeTypes = useMemo13(
5049
5755
  () => userEdgeTypes ? { ...DEFAULT_EDGE_TYPES, ...userEdgeTypes } : DEFAULT_EDGE_TYPES,
5050
5756
  [userEdgeTypes]
5051
5757
  );
5052
5758
  const drill = useSubflowDrill(graph, onSubflowChange);
5053
- const groupedSet = useMemo10(() => new Set(groupedSubflows ?? []), [groupedSubflows]);
5054
- const filteredGraph = useMemo10(() => {
5759
+ const groupedSet = useMemo13(() => new Set(groupedSubflows ?? []), [groupedSubflows]);
5760
+ const filteredGraph = useMemo13(() => {
5055
5761
  const base = filterGraphForDrill(graph, drill.currentSubflowId);
5056
5762
  if (groupedSet.size === 0) return base;
5057
5763
  const baseIds = new Set(base.nodes.map((n) => n.id));
@@ -5066,12 +5772,12 @@ function TracedFlow({
5066
5772
  );
5067
5773
  return { nodes: [...base.nodes, ...extraNodes], edges: [...base.edges, ...extraEdges] };
5068
5774
  }, [graph, drill.currentSubflowId, groupedSet]);
5069
- const breadcrumb = useMemo10(
5775
+ const breadcrumb = useMemo13(
5070
5776
  () => buildSubflowBreadcrumb(graph, drill.currentSubflowId),
5071
5777
  [graph, drill.currentSubflowId]
5072
5778
  );
5073
- const [measuredSizes, setMeasuredSizes] = useState10(null);
5074
- const positioned = useMemo10(() => {
5779
+ const [measuredSizes, setMeasuredSizes] = useState11(null);
5780
+ const positioned = useMemo13(() => {
5075
5781
  const nodeSize = measuredSizes ? (n) => measuredSizes.get(n.id) : void 0;
5076
5782
  const sizeOpts = nodeSize ? { nodeSize } : {};
5077
5783
  const dagreBase = withForkCentering(
@@ -5095,7 +5801,7 @@ function TracedFlow({
5095
5801
  }
5096
5802
  return realBase(filteredGraph);
5097
5803
  }, [filteredGraph, layout, layoutProp, groupedSet, mainChartBox, measuredSizes]);
5098
- const slice = useMemo10(() => {
5804
+ const slice = useMemo13(() => {
5099
5805
  const empty = {
5100
5806
  doneStageIds: /* @__PURE__ */ new Set(),
5101
5807
  activeStageId: null,
@@ -5107,7 +5813,7 @@ function TracedFlow({
5107
5813
  const idx = scrubIndex ?? Math.max(0, overlay.executionOrder.length - 1);
5108
5814
  return aggregateMountStatus(sliceOverlay(overlay, idx), graph, drill.currentSubflowId);
5109
5815
  }, [overlay, scrubIndex, graph, drill.currentSubflowId]);
5110
- const reactFlowNodes = useMemo10(
5816
+ const reactFlowNodes = useMemo13(
5111
5817
  () => positioned.nodes.map(
5112
5818
  (n) => toStageNodeWithOverlay(
5113
5819
  n,
@@ -5120,12 +5826,44 @@ function TracedFlow({
5120
5826
  ),
5121
5827
  [positioned.nodes, slice, coActiveStageIds]
5122
5828
  );
5123
- const reactFlowEdges = useMemo10(
5829
+ const reactFlowEdges = useMemo13(
5124
5830
  () => positioned.edges.map(
5125
5831
  (e) => styleEdgeWithOverlay(e, slice.doneStageIds, slice.activeStageId, colors)
5126
5832
  ),
5127
5833
  [positioned.edges, slice, colors]
5128
5834
  );
5835
+ const [coneRevealed, setConeRevealed] = useState11(false);
5836
+ useEffect10(() => {
5837
+ if (!sliceCone) return;
5838
+ setConeRevealed(false);
5839
+ const raf = requestAnimationFrame(() => setConeRevealed(true));
5840
+ return () => cancelAnimationFrame(raf);
5841
+ }, [sliceCone]);
5842
+ const conedNodes = useMemo13(() => {
5843
+ if (!sliceCone || sliceCone.size === 0) return reactFlowNodes;
5844
+ return reactFlowNodes.map((n) => {
5845
+ const depth = sliceCone.get(n.id);
5846
+ if (depth === void 0) {
5847
+ return { ...n, style: { ...n.style, opacity: 0.22, transition: "opacity 260ms ease" } };
5848
+ }
5849
+ return {
5850
+ ...n,
5851
+ style: {
5852
+ ...n.style,
5853
+ opacity: coneRevealed ? 1 : 0.22,
5854
+ transition: "opacity 320ms ease",
5855
+ transitionDelay: `${depth * 90}ms`
5856
+ }
5857
+ };
5858
+ });
5859
+ }, [reactFlowNodes, sliceCone, coneRevealed]);
5860
+ const conedEdges = useMemo13(() => {
5861
+ if (!sliceCone || sliceCone.size === 0) return reactFlowEdges;
5862
+ return reactFlowEdges.map((e) => {
5863
+ const inCone = sliceCone.has(e.source) && sliceCone.has(e.target);
5864
+ return inCone ? e : { ...e, style: { ...e.style, opacity: 0.12, transition: "opacity 260ms ease" } };
5865
+ });
5866
+ }, [reactFlowEdges, sliceCone]);
5129
5867
  const handleNodeClick = useCallback7(
5130
5868
  (_, node) => {
5131
5869
  const data = node.data ?? {};
@@ -5137,13 +5875,13 @@ function TracedFlow({
5137
5875
  [drill, onNodeClick, groupedSet]
5138
5876
  );
5139
5877
  const wrapperRef = useRef8(null);
5140
- const [rfInstance, setRfInstance] = useState10(null);
5878
+ const [rfInstance, setRfInstance] = useState11(null);
5141
5879
  useChartAutoRefit(wrapperRef, rfInstance, {
5142
5880
  // Re-fit on drill AND after the measured-size re-layout settles.
5143
5881
  refitKey: `${drill.currentSubflowId ?? ""}:${measuredSizes ? "measured" : "estimated"}`,
5144
5882
  padding: 0.18
5145
5883
  });
5146
- return /* @__PURE__ */ jsxs18(
5884
+ return /* @__PURE__ */ jsxs20(
5147
5885
  "div",
5148
5886
  {
5149
5887
  ref: wrapperRef,
@@ -5157,18 +5895,18 @@ function TracedFlow({
5157
5895
  ...style
5158
5896
  },
5159
5897
  children: [
5160
- breadcrumb.length > 1 && /* @__PURE__ */ jsx21(
5898
+ breadcrumb.length > 1 && /* @__PURE__ */ jsx23(
5161
5899
  SubflowBreadcrumbBar,
5162
5900
  {
5163
5901
  entries: breadcrumb,
5164
5902
  onNavigate: drill.setCurrentSubflowId
5165
5903
  }
5166
5904
  ),
5167
- /* @__PURE__ */ jsx21("div", { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsxs18(
5905
+ /* @__PURE__ */ jsx23("div", { style: { flex: 1, minHeight: 0 }, children: /* @__PURE__ */ jsxs20(
5168
5906
  ReactFlow,
5169
5907
  {
5170
- nodes: reactFlowNodes,
5171
- edges: reactFlowEdges,
5908
+ nodes: conedNodes,
5909
+ edges: conedEdges,
5172
5910
  nodeTypes: mergedNodeTypes,
5173
5911
  edgeTypes: mergedEdgeTypes,
5174
5912
  onNodeClick: handleNodeClick,
@@ -5178,8 +5916,8 @@ function TracedFlow({
5178
5916
  minZoom: 0.1,
5179
5917
  proOptions: { hideAttribution: true },
5180
5918
  children: [
5181
- /* @__PURE__ */ jsx21(MeasuredNodeSizes, { onSizes: setMeasuredSizes }),
5182
- /* @__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 }),
5183
5921
  children
5184
5922
  ]
5185
5923
  }
@@ -5190,182 +5928,27 @@ function TracedFlow({
5190
5928
  }
5191
5929
 
5192
5930
  // src/components/InspectorPanel/InspectorPanel.tsx
5193
- import { memo as memo5, useState as useState11 } from "react";
5194
-
5195
- // src/components/DataTracePanel/DataTracePanel.tsx
5196
- import { memo as memo4 } from "react";
5197
- import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
5198
- var DataTracePanel = memo4(function DataTracePanel2({
5199
- frames,
5200
- selectedStageId,
5201
- onFrameClick,
5202
- fromStageName,
5203
- note
5204
- }) {
5205
- const noteLine = note ? /* @__PURE__ */ jsx22("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", marginBottom: 8 }, children: note }) : null;
5206
- if (frames.length === 0) {
5207
- return /* @__PURE__ */ jsxs19("div", { style: { padding: "14px 14px 12px", fontSize: 13, lineHeight: 1.55 }, children: [
5208
- /* @__PURE__ */ jsx22(
5209
- "div",
5210
- {
5211
- style: {
5212
- fontSize: 11,
5213
- color: theme.textMuted,
5214
- textTransform: "uppercase",
5215
- letterSpacing: "0.5px",
5216
- fontWeight: 600,
5217
- marginBottom: 6
5218
- },
5219
- children: "Backward causal chain"
5220
- }
5221
- ),
5222
- /* @__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." }),
5223
- noteLine,
5224
- /* @__PURE__ */ jsx22("div", { style: { color: theme.textMuted, fontSize: 12 }, children: "Select a stage above to see its dependency chain." })
5225
- ] });
5226
- }
5227
- return /* @__PURE__ */ jsxs19("div", { style: { padding: "8px 0", fontSize: 13 }, children: [
5228
- note && /* @__PURE__ */ jsx22("div", { style: { padding: "4px 12px 0", fontSize: 11, color: theme.textMuted, fontStyle: "italic" }, children: note }),
5229
- fromStageName && /* @__PURE__ */ jsxs19("div", { style: { padding: "4px 12px 8px" }, children: [
5230
- /* @__PURE__ */ jsxs19(
5231
- "div",
5232
- {
5233
- style: {
5234
- fontSize: 11,
5235
- color: theme.textMuted,
5236
- textTransform: "uppercase",
5237
- letterSpacing: "0.5px",
5238
- fontWeight: 600
5239
- },
5240
- children: [
5241
- "Data trace from ",
5242
- fromStageName
5243
- ]
5244
- }
5245
- ),
5246
- /* @__PURE__ */ jsx22(
5247
- "div",
5248
- {
5249
- style: {
5250
- fontSize: 11,
5251
- color: theme.textMuted,
5252
- fontStyle: "italic",
5253
- marginTop: 3
5254
- },
5255
- children: "Every value here was derived from the stages below."
5256
- }
5257
- )
5258
- ] }),
5259
- frames.map((frame, i) => /* @__PURE__ */ jsx22(
5260
- DataTraceFrame,
5261
- {
5262
- frame,
5263
- isFirst: i === 0,
5264
- isLast: i === frames.length - 1,
5265
- isSelected: frame.runtimeStageId === selectedStageId,
5266
- onClick: onFrameClick
5267
- },
5268
- frame.runtimeStageId
5269
- ))
5270
- ] });
5271
- });
5272
- var DataTraceFrame = memo4(function DataTraceFrame2({
5273
- frame,
5274
- isFirst,
5275
- isLast,
5276
- isSelected,
5277
- onClick
5278
- }) {
5279
- return /* @__PURE__ */ jsxs19(
5280
- "button",
5281
- {
5282
- onClick: () => onClick?.(frame.runtimeStageId),
5283
- style: {
5284
- display: "block",
5285
- width: "100%",
5286
- textAlign: "left",
5287
- border: "none",
5288
- background: isSelected ? "var(--fp-accent-bg, rgba(99,102,241,0.12))" : "transparent",
5289
- padding: "6px 12px 6px 16px",
5290
- cursor: onClick ? "pointer" : "default",
5291
- borderLeft: isSelected ? "3px solid var(--fp-accent, #6366f1)" : "3px solid transparent",
5292
- color: "inherit",
5293
- fontSize: 13
5294
- },
5295
- children: [
5296
- /* @__PURE__ */ jsxs19("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
5297
- !isFirst && /* @__PURE__ */ jsx22("span", { style: { color: theme.textMuted, fontSize: 11 }, children: "\u2191" }),
5298
- /* @__PURE__ */ jsx22(
5299
- "span",
5300
- {
5301
- style: {
5302
- fontWeight: isFirst ? 600 : 400,
5303
- color: isFirst ? "var(--fp-accent, #6366f1)" : theme.textPrimary
5304
- },
5305
- children: frame.stageName
5306
- }
5307
- ),
5308
- isLast && !isFirst && /* @__PURE__ */ jsx22(
5309
- "span",
5310
- {
5311
- style: {
5312
- fontSize: 10,
5313
- color: theme.textMuted,
5314
- fontStyle: "italic"
5315
- },
5316
- children: "(origin)"
5317
- }
5318
- )
5319
- ] }),
5320
- frame.keysWritten.length > 0 && /* @__PURE__ */ jsxs19(
5321
- "div",
5322
- {
5323
- style: {
5324
- fontSize: 11,
5325
- color: theme.textMuted,
5326
- paddingLeft: isFirst ? 0 : 18,
5327
- marginTop: 2
5328
- },
5329
- children: [
5330
- "wrote:",
5331
- " ",
5332
- /* @__PURE__ */ jsx22("span", { style: { color: theme.textSecondary }, children: frame.keysWritten.join(", ") })
5333
- ]
5334
- }
5335
- ),
5336
- frame.linkedBy && /* @__PURE__ */ jsxs19(
5337
- "div",
5338
- {
5339
- style: {
5340
- fontSize: 11,
5341
- color: "var(--fp-accent, #6366f1)",
5342
- paddingLeft: 18,
5343
- marginTop: 1
5344
- },
5345
- children: [
5346
- "\u2190 via ",
5347
- frame.linkedBy
5348
- ]
5349
- }
5350
- )
5351
- ]
5352
- }
5353
- );
5354
- });
5355
-
5356
- // src/components/InspectorPanel/InspectorPanel.tsx
5357
- import { jsx as jsx23, jsxs as jsxs20 } from "react/jsx-runtime";
5358
- 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({
5359
5934
  snapshots,
5360
5935
  selectedIndex,
5361
5936
  dataTraceFrames,
5362
5937
  dataTraceNote,
5363
5938
  selectedStageId,
5364
- onNavigateToStage
5939
+ onNavigateToStage,
5940
+ onTabChange,
5941
+ tab: controlledTab,
5942
+ traceContent
5365
5943
  }) {
5366
- const [tab, setTab] = useState11("state");
5944
+ const [internalTab, setTabState] = useState12("state");
5945
+ const tab = controlledTab ?? internalTab;
5946
+ const setTab = (t) => {
5947
+ setTabState(t);
5948
+ onTabChange?.(t);
5949
+ };
5367
5950
  const currentSnapshot = snapshots[selectedIndex];
5368
- return /* @__PURE__ */ jsxs20(
5951
+ return /* @__PURE__ */ jsxs21(
5369
5952
  "div",
5370
5953
  {
5371
5954
  style: {
@@ -5375,7 +5958,7 @@ var InspectorPanel = memo5(function InspectorPanel2({
5375
5958
  overflow: "hidden"
5376
5959
  },
5377
5960
  children: [
5378
- /* @__PURE__ */ jsxs20(
5961
+ /* @__PURE__ */ jsxs21(
5379
5962
  "div",
5380
5963
  {
5381
5964
  style: {
@@ -5384,7 +5967,7 @@ var InspectorPanel = memo5(function InspectorPanel2({
5384
5967
  flexShrink: 0
5385
5968
  },
5386
5969
  children: [
5387
- /* @__PURE__ */ jsx23(
5970
+ /* @__PURE__ */ jsx24(
5388
5971
  TabButton,
5389
5972
  {
5390
5973
  active: tab === "state",
@@ -5392,7 +5975,7 @@ var InspectorPanel = memo5(function InspectorPanel2({
5392
5975
  label: "State"
5393
5976
  }
5394
5977
  ),
5395
- /* @__PURE__ */ jsx23(
5978
+ /* @__PURE__ */ jsx24(
5396
5979
  TabButton,
5397
5980
  {
5398
5981
  active: tab === "trace",
@@ -5404,15 +5987,15 @@ var InspectorPanel = memo5(function InspectorPanel2({
5404
5987
  ]
5405
5988
  }
5406
5989
  ),
5407
- /* @__PURE__ */ jsxs20("div", { style: { flex: 1, overflow: "auto" }, children: [
5408
- tab === "state" && /* @__PURE__ */ jsx23(
5990
+ /* @__PURE__ */ jsxs21("div", { style: { flex: 1, overflow: "auto" }, children: [
5991
+ tab === "state" && /* @__PURE__ */ jsx24(
5409
5992
  MemoryPanel,
5410
5993
  {
5411
5994
  snapshots,
5412
5995
  selectedIndex
5413
5996
  }
5414
5997
  ),
5415
- tab === "trace" && /* @__PURE__ */ jsx23(
5998
+ tab === "trace" && (traceContent ?? /* @__PURE__ */ jsx24(
5416
5999
  DataTracePanel,
5417
6000
  {
5418
6001
  frames: dataTraceFrames,
@@ -5421,7 +6004,7 @@ var InspectorPanel = memo5(function InspectorPanel2({
5421
6004
  onFrameClick: onNavigateToStage,
5422
6005
  fromStageName: currentSnapshot?.stageName
5423
6006
  }
5424
- )
6007
+ ))
5425
6008
  ] })
5426
6009
  ]
5427
6010
  }
@@ -5433,7 +6016,7 @@ function TabButton({
5433
6016
  label,
5434
6017
  badge
5435
6018
  }) {
5436
- return /* @__PURE__ */ jsxs20(
6019
+ return /* @__PURE__ */ jsxs21(
5437
6020
  "button",
5438
6021
  {
5439
6022
  onClick,
@@ -5452,7 +6035,7 @@ function TabButton({
5452
6035
  },
5453
6036
  children: [
5454
6037
  label,
5455
- badge && /* @__PURE__ */ jsx23(
6038
+ badge && /* @__PURE__ */ jsx24(
5456
6039
  "span",
5457
6040
  {
5458
6041
  style: {
@@ -5472,28 +6055,28 @@ function TabButton({
5472
6055
  }
5473
6056
 
5474
6057
  // src/components/InsightPanel/InsightPanel.tsx
5475
- import { memo as memo6, useState as useState12 } from "react";
5476
- import { jsx as jsx24, jsxs as jsxs21 } from "react/jsx-runtime";
5477
- 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({
5478
6061
  insights,
5479
6062
  expandedId,
5480
6063
  mode
5481
6064
  }) {
5482
6065
  if (insights.length === 0) {
5483
- 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." });
5484
6067
  }
5485
6068
  if (mode === "grid") {
5486
- return /* @__PURE__ */ jsx24(InsightGrid, { insights });
6069
+ return /* @__PURE__ */ jsx25(InsightGrid, { insights });
5487
6070
  }
5488
- return /* @__PURE__ */ jsx24(InsightTabs, { insights, defaultId: expandedId });
6071
+ return /* @__PURE__ */ jsx25(InsightTabs, { insights, defaultId: expandedId });
5489
6072
  });
5490
- var InsightTabs = memo6(function InsightTabs2({
6073
+ var InsightTabs = memo7(function InsightTabs2({
5491
6074
  insights,
5492
6075
  defaultId
5493
6076
  }) {
5494
- const [activeId, setActiveId] = useState12(defaultId ?? insights[0]?.id);
6077
+ const [activeId, setActiveId] = useState13(defaultId ?? insights[0]?.id);
5495
6078
  const active = insights.find((i) => i.id === activeId) ?? insights[0];
5496
- return /* @__PURE__ */ jsxs21(
6079
+ return /* @__PURE__ */ jsxs22(
5497
6080
  "div",
5498
6081
  {
5499
6082
  style: {
@@ -5503,7 +6086,7 @@ var InsightTabs = memo6(function InsightTabs2({
5503
6086
  overflow: "hidden"
5504
6087
  },
5505
6088
  children: [
5506
- /* @__PURE__ */ jsx24(
6089
+ /* @__PURE__ */ jsx25(
5507
6090
  "div",
5508
6091
  {
5509
6092
  style: {
@@ -5512,7 +6095,7 @@ var InsightTabs = memo6(function InsightTabs2({
5512
6095
  flexShrink: 0,
5513
6096
  overflowX: "auto"
5514
6097
  },
5515
- children: insights.map((insight) => /* @__PURE__ */ jsx24(
6098
+ children: insights.map((insight) => /* @__PURE__ */ jsx25(
5516
6099
  "button",
5517
6100
  {
5518
6101
  onClick: () => setActiveId(insight.id),
@@ -5533,16 +6116,16 @@ var InsightTabs = memo6(function InsightTabs2({
5533
6116
  ))
5534
6117
  }
5535
6118
  ),
5536
- /* @__PURE__ */ jsx24("div", { style: { flex: 1, overflow: "auto" }, children: active?.render() })
6119
+ /* @__PURE__ */ jsx25("div", { style: { flex: 1, overflow: "auto" }, children: active?.render() })
5537
6120
  ]
5538
6121
  }
5539
6122
  );
5540
6123
  });
5541
- var InsightGrid = memo6(function InsightGrid2({
6124
+ var InsightGrid = memo7(function InsightGrid2({
5542
6125
  insights
5543
6126
  }) {
5544
6127
  const cols = insights.length <= 2 ? 1 : 2;
5545
- return /* @__PURE__ */ jsx24(
6128
+ return /* @__PURE__ */ jsx25(
5546
6129
  "div",
5547
6130
  {
5548
6131
  style: {
@@ -5553,7 +6136,7 @@ var InsightGrid = memo6(function InsightGrid2({
5553
6136
  gap: 1,
5554
6137
  background: theme.border
5555
6138
  },
5556
- children: insights.map((insight) => /* @__PURE__ */ jsxs21(
6139
+ children: insights.map((insight) => /* @__PURE__ */ jsxs22(
5557
6140
  "div",
5558
6141
  {
5559
6142
  style: {
@@ -5563,7 +6146,7 @@ var InsightGrid = memo6(function InsightGrid2({
5563
6146
  overflow: "hidden"
5564
6147
  },
5565
6148
  children: [
5566
- /* @__PURE__ */ jsxs21(
6149
+ /* @__PURE__ */ jsxs22(
5567
6150
  "div",
5568
6151
  {
5569
6152
  style: {
@@ -5578,7 +6161,7 @@ var InsightGrid = memo6(function InsightGrid2({
5578
6161
  },
5579
6162
  children: [
5580
6163
  insight.name,
5581
- insight.summary && /* @__PURE__ */ jsx24(
6164
+ insight.summary && /* @__PURE__ */ jsx25(
5582
6165
  "span",
5583
6166
  {
5584
6167
  style: {
@@ -5593,7 +6176,7 @@ var InsightGrid = memo6(function InsightGrid2({
5593
6176
  ]
5594
6177
  }
5595
6178
  ),
5596
- /* @__PURE__ */ jsx24("div", { style: { flex: 1, overflow: "auto" }, children: insight.render() })
6179
+ /* @__PURE__ */ jsx25("div", { style: { flex: 1, overflow: "auto" }, children: insight.render() })
5597
6180
  ]
5598
6181
  },
5599
6182
  insight.id
@@ -5603,17 +6186,17 @@ var InsightGrid = memo6(function InsightGrid2({
5603
6186
  });
5604
6187
 
5605
6188
  // src/components/CompactTimeline/CompactTimeline.tsx
5606
- import { memo as memo7, useState as useState13 } from "react";
5607
- import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
5608
- 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({
5609
6192
  snapshots,
5610
6193
  selectedIndex,
5611
6194
  defaultExpanded = false
5612
6195
  }) {
5613
- const [expanded, setExpanded] = useState13(defaultExpanded);
6196
+ const [expanded, setExpanded] = useState14(defaultExpanded);
5614
6197
  if (snapshots.length === 0) return null;
5615
- return /* @__PURE__ */ jsxs22("div", { style: { borderTop: `1px solid ${theme.border}` }, children: [
5616
- /* @__PURE__ */ jsxs22(
6198
+ return /* @__PURE__ */ jsxs23("div", { style: { borderTop: `1px solid ${theme.border}` }, children: [
6199
+ /* @__PURE__ */ jsxs23(
5617
6200
  "button",
5618
6201
  {
5619
6202
  onClick: () => setExpanded((e) => !e),
@@ -5633,13 +6216,13 @@ var CompactTimeline = memo7(function CompactTimeline2({
5633
6216
  letterSpacing: "0.5px"
5634
6217
  },
5635
6218
  children: [
5636
- /* @__PURE__ */ jsx25("span", { style: { fontSize: 10 }, children: expanded ? "\u25BC" : "\u25B8" }),
6219
+ /* @__PURE__ */ jsx26("span", { style: { fontSize: 10 }, children: expanded ? "\u25BC" : "\u25B8" }),
5637
6220
  "Timeline",
5638
- /* @__PURE__ */ jsxs22("span", { style: { fontWeight: 400, fontSize: 10 }, children: [
6221
+ /* @__PURE__ */ jsxs23("span", { style: { fontWeight: 400, fontSize: 10 }, children: [
5639
6222
  snapshots.length,
5640
6223
  " stages"
5641
6224
  ] }),
5642
- !expanded && /* @__PURE__ */ jsxs22(
6225
+ !expanded && /* @__PURE__ */ jsxs23(
5643
6226
  "div",
5644
6227
  {
5645
6228
  style: {
@@ -5650,7 +6233,7 @@ var CompactTimeline = memo7(function CompactTimeline2({
5650
6233
  marginLeft: 8
5651
6234
  },
5652
6235
  children: [
5653
- snapshots.map((snap, i) => /* @__PURE__ */ jsx25(
6236
+ snapshots.map((snap, i) => /* @__PURE__ */ jsx26(
5654
6237
  "div",
5655
6238
  {
5656
6239
  style: {
@@ -5665,7 +6248,7 @@ var CompactTimeline = memo7(function CompactTimeline2({
5665
6248
  },
5666
6249
  i
5667
6250
  )),
5668
- /* @__PURE__ */ jsx25(
6251
+ /* @__PURE__ */ jsx26(
5669
6252
  "div",
5670
6253
  {
5671
6254
  style: {
@@ -5683,7 +6266,7 @@ var CompactTimeline = memo7(function CompactTimeline2({
5683
6266
  ]
5684
6267
  }
5685
6268
  ),
5686
- 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(
5687
6270
  GanttTimeline,
5688
6271
  {
5689
6272
  snapshots,
@@ -5694,21 +6277,21 @@ var CompactTimeline = memo7(function CompactTimeline2({
5694
6277
  });
5695
6278
 
5696
6279
  // src/components/ExplainableShell/ExplainableShell.tsx
5697
- import { Fragment as Fragment6, jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
5698
- 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({
5699
6282
  label,
5700
6283
  detail,
5701
6284
  expanded,
5702
6285
  onClick
5703
6286
  }) {
5704
- return /* @__PURE__ */ jsxs23("div", { style: {
6287
+ return /* @__PURE__ */ jsxs24("div", { style: {
5705
6288
  display: "flex",
5706
6289
  alignItems: "center",
5707
6290
  gap: 0,
5708
6291
  padding: "0"
5709
6292
  }, children: [
5710
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, height: 1, background: theme.border } }),
5711
- /* @__PURE__ */ jsxs23(
6293
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, height: 1, background: theme.border } }),
6294
+ /* @__PURE__ */ jsxs24(
5712
6295
  "button",
5713
6296
  {
5714
6297
  onClick,
@@ -5732,31 +6315,31 @@ var HLinePill = memo8(function HLinePill2({
5732
6315
  transition: "color 0.15s ease"
5733
6316
  },
5734
6317
  children: [
5735
- /* @__PURE__ */ jsx26("span", { style: { fontSize: 7 }, children: expanded ? "\u25BC" : "\u25B6" }),
6318
+ /* @__PURE__ */ jsx27("span", { style: { fontSize: 7 }, children: expanded ? "\u25BC" : "\u25B6" }),
5736
6319
  label,
5737
- 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 })
5738
6321
  ]
5739
6322
  }
5740
6323
  ),
5741
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, height: 1, background: theme.border } })
6324
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, height: 1, background: theme.border } })
5742
6325
  ] });
5743
6326
  });
5744
- var VLinePill = memo8(function VLinePill2({
6327
+ var VLinePill = memo9(function VLinePill2({
5745
6328
  label,
5746
6329
  expanded,
5747
6330
  side = "right",
5748
6331
  onClick
5749
6332
  }) {
5750
6333
  const arrow = side === "right" ? expanded ? "\u25B6" : "\u25C0" : expanded ? "\u25C0" : "\u25B6";
5751
- return /* @__PURE__ */ jsxs23("div", { style: {
6334
+ return /* @__PURE__ */ jsxs24("div", { style: {
5752
6335
  display: "flex",
5753
6336
  flexDirection: "column",
5754
6337
  alignItems: "center",
5755
6338
  gap: 0,
5756
6339
  padding: "0"
5757
6340
  }, children: [
5758
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, width: 1, background: theme.border } }),
5759
- /* @__PURE__ */ jsxs23(
6341
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, width: 1, background: theme.border } }),
6342
+ /* @__PURE__ */ jsxs24(
5760
6343
  "button",
5761
6344
  {
5762
6345
  onClick,
@@ -5781,12 +6364,12 @@ var VLinePill = memo8(function VLinePill2({
5781
6364
  transition: "color 0.15s ease"
5782
6365
  },
5783
6366
  children: [
5784
- /* @__PURE__ */ jsx26("span", { style: { fontSize: 7, writingMode: "horizontal-tb" }, children: arrow }),
6367
+ /* @__PURE__ */ jsx27("span", { style: { fontSize: 7, writingMode: "horizontal-tb" }, children: arrow }),
5785
6368
  label
5786
6369
  ]
5787
6370
  }
5788
6371
  ),
5789
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, width: 1, background: theme.border } })
6372
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, width: 1, background: theme.border } })
5790
6373
  ] });
5791
6374
  });
5792
6375
  function detectKeyedSteps(data) {
@@ -5823,9 +6406,9 @@ function KeyedRecorderView({
5823
6406
  snapshots,
5824
6407
  selectedIndex
5825
6408
  }) {
5826
- const [showAggregate, setShowAggregate] = useState14(false);
5827
- const detected = useMemo12(() => detectKeyedSteps(data), [data]);
5828
- const visibleKeys = useMemo12(() => {
6409
+ const [showAggregate, setShowAggregate] = useState15(false);
6410
+ const detected = useMemo14(() => detectKeyedSteps(data), [data]);
6411
+ const visibleKeys = useMemo14(() => {
5829
6412
  const keys = /* @__PURE__ */ new Set();
5830
6413
  for (let i = 0; i <= selectedIndex && i < snapshots.length; i++) {
5831
6414
  const snap = snapshots[i];
@@ -5840,7 +6423,7 @@ function KeyedRecorderView({
5840
6423
  }, [snapshots, selectedIndex, detected?.keyType]);
5841
6424
  const isAtEnd = selectedIndex >= snapshots.length - 1;
5842
6425
  if (!detected) {
5843
- 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) });
5844
6427
  }
5845
6428
  const steps = detected.steps;
5846
6429
  const hints = extractRenderHints(data);
@@ -5854,13 +6437,13 @@ function KeyedRecorderView({
5854
6437
  }
5855
6438
  }
5856
6439
  const grandTotal = hints?.grandTotal ?? 0;
5857
- return /* @__PURE__ */ jsxs23("div", { style: { overflow: "auto", height: "100%", display: "flex", flexDirection: "column" }, children: [
5858
- description && /* @__PURE__ */ jsx26("div", { style: { padding: "6px 12px", fontSize: 11, color: theme.textMuted, fontStyle: "italic", borderBottom: `1px solid ${theme.border}`, flexShrink: 0 }, children: description }),
5859
- /* @__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: [
5860
6443
  preferredOperation === "aggregate" ? (
5861
6444
  /* AGGREGATE: collect silently during scrub, button at end to reveal total */
5862
- /* @__PURE__ */ jsxs23(Fragment6, { children: [
5863
- 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(
5864
6447
  "button",
5865
6448
  {
5866
6449
  onClick: () => setShowAggregate(true),
@@ -5878,35 +6461,35 @@ function KeyedRecorderView({
5878
6461
  },
5879
6462
  children: "Aggregate \u2014 Show Grand Total"
5880
6463
  }
5881
- ) : /* @__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: [
5882
- /* @__PURE__ */ jsx26("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Aggregate \u2014 grand total" }),
5883
- 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: [
5884
6467
  grandTotal < 1 ? grandTotal.toFixed(3) : grandTotal.toFixed(1),
5885
- /* @__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: [
5886
6469
  numFieldKey,
5887
6470
  " \xB7 ",
5888
6471
  allKeys.length,
5889
6472
  " steps"
5890
6473
  ] })
5891
6474
  ] })
5892
- ] }) }) : /* @__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: [
5893
- /* @__PURE__ */ jsx26("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 600 }, children: "Collecting data..." }),
5894
- /* @__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: [
5895
6478
  visibleEntries.length,
5896
6479
  " of ",
5897
6480
  allKeys.length,
5898
6481
  " steps collected. Scrub to end to aggregate."
5899
6482
  ] })
5900
6483
  ] }),
5901
- /* @__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" })
5902
6485
  ] })
5903
6486
  ) : preferredOperation === "accumulate" ? (
5904
6487
  /* ACCUMULATE: running total grows with slider — IS the total at end, no button */
5905
- /* @__PURE__ */ jsxs23(Fragment6, { children: [
5906
- 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: [
5907
- /* @__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" }),
5908
- /* @__PURE__ */ jsx26("span", { style: { fontWeight: 700, fontSize: 18, color: theme.primary }, children: runningTotal < 1 ? runningTotal.toFixed(3) : runningTotal.toFixed(1) }),
5909
- /* @__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: [
5910
6493
  numFieldKey,
5911
6494
  " \xB7 ",
5912
6495
  visibleEntries.length,
@@ -5915,27 +6498,27 @@ function KeyedRecorderView({
5915
6498
  " steps"
5916
6499
  ] })
5917
6500
  ] }),
5918
- /* @__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" })
5919
6502
  ] })
5920
6503
  ) : (
5921
6504
  /* TRANSLATE: per-step entries prominent, no totals */
5922
- /* @__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" })
5923
6506
  ),
5924
6507
  visibleEntries.map((key) => {
5925
6508
  const entry = steps[key];
5926
6509
  const label = entry.stageName ?? key;
5927
6510
  const numVal = numFieldKey ? entry[numFieldKey] : void 0;
5928
- return /* @__PURE__ */ jsxs23("div", { style: { display: "flex", alignItems: "center", padding: "4px 0", fontSize: 12, fontFamily: theme.fontMono, borderBottom: `1px solid ${theme.border}22` }, children: [
5929
- /* @__PURE__ */ jsx26("span", { style: { color: theme.textMuted, width: 140, flexShrink: 0, fontSize: 10 }, children: key }),
5930
- /* @__PURE__ */ jsx26("span", { style: { fontWeight: 600, flex: 1 }, children: label }),
5931
- 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) })
5932
6515
  ] }, key);
5933
6516
  }),
5934
- 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..." })
5935
6518
  ] })
5936
6519
  ] });
5937
6520
  }
5938
- var DetailsContent = memo8(function DetailsContent2({
6521
+ var DetailsContent = memo9(function DetailsContent2({
5939
6522
  snapshots,
5940
6523
  selectedIndex,
5941
6524
  narrativeEntries,
@@ -5947,16 +6530,16 @@ var DetailsContent = memo8(function DetailsContent2({
5947
6530
  {
5948
6531
  id: "memory",
5949
6532
  name: "Memory",
5950
- 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 })
5951
6534
  },
5952
6535
  {
5953
6536
  id: "narrative",
5954
6537
  name: "Narrative",
5955
- 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 })
5956
6539
  }
5957
6540
  ];
5958
6541
  const allViews = [...builtInViews, ...extraViews ?? []];
5959
- const [activeViewId, setActiveViewId] = useState14(allViews[0]?.id ?? "memory");
6542
+ const [activeViewId, setActiveViewId] = useState15(allViews[0]?.id ?? "memory");
5960
6543
  const viewIds = allViews.map((v2) => v2.id).join(",");
5961
6544
  useEffect11(() => {
5962
6545
  if (!allViews.find((v2) => v2.id === activeViewId)) {
@@ -5964,10 +6547,10 @@ var DetailsContent = memo8(function DetailsContent2({
5964
6547
  }
5965
6548
  }, [viewIds]);
5966
6549
  const activeView = allViews.find((v2) => v2.id === activeViewId) ?? allViews[0];
5967
- return /* @__PURE__ */ jsxs23("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: [
5968
- /* @__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) => {
5969
6552
  const active = view.id === activeViewId;
5970
- return /* @__PURE__ */ jsx26(
6553
+ return /* @__PURE__ */ jsx27(
5971
6554
  "button",
5972
6555
  {
5973
6556
  onClick: () => setActiveViewId(view.id),
@@ -5991,7 +6574,7 @@ var DetailsContent = memo8(function DetailsContent2({
5991
6574
  view.id
5992
6575
  );
5993
6576
  }) }),
5994
- /* @__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 }) })
5995
6578
  ] });
5996
6579
  });
5997
6580
  function resolveSubflowFromRuntime(parentSnapshots, subflowId, narrativeEntries) {
@@ -6008,7 +6591,7 @@ function resolveSubflowFromRuntime(parentSnapshots, subflowId, narrativeEntries)
6008
6591
  if (sfSnapshots.length === 0) return null;
6009
6592
  return { subflowId, label, spec: null, snapshots: sfSnapshots, narrative: sfNarrative };
6010
6593
  }
6011
- var RightPanel = memo8(function RightPanel2({
6594
+ var RightPanel = memo9(function RightPanel2({
6012
6595
  mode,
6013
6596
  onModeChange,
6014
6597
  snapshots,
@@ -6020,19 +6603,19 @@ var RightPanel = memo8(function RightPanel2({
6020
6603
  recorderViews,
6021
6604
  autoRecorderViews,
6022
6605
  size,
6023
- onNavigateToStage
6606
+ onNavigateToStage,
6607
+ dataTrace,
6608
+ onInspectorTabChange,
6609
+ inspectorTab,
6610
+ traceContent
6024
6611
  }) {
6025
- const dataTrace = useMemo12(
6026
- () => runtimeSnapshot?.commitLog ? buildDataTrace(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, snapshots[selectedIndex]?.runtimeStageId ?? "") : { frames: [], readsAvailable: true },
6027
- [runtimeSnapshot, snapshots, selectedIndex]
6028
- );
6029
- return /* @__PURE__ */ jsxs23(Fragment6, { children: [
6030
- /* @__PURE__ */ jsx26("div", { style: {
6612
+ return /* @__PURE__ */ jsxs24(Fragment8, { children: [
6613
+ /* @__PURE__ */ jsx27("div", { style: {
6031
6614
  display: "flex",
6032
6615
  borderBottom: `1px solid ${theme.border}`,
6033
6616
  flexShrink: 0,
6034
6617
  background: theme.bgSecondary
6035
- }, children: ["insights", "what"].map((m) => /* @__PURE__ */ jsx26(
6618
+ }, children: ["insights", "what"].map((m) => /* @__PURE__ */ jsx27(
6036
6619
  "button",
6037
6620
  {
6038
6621
  onClick: () => onModeChange(m),
@@ -6054,7 +6637,7 @@ var RightPanel = memo8(function RightPanel2({
6054
6637
  },
6055
6638
  m
6056
6639
  )) }),
6057
- /* @__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(
6058
6641
  InsightPanel,
6059
6642
  {
6060
6643
  mode: "tabs",
@@ -6063,22 +6646,25 @@ var RightPanel = memo8(function RightPanel2({
6063
6646
  id: tab.id,
6064
6647
  name: insightName(tab.name),
6065
6648
  render: () => {
6066
- 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%" } });
6067
6650
  const customView = recorderViews?.find((v2) => v2.id === tab.id);
6068
6651
  if (customView?.render) return customView.render({ snapshots, selectedIndex });
6069
6652
  const autoView = autoRecorderViews.find((v2) => v2.id === tab.id);
6070
- 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 });
6071
6654
  return null;
6072
6655
  }
6073
6656
  }))
6074
6657
  }
6075
- ) : /* @__PURE__ */ jsx26(
6658
+ ) : /* @__PURE__ */ jsx27(
6076
6659
  InspectorPanel,
6077
6660
  {
6078
6661
  snapshots,
6079
6662
  selectedIndex,
6080
6663
  dataTraceFrames: dataTrace.frames,
6081
6664
  dataTraceNote: dataTrace.readsAvailable ? void 0 : "\u26A0 reads were not recorded (readTracking off) \u2014 dependencies are unknowable, not absent.",
6665
+ onTabChange: onInspectorTabChange,
6666
+ tab: inspectorTab,
6667
+ traceContent,
6082
6668
  selectedStageId: snapshots[selectedIndex]?.runtimeStageId,
6083
6669
  onNavigateToStage
6084
6670
  }
@@ -6119,7 +6705,7 @@ function ExplainableShell({
6119
6705
  className,
6120
6706
  style
6121
6707
  }) {
6122
- const derivedFromRuntime = useMemo12(() => {
6708
+ const derivedFromRuntime = useMemo14(() => {
6123
6709
  if (!runtimeSnapshot) return null;
6124
6710
  try {
6125
6711
  const snaps = toVisualizationSnapshots(runtimeSnapshot, narrativeEntries);
@@ -6130,9 +6716,9 @@ function ExplainableShell({
6130
6716
  }, [runtimeSnapshot, narrativeEntries]);
6131
6717
  const snapshots = snapshotsProp ?? derivedFromRuntime?.snapshots ?? [];
6132
6718
  const resultData = resultDataProp ?? derivedFromRuntime?.resultData ?? null;
6133
- const tracedFlowRenderer = useMemo12(() => {
6719
+ const tracedFlowRenderer = useMemo14(() => {
6134
6720
  if (!traceGraph) return void 0;
6135
- return ({ selectedIndex, snapshots: snapshots2, onNodeClick }) => {
6721
+ return ({ selectedIndex, snapshots: snapshots2, onNodeClick, sliceCone: sliceCone2 }) => {
6136
6722
  const activeRsid = snapshots2[selectedIndex]?.runtimeStageId;
6137
6723
  let overlayIdx = selectedIndex;
6138
6724
  if (activeRsid && runtimeOverlay) {
@@ -6151,11 +6737,12 @@ function ExplainableShell({
6151
6737
  ...traceTheme.current !== void 0 && { active: traceTheme.current },
6152
6738
  ...traceTheme.mode !== void 0 && { default: traceTheme.mode === "dark" ? "#94a3b8" : "#64748b" }
6153
6739
  };
6154
- return /* @__PURE__ */ jsx26(
6740
+ return /* @__PURE__ */ jsx27(
6155
6741
  TracedFlow,
6156
6742
  {
6157
6743
  graph: traceGraph,
6158
6744
  overlay: runtimeOverlay ?? void 0,
6745
+ sliceCone: sliceCone2 ?? void 0,
6159
6746
  colors: traceColors || void 0,
6160
6747
  scrubIndex: overlayIdx,
6161
6748
  onNodeClick: (stageId) => onNodeClick?.(stageId),
@@ -6171,8 +6758,8 @@ function ExplainableShell({
6171
6758
  const rightLabel = panelLabels?.details ?? "Details";
6172
6759
  const bottomLabel = panelLabels?.timeline ?? "Timeline";
6173
6760
  const shellRef = useRef9(null);
6174
- const [isNarrow, setIsNarrow] = useState14(false);
6175
- const [isMedium, setIsMedium] = useState14(false);
6761
+ const [isNarrow, setIsNarrow] = useState15(false);
6762
+ const [isMedium, setIsMedium] = useState15(false);
6176
6763
  useEffect11(() => {
6177
6764
  const el = shellRef.current;
6178
6765
  if (!el) return;
@@ -6185,14 +6772,14 @@ function ExplainableShell({
6185
6772
  ro.observe(el);
6186
6773
  return () => ro.disconnect();
6187
6774
  }, []);
6188
- const autoRecorderViews = useMemo12(() => {
6775
+ const autoRecorderViews = useMemo14(() => {
6189
6776
  const recorders = runtimeSnapshot?.recorders;
6190
6777
  if (!recorders?.length) return [];
6191
6778
  const explicitIds = new Set((recorderViews ?? []).map((v2) => v2.id));
6192
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 }));
6193
6780
  }, [runtimeSnapshot, recorderViews]);
6194
6781
  const hasNarrative = !!narrativeEntries?.length;
6195
- const allTabs = useMemo12(() => {
6782
+ const allTabs = useMemo14(() => {
6196
6783
  const tabs2 = [
6197
6784
  { id: "result", name: "Result", description: "Final output and console logs" },
6198
6785
  { id: "memory", name: "Memory", description: "Accumulator \u2014 progressive shared state at each stage" }
@@ -6211,13 +6798,15 @@ function ExplainableShell({
6211
6798
  }, [hasNarrative, recorderViews, autoRecorderViews, hideTabsProp]);
6212
6799
  const validTabIds = new Set(allTabs.map((t) => t.id));
6213
6800
  const resolvedDefault = defaultTab && validTabIds.has(defaultTab) ? defaultTab : allTabs[0]?.id ?? "result";
6214
- const [activeTab, setActiveTab] = useState14(resolvedDefault);
6215
- const [snapshotIdx, setSnapshotIdx] = useState14(0);
6216
- const [drillDownStack, setDrillDownStack] = useState14([]);
6217
- const [rightExpanded, setRightExpanded] = useState14(defaultExpanded?.details ?? true);
6218
- const [rightPanelMode, setRightPanelMode] = useState14("insights");
6219
- const [leftExpanded, setLeftExpanded] = useState14(defaultExpanded?.topology ?? false);
6220
- 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);
6221
6810
  useEffect11(() => {
6222
6811
  if (isNarrow) {
6223
6812
  setLeftExpanded(false);
@@ -6242,7 +6831,7 @@ function ExplainableShell({
6242
6831
  triggerReflow();
6243
6832
  }, [triggerReflow]);
6244
6833
  const isInSubflow = drillDownStack.length > 0;
6245
- const currentLevel = useMemo12(() => {
6834
+ const currentLevel = useMemo14(() => {
6246
6835
  if (drillDownStack.length > 0) {
6247
6836
  const top = drillDownStack[drillDownStack.length - 1];
6248
6837
  return { spec: top.spec, snapshots: top.snapshots, narrative: top.narrative };
@@ -6251,18 +6840,54 @@ function ExplainableShell({
6251
6840
  }, [drillDownStack, snapshots]);
6252
6841
  const activeSnapshots = currentLevel.snapshots;
6253
6842
  const safeIdx = activeSnapshots.length > 0 ? Math.max(0, Math.min(snapshotIdx, activeSnapshots.length - 1)) : 0;
6843
+ const shellDataTrace = useMemo14(
6844
+ () => runtimeSnapshot?.commitLog ? buildDataTrace(runtimeSnapshot.commitLog, runtimeSnapshot.executionTree, activeSnapshots[safeIdx]?.runtimeStageId ?? "") : { frames: [], readsAvailable: true },
6845
+ [runtimeSnapshot, activeSnapshots, safeIdx]
6846
+ );
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
+ }
6869
+ if (rightPanelMode !== "what" || inspectorTab !== "trace") return void 0;
6870
+ if (shellDataTrace.frames.length < 2) return void 0;
6871
+ const cone = /* @__PURE__ */ new Map();
6872
+ for (const f of shellDataTrace.frames) {
6873
+ const stagePart = f.runtimeStageId.split("#")[0];
6874
+ const prev = cone.get(stagePart);
6875
+ if (prev === void 0 || f.depth < prev) cone.set(stagePart, f.depth);
6876
+ }
6877
+ return cone;
6878
+ }, [traceWalk, rightPanelMode, inspectorTab, shellDataTrace]);
6254
6879
  const activeNarrativeEntries = isInSubflow ? currentLevel.narrative : narrativeEntries;
6255
- const breadcrumbs = useMemo12(() => {
6880
+ const breadcrumbs = useMemo14(() => {
6256
6881
  const root = { label: title || "Flowchart", spec: null, description: void 0 };
6257
6882
  return [root, ...drillDownStack.map((e) => ({ label: e.label, spec: e.spec, description: void 0 }))];
6258
6883
  }, [title, drillDownStack]);
6259
- const showTreeSidebar = useMemo12(() => {
6884
+ const showTreeSidebar = useMemo14(() => {
6260
6885
  if (traceGraph?.nodes?.length) {
6261
6886
  return traceGraph.nodes.some((n) => n.data?.isSubflow === true);
6262
6887
  }
6263
6888
  return false;
6264
6889
  }, [traceGraph]);
6265
- const rootOverlay = useMemo12(() => {
6890
+ const rootOverlay = useMemo14(() => {
6266
6891
  if (isInSubflow || !snapshots.length) return { activeStage: void 0, doneStages: void 0 };
6267
6892
  const doneStages = new Set(snapshots.slice(0, safeIdx).map((s) => s.stageLabel));
6268
6893
  const activeStage = snapshots[safeIdx]?.stageLabel ?? null;
@@ -6275,10 +6900,59 @@ function ExplainableShell({
6275
6900
  const handleSnapshotChange = useCallback8((idx) => {
6276
6901
  if (typeof idx === "number") setSnapshotIdx(idx);
6277
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), []);
6278
6951
  const handleDrillDown = useCallback8(
6279
6952
  (nodeName) => {
6280
6953
  const entry = resolveSubflowFromRuntime(activeSnapshots, nodeName, narrativeEntries);
6281
6954
  if (entry) {
6955
+ setTracing(null);
6282
6956
  setDrillDownStack((prev) => [...prev, { ...entry, parentSnapshotIdx: snapshotIdx }]);
6283
6957
  setSnapshotIdx(0);
6284
6958
  }
@@ -6325,33 +6999,112 @@ function ExplainableShell({
6325
6999
  },
6326
7000
  [snapshots, narrativeEntries, snapshotIdx]
6327
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]);
6328
7081
  const tabLabels = new Map(allTabs.map((t) => [t.id, t.name]));
6329
7082
  if (unstyled) {
6330
- return /* @__PURE__ */ jsxs23("div", { className, style, "data-fp": "explainable-shell", children: [
6331
- /* @__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)) }),
6332
- /* @__PURE__ */ jsxs23("div", { "data-fp": "shell-content", "data-tab": activeTab, children: [
6333
- activeTab === "result" && /* @__PURE__ */ jsx26(ResultPanel, { data: resultData ?? null, logs, hideConsole, unstyled: true }),
6334
- (activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ jsxs23(Fragment6, { children: [
6335
- /* @__PURE__ */ jsx26(TimeTravelControls, { snapshots: activeSnapshots, selectedIndex: safeIdx, onIndexChange: handleSnapshotChange, unstyled: true }),
6336
- isInSubflow && /* @__PURE__ */ jsx26(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
6337
- traceGraph && effectiveRenderFlowchart?.({ spec: null, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick, showStageId }),
6338
- /* @__PURE__ */ jsx26(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, unstyled: true }),
6339
- /* @__PURE__ */ jsx26(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, unstyled: true }),
6340
- /* @__PURE__ */ jsx26(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, unstyled: true })
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 }),
7090
+ traceGraph && effectiveRenderFlowchart?.({ spec: null, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick, showStageId, ...sliceCone && { sliceCone } }),
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 })
6341
7094
  ] })
6342
7095
  ] })
6343
7096
  ] });
6344
7097
  }
6345
7098
  const showTopology = !!effectiveRenderFlowchart && !!traceGraph;
6346
- const detailsContent = useMemo12(() => {
7099
+ const detailsContent = useMemo14(() => {
6347
7100
  if (activeTab === "result") {
6348
- return /* @__PURE__ */ jsx26(ResultPanel, { data: resultData ?? null, logs, hideConsole, size });
7101
+ return /* @__PURE__ */ jsx27(ResultPanel, { data: resultData ?? null, logs, hideConsole, size });
6349
7102
  }
6350
7103
  if (activeTab === "memory") {
6351
- 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%" } });
6352
7105
  }
6353
7106
  if (activeTab === "narrative") {
6354
- 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%" } });
6355
7108
  }
6356
7109
  const customView = recorderViews?.find((v2) => v2.id === activeTab);
6357
7110
  if (customView?.render) {
@@ -6359,7 +7112,7 @@ function ExplainableShell({
6359
7112
  }
6360
7113
  const autoView = autoRecorderViews.find((v2) => v2.id === activeTab);
6361
7114
  if (autoView) {
6362
- return /* @__PURE__ */ jsx26(
7115
+ return /* @__PURE__ */ jsx27(
6363
7116
  KeyedRecorderView,
6364
7117
  {
6365
7118
  data: autoView.data,
@@ -6372,8 +7125,8 @@ function ExplainableShell({
6372
7125
  }
6373
7126
  return null;
6374
7127
  }, [activeTab, resultData, logs, hideConsole, size, activeSnapshots, safeIdx, activeNarrativeEntries, recorderViews, autoRecorderViews]);
6375
- const detailsPanel = /* @__PURE__ */ jsxs23("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflow: "hidden" }, children: [
6376
- /* @__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: {
6377
7130
  display: "flex",
6378
7131
  borderBottom: `1px solid ${theme.border}`,
6379
7132
  background: theme.bgSecondary,
@@ -6381,7 +7134,7 @@ function ExplainableShell({
6381
7134
  overflowX: "auto"
6382
7135
  }, children: allTabs.map((tab) => {
6383
7136
  const active = tab.id === activeTab;
6384
- return /* @__PURE__ */ jsx26(
7137
+ return /* @__PURE__ */ jsx27(
6385
7138
  "button",
6386
7139
  {
6387
7140
  onClick: () => handleTabChange(tab.id),
@@ -6405,9 +7158,9 @@ function ExplainableShell({
6405
7158
  tab.id
6406
7159
  );
6407
7160
  }) }),
6408
- /* @__PURE__ */ jsx26("div", { style: { flex: 1, overflow: "auto" }, children: detailsContent })
7161
+ /* @__PURE__ */ jsx27("div", { style: { flex: 1, overflow: "auto" }, children: detailsContent })
6409
7162
  ] });
6410
- const shellThemeVars = useMemo12(() => {
7163
+ const shellThemeVars = useMemo14(() => {
6411
7164
  if (!traceTheme) return {};
6412
7165
  const base = traceTheme.mode ? tokensToCSSVars(traceTheme.mode === "light" ? coolLight : coolDark) : {};
6413
7166
  return {
@@ -6416,7 +7169,7 @@ function ExplainableShell({
6416
7169
  ...traceTheme.current !== void 0 && { ["--fp-node-cursor"]: traceTheme.current }
6417
7170
  };
6418
7171
  }, [traceTheme]);
6419
- return /* @__PURE__ */ jsxs23(
7172
+ return /* @__PURE__ */ jsxs24(
6420
7173
  "div",
6421
7174
  {
6422
7175
  ref: shellRef,
@@ -6435,29 +7188,31 @@ function ExplainableShell({
6435
7188
  },
6436
7189
  "data-fp": "explainable-shell",
6437
7190
  children: [
6438
- /* @__PURE__ */ jsx26(
7191
+ /* @__PURE__ */ jsx27(
6439
7192
  TimeTravelControls,
6440
7193
  {
6441
7194
  snapshots: activeSnapshots,
6442
7195
  selectedIndex: safeIdx,
6443
7196
  onIndexChange: handleSnapshotChange,
6444
- size
7197
+ size,
7198
+ tracing: tracingRail
6445
7199
  }
6446
7200
  ),
6447
- isInSubflow && /* @__PURE__ */ jsx26(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
6448
- /* @__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 ? (
6449
7203
  /* ── Mobile: stacked vertical ── */
6450
- /* @__PURE__ */ jsxs23(Fragment6, { children: [
6451
- 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({
6452
7206
  spec: null,
6453
7207
  snapshots: activeSnapshots,
6454
7208
  selectedIndex: safeIdx,
6455
7209
  onNodeClick: handleNodeClick,
6456
- showStageId
7210
+ showStageId,
7211
+ ...sliceCone && { sliceCone }
6457
7212
  }) }),
6458
- showTreeSidebar && /* @__PURE__ */ jsxs23(Fragment6, { children: [
6459
- /* @__PURE__ */ jsx26(HLinePill, { label: leftLabel, expanded: leftExpanded, onClick: () => toggleLeft(!leftExpanded) }),
6460
- 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(
6461
7216
  SubflowTree,
6462
7217
  {
6463
7218
  graph: traceGraph ?? { nodes: [], edges: [] },
@@ -6467,17 +7222,17 @@ function ExplainableShell({
6467
7222
  }
6468
7223
  ) })
6469
7224
  ] }),
6470
- /* @__PURE__ */ jsx26(HLinePill, { label: rightLabel, expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
6471
- rightExpanded && /* @__PURE__ */ jsx26("div", { style: { maxHeight: 350, flexShrink: 0, overflow: "hidden" }, children: detailsPanel }),
6472
- /* @__PURE__ */ jsx26(HLinePill, { label: bottomLabel, detail: `${activeSnapshots.length} stages`, expanded: timelineExpanded, onClick: toggleTimeline }),
6473
- 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 }) })
6474
7229
  ] })
6475
7230
  ) : (
6476
7231
  /* ── Desktop: two-column — Flowchart | Right Panel ── */
6477
- /* @__PURE__ */ jsxs23(Fragment6, { children: [
6478
- /* @__PURE__ */ jsxs23("div", { style: { flex: 1, display: "flex", overflow: "hidden" }, children: [
6479
- showTreeSidebar && (leftExpanded ? /* @__PURE__ */ jsxs23("div", { style: { width: 180, flexShrink: 0, display: "flex", flexDirection: "row", overflow: "hidden" }, children: [
6480
- /* @__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(
6481
7236
  SubflowTree,
6482
7237
  {
6483
7238
  graph: traceGraph ?? { nodes: [], edges: [] },
@@ -6486,21 +7241,26 @@ function ExplainableShell({
6486
7241
  onNodeSelect: handleTreeNodeSelect
6487
7242
  }
6488
7243
  ) }),
6489
- /* @__PURE__ */ jsx26(VLinePill, { label: "Topology", expanded: true, side: "left", onClick: () => toggleLeft(false) })
6490
- ] }) : /* @__PURE__ */ jsx26(VLinePill, { label: "Topology", expanded: false, side: "left", onClick: () => toggleLeft(true) })),
6491
- 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({
6492
7247
  spec: null,
6493
7248
  snapshots: activeSnapshots,
6494
7249
  selectedIndex: safeIdx,
6495
7250
  onNodeClick: handleNodeClick,
6496
- showStageId
6497
- }) }) : /* @__PURE__ */ jsx26("div", { style: { flex: 1 } }),
6498
- /* @__PURE__ */ jsx26(VLinePill, { label: "Details", expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
6499
- rightExpanded && /* @__PURE__ */ jsx26("div", { style: { width: "42%", minWidth: 320, maxWidth: 550, display: "flex", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ jsx26(
7251
+ showStageId,
7252
+ ...sliceCone && { sliceCone }
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(
6500
7256
  RightPanel,
6501
7257
  {
6502
7258
  mode: rightPanelMode,
6503
7259
  onModeChange: setRightPanelMode,
7260
+ dataTrace: shellDataTrace,
7261
+ onInspectorTabChange: setInspectorTab,
7262
+ inspectorTab,
7263
+ traceContent: traceTabContent,
6504
7264
  snapshots: activeSnapshots,
6505
7265
  selectedIndex: safeIdx,
6506
7266
  runtimeSnapshot,
@@ -6510,14 +7270,11 @@ function ExplainableShell({
6510
7270
  recorderViews,
6511
7271
  autoRecorderViews,
6512
7272
  size,
6513
- onNavigateToStage: (id) => {
6514
- const idx = activeSnapshots.findIndex((s) => s.runtimeStageId === id);
6515
- if (idx >= 0) setSnapshotIdx(idx);
6516
- }
7273
+ onNavigateToStage: navigateToStage
6517
7274
  }
6518
7275
  ) })
6519
7276
  ] }),
6520
- /* @__PURE__ */ jsx26(
7277
+ /* @__PURE__ */ jsx27(
6521
7278
  CompactTimeline,
6522
7279
  {
6523
7280
  snapshots: activeSnapshots,
@@ -6534,8 +7291,8 @@ function ExplainableShell({
6534
7291
 
6535
7292
  // src/components/TraceViewer/TraceViewer.tsx
6536
7293
  import * as React from "react";
6537
- import { useMemo as useMemo13 } from "react";
6538
- import { jsx as jsx27 } from "react/jsx-runtime";
7294
+ import { useMemo as useMemo15 } from "react";
7295
+ import { jsx as jsx28 } from "react/jsx-runtime";
6539
7296
  function parseTrace(input) {
6540
7297
  if (input == null) {
6541
7298
  return {
@@ -6598,11 +7355,11 @@ function TraceViewer({
6598
7355
  recorderViews,
6599
7356
  renderFlowchart
6600
7357
  }) {
6601
- const parsed = useMemo13(() => parseTrace(trace), [trace]);
7358
+ const parsed = useMemo15(() => parseTrace(trace), [trace]);
6602
7359
  React.useEffect(() => {
6603
7360
  if (!parsed.ok && onError) onError(parsed.error);
6604
7361
  }, [parsed, onError]);
6605
- const snapshots = useMemo13(() => {
7362
+ const snapshots = useMemo15(() => {
6606
7363
  if (!parsed.ok || !parsed.trace.snapshot) return [];
6607
7364
  try {
6608
7365
  return toVisualizationSnapshots(
@@ -6616,7 +7373,7 @@ function TraceViewer({
6616
7373
  if (!parsed.ok || snapshots.length === 0) {
6617
7374
  return fallback ?? null;
6618
7375
  }
6619
- return /* @__PURE__ */ jsx27(
7376
+ return /* @__PURE__ */ jsx28(
6620
7377
  ExplainableShell,
6621
7378
  {
6622
7379
  snapshots,
@@ -6652,13 +7409,16 @@ export {
6652
7409
  SubflowTree,
6653
7410
  TimeTravelControls,
6654
7411
  TraceViewer,
7412
+ TraceWalkCard,
6655
7413
  buildEntryRangeIndex,
7414
+ buildTraceWalk,
6656
7415
  computeRevealedEntryCount,
6657
7416
  coolDark,
6658
7417
  coolLight,
6659
7418
  createSnapshots,
6660
7419
  defaultTokens,
6661
7420
  extractSubflowNarrative,
7421
+ formatTraceWalk,
6662
7422
  mergeWritePatch,
6663
7423
  rawDefaults,
6664
7424
  subflowResultToSnapshots,