footprint-explainable-ui 0.14.11 → 0.16.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.cjs +782 -138
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -1
- package/dist/index.d.ts +66 -1
- package/dist/index.js +764 -124
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -20,9 +20,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
+
CompactTimeline: () => CompactTimeline,
|
|
24
|
+
DataTracePanel: () => DataTracePanel,
|
|
23
25
|
ExplainableShell: () => ExplainableShell,
|
|
24
26
|
FootprintTheme: () => FootprintTheme,
|
|
25
27
|
GanttTimeline: () => GanttTimeline,
|
|
28
|
+
InsightPanel: () => InsightPanel,
|
|
29
|
+
InspectorPanel: () => InspectorPanel,
|
|
26
30
|
MemoryInspector: () => MemoryInspector,
|
|
27
31
|
MemoryPanel: () => MemoryPanel,
|
|
28
32
|
NarrativeLog: () => NarrativeLog,
|
|
@@ -2257,7 +2261,7 @@ function TimeTravelControls({
|
|
|
2257
2261
|
}
|
|
2258
2262
|
|
|
2259
2263
|
// src/components/ExplainableShell/ExplainableShell.tsx
|
|
2260
|
-
var
|
|
2264
|
+
var import_react24 = require("react");
|
|
2261
2265
|
|
|
2262
2266
|
// src/utils/narrativeSync.ts
|
|
2263
2267
|
function buildEntryRangeIndex(entries) {
|
|
@@ -3997,22 +4001,520 @@ function TracedFlowchartView({
|
|
|
3997
4001
|
);
|
|
3998
4002
|
}
|
|
3999
4003
|
|
|
4000
|
-
// src/components/
|
|
4004
|
+
// src/components/InspectorPanel/InspectorPanel.tsx
|
|
4005
|
+
var import_react21 = require("react");
|
|
4006
|
+
|
|
4007
|
+
// src/components/DataTracePanel/DataTracePanel.tsx
|
|
4008
|
+
var import_react20 = require("react");
|
|
4001
4009
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
4002
|
-
var
|
|
4010
|
+
var DataTracePanel = (0, import_react20.memo)(function DataTracePanel2({
|
|
4011
|
+
frames,
|
|
4012
|
+
selectedStageId,
|
|
4013
|
+
onFrameClick,
|
|
4014
|
+
fromStageName
|
|
4015
|
+
}) {
|
|
4016
|
+
if (frames.length === 0) {
|
|
4017
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: "14px 14px 12px", fontSize: 13, lineHeight: 1.55 }, children: [
|
|
4018
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4019
|
+
"div",
|
|
4020
|
+
{
|
|
4021
|
+
style: {
|
|
4022
|
+
fontSize: 11,
|
|
4023
|
+
color: theme.textMuted,
|
|
4024
|
+
textTransform: "uppercase",
|
|
4025
|
+
letterSpacing: "0.5px",
|
|
4026
|
+
fontWeight: 600,
|
|
4027
|
+
marginBottom: 6
|
|
4028
|
+
},
|
|
4029
|
+
children: "Backward causal chain"
|
|
4030
|
+
}
|
|
4031
|
+
),
|
|
4032
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("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." }),
|
|
4033
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { color: theme.textMuted, fontSize: 12 }, children: "Select a stage above to see its dependency chain." })
|
|
4034
|
+
] });
|
|
4035
|
+
}
|
|
4036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: "8px 0", fontSize: 13 }, children: [
|
|
4037
|
+
fromStageName && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: "4px 12px 8px" }, children: [
|
|
4038
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4039
|
+
"div",
|
|
4040
|
+
{
|
|
4041
|
+
style: {
|
|
4042
|
+
fontSize: 11,
|
|
4043
|
+
color: theme.textMuted,
|
|
4044
|
+
textTransform: "uppercase",
|
|
4045
|
+
letterSpacing: "0.5px",
|
|
4046
|
+
fontWeight: 600
|
|
4047
|
+
},
|
|
4048
|
+
children: [
|
|
4049
|
+
"Data trace from ",
|
|
4050
|
+
fromStageName
|
|
4051
|
+
]
|
|
4052
|
+
}
|
|
4053
|
+
),
|
|
4054
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4055
|
+
"div",
|
|
4056
|
+
{
|
|
4057
|
+
style: {
|
|
4058
|
+
fontSize: 11,
|
|
4059
|
+
color: theme.textMuted,
|
|
4060
|
+
fontStyle: "italic",
|
|
4061
|
+
marginTop: 3
|
|
4062
|
+
},
|
|
4063
|
+
children: "Every value here was derived from the stages below."
|
|
4064
|
+
}
|
|
4065
|
+
)
|
|
4066
|
+
] }),
|
|
4067
|
+
frames.map((frame, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4068
|
+
DataTraceFrame,
|
|
4069
|
+
{
|
|
4070
|
+
frame,
|
|
4071
|
+
isFirst: i === 0,
|
|
4072
|
+
isLast: i === frames.length - 1,
|
|
4073
|
+
isSelected: frame.runtimeStageId === selectedStageId,
|
|
4074
|
+
onClick: onFrameClick
|
|
4075
|
+
},
|
|
4076
|
+
frame.runtimeStageId
|
|
4077
|
+
))
|
|
4078
|
+
] });
|
|
4079
|
+
});
|
|
4080
|
+
var DataTraceFrame = (0, import_react20.memo)(function DataTraceFrame2({
|
|
4081
|
+
frame,
|
|
4082
|
+
isFirst,
|
|
4083
|
+
isLast,
|
|
4084
|
+
isSelected,
|
|
4085
|
+
onClick
|
|
4086
|
+
}) {
|
|
4087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4088
|
+
"button",
|
|
4089
|
+
{
|
|
4090
|
+
onClick: () => onClick?.(frame.runtimeStageId),
|
|
4091
|
+
style: {
|
|
4092
|
+
display: "block",
|
|
4093
|
+
width: "100%",
|
|
4094
|
+
textAlign: "left",
|
|
4095
|
+
border: "none",
|
|
4096
|
+
background: isSelected ? "var(--fp-accent-bg, rgba(99,102,241,0.12))" : "transparent",
|
|
4097
|
+
padding: "6px 12px 6px 16px",
|
|
4098
|
+
cursor: onClick ? "pointer" : "default",
|
|
4099
|
+
borderLeft: isSelected ? "3px solid var(--fp-accent, #6366f1)" : "3px solid transparent",
|
|
4100
|
+
color: "inherit",
|
|
4101
|
+
fontSize: 13
|
|
4102
|
+
},
|
|
4103
|
+
children: [
|
|
4104
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
4105
|
+
!isFirst && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { color: theme.textMuted, fontSize: 11 }, children: "\u2191" }),
|
|
4106
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4107
|
+
"span",
|
|
4108
|
+
{
|
|
4109
|
+
style: {
|
|
4110
|
+
fontWeight: isFirst ? 600 : 400,
|
|
4111
|
+
color: isFirst ? "var(--fp-accent, #6366f1)" : theme.textPrimary
|
|
4112
|
+
},
|
|
4113
|
+
children: frame.stageName
|
|
4114
|
+
}
|
|
4115
|
+
),
|
|
4116
|
+
isLast && !isFirst && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4117
|
+
"span",
|
|
4118
|
+
{
|
|
4119
|
+
style: {
|
|
4120
|
+
fontSize: 10,
|
|
4121
|
+
color: theme.textMuted,
|
|
4122
|
+
fontStyle: "italic"
|
|
4123
|
+
},
|
|
4124
|
+
children: "(origin)"
|
|
4125
|
+
}
|
|
4126
|
+
)
|
|
4127
|
+
] }),
|
|
4128
|
+
frame.keysWritten.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4129
|
+
"div",
|
|
4130
|
+
{
|
|
4131
|
+
style: {
|
|
4132
|
+
fontSize: 11,
|
|
4133
|
+
color: theme.textMuted,
|
|
4134
|
+
paddingLeft: isFirst ? 0 : 18,
|
|
4135
|
+
marginTop: 2
|
|
4136
|
+
},
|
|
4137
|
+
children: [
|
|
4138
|
+
"wrote:",
|
|
4139
|
+
" ",
|
|
4140
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { color: theme.textSecondary }, children: frame.keysWritten.join(", ") })
|
|
4141
|
+
]
|
|
4142
|
+
}
|
|
4143
|
+
),
|
|
4144
|
+
frame.linkedBy && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4145
|
+
"div",
|
|
4146
|
+
{
|
|
4147
|
+
style: {
|
|
4148
|
+
fontSize: 11,
|
|
4149
|
+
color: "var(--fp-accent, #6366f1)",
|
|
4150
|
+
paddingLeft: 18,
|
|
4151
|
+
marginTop: 1
|
|
4152
|
+
},
|
|
4153
|
+
children: [
|
|
4154
|
+
"\u2190 via ",
|
|
4155
|
+
frame.linkedBy
|
|
4156
|
+
]
|
|
4157
|
+
}
|
|
4158
|
+
)
|
|
4159
|
+
]
|
|
4160
|
+
}
|
|
4161
|
+
);
|
|
4162
|
+
});
|
|
4163
|
+
|
|
4164
|
+
// src/components/InspectorPanel/InspectorPanel.tsx
|
|
4165
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4166
|
+
var InspectorPanel = (0, import_react21.memo)(function InspectorPanel2({
|
|
4167
|
+
snapshots,
|
|
4168
|
+
selectedIndex,
|
|
4169
|
+
dataTraceFrames,
|
|
4170
|
+
selectedStageId,
|
|
4171
|
+
onNavigateToStage
|
|
4172
|
+
}) {
|
|
4173
|
+
const [tab, setTab] = (0, import_react21.useState)("state");
|
|
4174
|
+
const currentSnapshot = snapshots[selectedIndex];
|
|
4175
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4176
|
+
"div",
|
|
4177
|
+
{
|
|
4178
|
+
style: {
|
|
4179
|
+
display: "flex",
|
|
4180
|
+
flexDirection: "column",
|
|
4181
|
+
height: "100%",
|
|
4182
|
+
overflow: "hidden"
|
|
4183
|
+
},
|
|
4184
|
+
children: [
|
|
4185
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4186
|
+
"div",
|
|
4187
|
+
{
|
|
4188
|
+
style: {
|
|
4189
|
+
display: "flex",
|
|
4190
|
+
borderBottom: `1px solid ${theme.border}`,
|
|
4191
|
+
flexShrink: 0
|
|
4192
|
+
},
|
|
4193
|
+
children: [
|
|
4194
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4195
|
+
TabButton,
|
|
4196
|
+
{
|
|
4197
|
+
active: tab === "state",
|
|
4198
|
+
onClick: () => setTab("state"),
|
|
4199
|
+
label: "State"
|
|
4200
|
+
}
|
|
4201
|
+
),
|
|
4202
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4203
|
+
TabButton,
|
|
4204
|
+
{
|
|
4205
|
+
active: tab === "trace",
|
|
4206
|
+
onClick: () => setTab("trace"),
|
|
4207
|
+
label: "Data Trace",
|
|
4208
|
+
badge: dataTraceFrames.length > 0 ? String(dataTraceFrames.length) : void 0
|
|
4209
|
+
}
|
|
4210
|
+
)
|
|
4211
|
+
]
|
|
4212
|
+
}
|
|
4213
|
+
),
|
|
4214
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { flex: 1, overflow: "auto" }, children: [
|
|
4215
|
+
tab === "state" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4216
|
+
MemoryPanel,
|
|
4217
|
+
{
|
|
4218
|
+
snapshots,
|
|
4219
|
+
selectedIndex
|
|
4220
|
+
}
|
|
4221
|
+
),
|
|
4222
|
+
tab === "trace" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4223
|
+
DataTracePanel,
|
|
4224
|
+
{
|
|
4225
|
+
frames: dataTraceFrames,
|
|
4226
|
+
selectedStageId,
|
|
4227
|
+
onFrameClick: onNavigateToStage,
|
|
4228
|
+
fromStageName: currentSnapshot?.stageName
|
|
4229
|
+
}
|
|
4230
|
+
)
|
|
4231
|
+
] })
|
|
4232
|
+
]
|
|
4233
|
+
}
|
|
4234
|
+
);
|
|
4235
|
+
});
|
|
4236
|
+
function TabButton({
|
|
4237
|
+
active,
|
|
4238
|
+
onClick,
|
|
4239
|
+
label,
|
|
4240
|
+
badge
|
|
4241
|
+
}) {
|
|
4242
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4243
|
+
"button",
|
|
4244
|
+
{
|
|
4245
|
+
onClick,
|
|
4246
|
+
style: {
|
|
4247
|
+
padding: "8px 14px",
|
|
4248
|
+
border: "none",
|
|
4249
|
+
borderBottom: active ? "2px solid var(--fp-accent, #6366f1)" : "2px solid transparent",
|
|
4250
|
+
background: "transparent",
|
|
4251
|
+
color: active ? "var(--fp-accent, #6366f1)" : theme.textMuted,
|
|
4252
|
+
fontWeight: active ? 600 : 400,
|
|
4253
|
+
fontSize: 12,
|
|
4254
|
+
cursor: "pointer",
|
|
4255
|
+
display: "flex",
|
|
4256
|
+
alignItems: "center",
|
|
4257
|
+
gap: 4
|
|
4258
|
+
},
|
|
4259
|
+
children: [
|
|
4260
|
+
label,
|
|
4261
|
+
badge && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4262
|
+
"span",
|
|
4263
|
+
{
|
|
4264
|
+
style: {
|
|
4265
|
+
fontSize: 10,
|
|
4266
|
+
background: active ? "var(--fp-accent, #6366f1)" : theme.textMuted,
|
|
4267
|
+
color: "#fff",
|
|
4268
|
+
borderRadius: 8,
|
|
4269
|
+
padding: "1px 5px",
|
|
4270
|
+
fontWeight: 600
|
|
4271
|
+
},
|
|
4272
|
+
children: badge
|
|
4273
|
+
}
|
|
4274
|
+
)
|
|
4275
|
+
]
|
|
4276
|
+
}
|
|
4277
|
+
);
|
|
4278
|
+
}
|
|
4279
|
+
|
|
4280
|
+
// src/components/InsightPanel/InsightPanel.tsx
|
|
4281
|
+
var import_react22 = require("react");
|
|
4282
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4283
|
+
var InsightPanel = (0, import_react22.memo)(function InsightPanel2({
|
|
4284
|
+
insights,
|
|
4285
|
+
expandedId,
|
|
4286
|
+
mode
|
|
4287
|
+
}) {
|
|
4288
|
+
if (insights.length === 0) {
|
|
4289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { padding: 12, color: theme.textMuted, fontSize: 13 }, children: "No insights available. Attach recorders to see data." });
|
|
4290
|
+
}
|
|
4291
|
+
if (mode === "grid") {
|
|
4292
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InsightGrid, { insights });
|
|
4293
|
+
}
|
|
4294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InsightTabs, { insights, defaultId: expandedId });
|
|
4295
|
+
});
|
|
4296
|
+
var InsightTabs = (0, import_react22.memo)(function InsightTabs2({
|
|
4297
|
+
insights,
|
|
4298
|
+
defaultId
|
|
4299
|
+
}) {
|
|
4300
|
+
const [activeId, setActiveId] = (0, import_react22.useState)(defaultId ?? insights[0]?.id);
|
|
4301
|
+
const active = insights.find((i) => i.id === activeId) ?? insights[0];
|
|
4302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4303
|
+
"div",
|
|
4304
|
+
{
|
|
4305
|
+
style: {
|
|
4306
|
+
display: "flex",
|
|
4307
|
+
flexDirection: "column",
|
|
4308
|
+
height: "100%",
|
|
4309
|
+
overflow: "hidden"
|
|
4310
|
+
},
|
|
4311
|
+
children: [
|
|
4312
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4313
|
+
"div",
|
|
4314
|
+
{
|
|
4315
|
+
style: {
|
|
4316
|
+
display: "flex",
|
|
4317
|
+
borderBottom: `1px solid ${theme.border}`,
|
|
4318
|
+
flexShrink: 0,
|
|
4319
|
+
overflowX: "auto"
|
|
4320
|
+
},
|
|
4321
|
+
children: insights.map((insight) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4322
|
+
"button",
|
|
4323
|
+
{
|
|
4324
|
+
onClick: () => setActiveId(insight.id),
|
|
4325
|
+
style: {
|
|
4326
|
+
padding: "8px 12px",
|
|
4327
|
+
border: "none",
|
|
4328
|
+
borderBottom: activeId === insight.id ? "2px solid var(--fp-accent, #6366f1)" : "2px solid transparent",
|
|
4329
|
+
background: "transparent",
|
|
4330
|
+
color: activeId === insight.id ? "var(--fp-accent, #6366f1)" : theme.textMuted,
|
|
4331
|
+
fontWeight: activeId === insight.id ? 600 : 400,
|
|
4332
|
+
fontSize: 12,
|
|
4333
|
+
cursor: "pointer",
|
|
4334
|
+
whiteSpace: "nowrap"
|
|
4335
|
+
},
|
|
4336
|
+
children: insight.name
|
|
4337
|
+
},
|
|
4338
|
+
insight.id
|
|
4339
|
+
))
|
|
4340
|
+
}
|
|
4341
|
+
),
|
|
4342
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: active?.render() })
|
|
4343
|
+
]
|
|
4344
|
+
}
|
|
4345
|
+
);
|
|
4346
|
+
});
|
|
4347
|
+
var InsightGrid = (0, import_react22.memo)(function InsightGrid2({
|
|
4348
|
+
insights
|
|
4349
|
+
}) {
|
|
4350
|
+
const cols = insights.length <= 2 ? 1 : 2;
|
|
4351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4352
|
+
"div",
|
|
4353
|
+
{
|
|
4354
|
+
style: {
|
|
4355
|
+
display: "grid",
|
|
4356
|
+
gridTemplateColumns: `repeat(${cols}, 1fr)`,
|
|
4357
|
+
height: "100%",
|
|
4358
|
+
overflow: "auto",
|
|
4359
|
+
gap: 1,
|
|
4360
|
+
background: theme.border
|
|
4361
|
+
},
|
|
4362
|
+
children: insights.map((insight) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4363
|
+
"div",
|
|
4364
|
+
{
|
|
4365
|
+
style: {
|
|
4366
|
+
background: "var(--fp-bg, #1a1b26)",
|
|
4367
|
+
display: "flex",
|
|
4368
|
+
flexDirection: "column",
|
|
4369
|
+
overflow: "hidden"
|
|
4370
|
+
},
|
|
4371
|
+
children: [
|
|
4372
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4373
|
+
"div",
|
|
4374
|
+
{
|
|
4375
|
+
style: {
|
|
4376
|
+
padding: "6px 10px",
|
|
4377
|
+
fontSize: 11,
|
|
4378
|
+
fontWeight: 600,
|
|
4379
|
+
color: theme.textMuted,
|
|
4380
|
+
textTransform: "uppercase",
|
|
4381
|
+
letterSpacing: "0.5px",
|
|
4382
|
+
borderBottom: `1px solid ${theme.border}`,
|
|
4383
|
+
flexShrink: 0
|
|
4384
|
+
},
|
|
4385
|
+
children: [
|
|
4386
|
+
insight.name,
|
|
4387
|
+
insight.summary && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4388
|
+
"span",
|
|
4389
|
+
{
|
|
4390
|
+
style: {
|
|
4391
|
+
marginLeft: 8,
|
|
4392
|
+
fontWeight: 400,
|
|
4393
|
+
fontSize: 10,
|
|
4394
|
+
color: theme.textMuted
|
|
4395
|
+
},
|
|
4396
|
+
children: insight.summary
|
|
4397
|
+
}
|
|
4398
|
+
)
|
|
4399
|
+
]
|
|
4400
|
+
}
|
|
4401
|
+
),
|
|
4402
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: insight.render() })
|
|
4403
|
+
]
|
|
4404
|
+
},
|
|
4405
|
+
insight.id
|
|
4406
|
+
))
|
|
4407
|
+
}
|
|
4408
|
+
);
|
|
4409
|
+
});
|
|
4410
|
+
|
|
4411
|
+
// src/components/CompactTimeline/CompactTimeline.tsx
|
|
4412
|
+
var import_react23 = require("react");
|
|
4413
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4414
|
+
var CompactTimeline = (0, import_react23.memo)(function CompactTimeline2({
|
|
4415
|
+
snapshots,
|
|
4416
|
+
selectedIndex,
|
|
4417
|
+
defaultExpanded = false
|
|
4418
|
+
}) {
|
|
4419
|
+
const [expanded, setExpanded] = (0, import_react23.useState)(defaultExpanded);
|
|
4420
|
+
if (snapshots.length === 0) return null;
|
|
4421
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { borderTop: `1px solid ${theme.border}` }, children: [
|
|
4422
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4423
|
+
"button",
|
|
4424
|
+
{
|
|
4425
|
+
onClick: () => setExpanded((e) => !e),
|
|
4426
|
+
style: {
|
|
4427
|
+
width: "100%",
|
|
4428
|
+
display: "flex",
|
|
4429
|
+
alignItems: "center",
|
|
4430
|
+
gap: 8,
|
|
4431
|
+
padding: "6px 12px",
|
|
4432
|
+
border: "none",
|
|
4433
|
+
background: "transparent",
|
|
4434
|
+
cursor: "pointer",
|
|
4435
|
+
fontSize: 11,
|
|
4436
|
+
color: theme.textMuted,
|
|
4437
|
+
fontWeight: 600,
|
|
4438
|
+
textTransform: "uppercase",
|
|
4439
|
+
letterSpacing: "0.5px"
|
|
4440
|
+
},
|
|
4441
|
+
children: [
|
|
4442
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 10 }, children: expanded ? "\u25BC" : "\u25B8" }),
|
|
4443
|
+
"Timeline",
|
|
4444
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontWeight: 400, fontSize: 10 }, children: [
|
|
4445
|
+
snapshots.length,
|
|
4446
|
+
" stages"
|
|
4447
|
+
] }),
|
|
4448
|
+
!expanded && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4449
|
+
"div",
|
|
4450
|
+
{
|
|
4451
|
+
style: {
|
|
4452
|
+
flex: 1,
|
|
4453
|
+
display: "flex",
|
|
4454
|
+
alignItems: "center",
|
|
4455
|
+
gap: 2,
|
|
4456
|
+
marginLeft: 8
|
|
4457
|
+
},
|
|
4458
|
+
children: [
|
|
4459
|
+
snapshots.map((snap, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4460
|
+
"div",
|
|
4461
|
+
{
|
|
4462
|
+
style: {
|
|
4463
|
+
width: i === selectedIndex ? 8 : 5,
|
|
4464
|
+
height: i === selectedIndex ? 8 : 5,
|
|
4465
|
+
borderRadius: "50%",
|
|
4466
|
+
background: i < selectedIndex ? "var(--fp-success, #22c55e)" : i === selectedIndex ? "var(--fp-accent, #6366f1)" : theme.textMuted + "40",
|
|
4467
|
+
transition: "all 0.15s",
|
|
4468
|
+
flexShrink: 0
|
|
4469
|
+
},
|
|
4470
|
+
title: snap.stageName
|
|
4471
|
+
},
|
|
4472
|
+
i
|
|
4473
|
+
)),
|
|
4474
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4475
|
+
"div",
|
|
4476
|
+
{
|
|
4477
|
+
style: {
|
|
4478
|
+
flex: 1,
|
|
4479
|
+
height: 1,
|
|
4480
|
+
background: theme.textMuted + "30",
|
|
4481
|
+
marginLeft: -2,
|
|
4482
|
+
marginRight: 4
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4485
|
+
)
|
|
4486
|
+
]
|
|
4487
|
+
}
|
|
4488
|
+
)
|
|
4489
|
+
]
|
|
4490
|
+
}
|
|
4491
|
+
),
|
|
4492
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { padding: "0 12px 8px" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4493
|
+
GanttTimeline,
|
|
4494
|
+
{
|
|
4495
|
+
snapshots,
|
|
4496
|
+
selectedIndex
|
|
4497
|
+
}
|
|
4498
|
+
) })
|
|
4499
|
+
] });
|
|
4500
|
+
});
|
|
4501
|
+
|
|
4502
|
+
// src/components/ExplainableShell/ExplainableShell.tsx
|
|
4503
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4504
|
+
var HLinePill = (0, import_react24.memo)(function HLinePill2({
|
|
4003
4505
|
label,
|
|
4004
4506
|
detail,
|
|
4005
4507
|
expanded,
|
|
4006
4508
|
onClick
|
|
4007
4509
|
}) {
|
|
4008
|
-
return /* @__PURE__ */ (0,
|
|
4510
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: {
|
|
4009
4511
|
display: "flex",
|
|
4010
4512
|
alignItems: "center",
|
|
4011
4513
|
gap: 0,
|
|
4012
4514
|
padding: "0"
|
|
4013
4515
|
}, children: [
|
|
4014
|
-
/* @__PURE__ */ (0,
|
|
4015
|
-
/* @__PURE__ */ (0,
|
|
4516
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, height: 1, background: theme.border } }),
|
|
4517
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4016
4518
|
"button",
|
|
4017
4519
|
{
|
|
4018
4520
|
onClick,
|
|
@@ -4036,31 +4538,31 @@ var HLinePill = (0, import_react20.memo)(function HLinePill2({
|
|
|
4036
4538
|
transition: "color 0.15s ease"
|
|
4037
4539
|
},
|
|
4038
4540
|
children: [
|
|
4039
|
-
/* @__PURE__ */ (0,
|
|
4541
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 7 }, children: expanded ? "\u25BC" : "\u25B6" }),
|
|
4040
4542
|
label,
|
|
4041
|
-
detail && /* @__PURE__ */ (0,
|
|
4543
|
+
detail && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontWeight: 400, opacity: 0.5, fontSize: 9 }, children: detail })
|
|
4042
4544
|
]
|
|
4043
4545
|
}
|
|
4044
4546
|
),
|
|
4045
|
-
/* @__PURE__ */ (0,
|
|
4547
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, height: 1, background: theme.border } })
|
|
4046
4548
|
] });
|
|
4047
4549
|
});
|
|
4048
|
-
var VLinePill = (0,
|
|
4550
|
+
var VLinePill = (0, import_react24.memo)(function VLinePill2({
|
|
4049
4551
|
label,
|
|
4050
4552
|
expanded,
|
|
4051
4553
|
side = "right",
|
|
4052
4554
|
onClick
|
|
4053
4555
|
}) {
|
|
4054
4556
|
const arrow = side === "right" ? expanded ? "\u25B6" : "\u25C0" : expanded ? "\u25C0" : "\u25B6";
|
|
4055
|
-
return /* @__PURE__ */ (0,
|
|
4557
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: {
|
|
4056
4558
|
display: "flex",
|
|
4057
4559
|
flexDirection: "column",
|
|
4058
4560
|
alignItems: "center",
|
|
4059
4561
|
gap: 0,
|
|
4060
4562
|
padding: "0"
|
|
4061
4563
|
}, children: [
|
|
4062
|
-
/* @__PURE__ */ (0,
|
|
4063
|
-
/* @__PURE__ */ (0,
|
|
4564
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, width: 1, background: theme.border } }),
|
|
4565
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4064
4566
|
"button",
|
|
4065
4567
|
{
|
|
4066
4568
|
onClick,
|
|
@@ -4085,12 +4587,12 @@ var VLinePill = (0, import_react20.memo)(function VLinePill2({
|
|
|
4085
4587
|
transition: "color 0.15s ease"
|
|
4086
4588
|
},
|
|
4087
4589
|
children: [
|
|
4088
|
-
/* @__PURE__ */ (0,
|
|
4590
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 7, writingMode: "horizontal-tb" }, children: arrow }),
|
|
4089
4591
|
label
|
|
4090
4592
|
]
|
|
4091
4593
|
}
|
|
4092
4594
|
),
|
|
4093
|
-
/* @__PURE__ */ (0,
|
|
4595
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, width: 1, background: theme.border } })
|
|
4094
4596
|
] });
|
|
4095
4597
|
});
|
|
4096
4598
|
function detectKeyedSteps(data) {
|
|
@@ -4127,9 +4629,9 @@ function KeyedRecorderView({
|
|
|
4127
4629
|
snapshots,
|
|
4128
4630
|
selectedIndex
|
|
4129
4631
|
}) {
|
|
4130
|
-
const [showAggregate, setShowAggregate] = (0,
|
|
4131
|
-
const detected = (0,
|
|
4132
|
-
const visibleKeys = (0,
|
|
4632
|
+
const [showAggregate, setShowAggregate] = (0, import_react24.useState)(false);
|
|
4633
|
+
const detected = (0, import_react24.useMemo)(() => detectKeyedSteps(data), [data]);
|
|
4634
|
+
const visibleKeys = (0, import_react24.useMemo)(() => {
|
|
4133
4635
|
const keys = /* @__PURE__ */ new Set();
|
|
4134
4636
|
for (let i = 0; i <= selectedIndex && i < snapshots.length; i++) {
|
|
4135
4637
|
const snap = snapshots[i];
|
|
@@ -4144,7 +4646,7 @@ function KeyedRecorderView({
|
|
|
4144
4646
|
}, [snapshots, selectedIndex, detected?.keyType]);
|
|
4145
4647
|
const isAtEnd = selectedIndex >= snapshots.length - 1;
|
|
4146
4648
|
if (!detected) {
|
|
4147
|
-
return /* @__PURE__ */ (0,
|
|
4649
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("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) });
|
|
4148
4650
|
}
|
|
4149
4651
|
const steps = detected.steps;
|
|
4150
4652
|
const hints = extractRenderHints(data);
|
|
@@ -4158,13 +4660,13 @@ function KeyedRecorderView({
|
|
|
4158
4660
|
}
|
|
4159
4661
|
}
|
|
4160
4662
|
const grandTotal = hints?.grandTotal ?? 0;
|
|
4161
|
-
return /* @__PURE__ */ (0,
|
|
4162
|
-
description && /* @__PURE__ */ (0,
|
|
4163
|
-
/* @__PURE__ */ (0,
|
|
4663
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { overflow: "auto", height: "100%", display: "flex", flexDirection: "column" }, children: [
|
|
4664
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { padding: "6px 12px", fontSize: 11, color: theme.textMuted, fontStyle: "italic", borderBottom: `1px solid ${theme.border}`, flexShrink: 0 }, children: description }),
|
|
4665
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: 12, flex: 1, overflow: "auto" }, children: [
|
|
4164
4666
|
preferredOperation === "aggregate" ? (
|
|
4165
4667
|
/* AGGREGATE: collect silently during scrub, button at end to reveal total */
|
|
4166
|
-
/* @__PURE__ */ (0,
|
|
4167
|
-
isAtEnd ? /* @__PURE__ */ (0,
|
|
4668
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4669
|
+
isAtEnd ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { marginBottom: 16 }, children: !showAggregate ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4168
4670
|
"button",
|
|
4169
4671
|
{
|
|
4170
4672
|
onClick: () => setShowAggregate(true),
|
|
@@ -4182,35 +4684,35 @@ function KeyedRecorderView({
|
|
|
4182
4684
|
},
|
|
4183
4685
|
children: "Aggregate \u2014 Show Grand Total"
|
|
4184
4686
|
}
|
|
4185
|
-
) : /* @__PURE__ */ (0,
|
|
4186
|
-
/* @__PURE__ */ (0,
|
|
4187
|
-
numFieldKey && /* @__PURE__ */ (0,
|
|
4687
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "14px 16px", background: `color-mix(in srgb, ${theme.success} 12%, transparent)`, borderRadius: 8, border: `1px solid ${theme.success}44` }, children: [
|
|
4688
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Aggregate \u2014 grand total" }),
|
|
4689
|
+
numFieldKey && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: 26, fontWeight: 700, color: theme.success }, children: [
|
|
4188
4690
|
grandTotal < 1 ? grandTotal.toFixed(3) : grandTotal.toFixed(1),
|
|
4189
|
-
/* @__PURE__ */ (0,
|
|
4691
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 11, color: theme.textMuted, fontWeight: 400, marginLeft: 8 }, children: [
|
|
4190
4692
|
numFieldKey,
|
|
4191
4693
|
" \xB7 ",
|
|
4192
4694
|
allKeys.length,
|
|
4193
4695
|
" steps"
|
|
4194
4696
|
] })
|
|
4195
4697
|
] })
|
|
4196
|
-
] }) }) : /* @__PURE__ */ (0,
|
|
4197
|
-
/* @__PURE__ */ (0,
|
|
4198
|
-
/* @__PURE__ */ (0,
|
|
4698
|
+
] }) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "10px 14px", background: `color-mix(in srgb, ${theme.textMuted} 6%, transparent)`, borderRadius: 6, marginBottom: 16, border: `1px dashed ${theme.border}` }, children: [
|
|
4699
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 600 }, children: "Collecting data..." }),
|
|
4700
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: 11, color: theme.textMuted, marginTop: 4 }, children: [
|
|
4199
4701
|
visibleEntries.length,
|
|
4200
4702
|
" of ",
|
|
4201
4703
|
allKeys.length,
|
|
4202
4704
|
" steps collected. Scrub to end to aggregate."
|
|
4203
4705
|
] })
|
|
4204
4706
|
] }),
|
|
4205
|
-
/* @__PURE__ */ (0,
|
|
4707
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Per-step detail" })
|
|
4206
4708
|
] })
|
|
4207
4709
|
) : preferredOperation === "accumulate" ? (
|
|
4208
4710
|
/* ACCUMULATE: running total grows with slider — IS the total at end, no button */
|
|
4209
|
-
/* @__PURE__ */ (0,
|
|
4210
|
-
numFieldKey && visibleEntries.length > 0 && /* @__PURE__ */ (0,
|
|
4211
|
-
/* @__PURE__ */ (0,
|
|
4212
|
-
/* @__PURE__ */ (0,
|
|
4213
|
-
/* @__PURE__ */ (0,
|
|
4711
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4712
|
+
numFieldKey && visibleEntries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: "10px 14px", background: `color-mix(in srgb, ${theme.primary} 8%, transparent)`, borderRadius: 6, marginBottom: 16 }, children: [
|
|
4713
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("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" }),
|
|
4714
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontWeight: 700, fontSize: 18, color: theme.primary }, children: runningTotal < 1 ? runningTotal.toFixed(3) : runningTotal.toFixed(1) }),
|
|
4715
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { color: theme.textMuted, marginLeft: 8, fontSize: 10 }, children: [
|
|
4214
4716
|
numFieldKey,
|
|
4215
4717
|
" \xB7 ",
|
|
4216
4718
|
visibleEntries.length,
|
|
@@ -4219,27 +4721,27 @@ function KeyedRecorderView({
|
|
|
4219
4721
|
" steps"
|
|
4220
4722
|
] })
|
|
4221
4723
|
] }),
|
|
4222
|
-
/* @__PURE__ */ (0,
|
|
4724
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Per-step detail" })
|
|
4223
4725
|
] })
|
|
4224
4726
|
) : (
|
|
4225
4727
|
/* TRANSLATE: per-step entries prominent, no totals */
|
|
4226
|
-
/* @__PURE__ */ (0,
|
|
4728
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6, fontWeight: 600 }, children: "Translate \u2014 per-step detail" })
|
|
4227
4729
|
),
|
|
4228
4730
|
visibleEntries.map((key) => {
|
|
4229
4731
|
const entry = steps[key];
|
|
4230
4732
|
const label = entry.stageName ?? key;
|
|
4231
4733
|
const numVal = numFieldKey ? entry[numFieldKey] : void 0;
|
|
4232
|
-
return /* @__PURE__ */ (0,
|
|
4233
|
-
/* @__PURE__ */ (0,
|
|
4234
|
-
/* @__PURE__ */ (0,
|
|
4235
|
-
numVal !== void 0 && /* @__PURE__ */ (0,
|
|
4734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", alignItems: "center", padding: "4px 0", fontSize: 12, fontFamily: theme.fontMono, borderBottom: `1px solid ${theme.border}22` }, children: [
|
|
4735
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { color: theme.textMuted, width: 140, flexShrink: 0, fontSize: 10 }, children: key }),
|
|
4736
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontWeight: 600, flex: 1 }, children: label }),
|
|
4737
|
+
numVal !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { color: theme.primary, fontWeight: 700, marginLeft: 8 }, children: numVal < 1 ? numVal.toFixed(3) : numVal.toFixed(1) })
|
|
4236
4738
|
] }, key);
|
|
4237
4739
|
}),
|
|
4238
|
-
visibleEntries.length === 0 && /* @__PURE__ */ (0,
|
|
4740
|
+
visibleEntries.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { color: theme.textMuted, fontSize: 11, fontStyle: "italic", padding: "8px 0" }, children: "Scrub the slider to reveal entries..." })
|
|
4239
4741
|
] })
|
|
4240
4742
|
] });
|
|
4241
4743
|
}
|
|
4242
|
-
var DetailsContent = (0,
|
|
4744
|
+
var DetailsContent = (0, import_react24.memo)(function DetailsContent2({
|
|
4243
4745
|
snapshots,
|
|
4244
4746
|
selectedIndex,
|
|
4245
4747
|
narrativeEntries,
|
|
@@ -4252,27 +4754,27 @@ var DetailsContent = (0, import_react20.memo)(function DetailsContent2({
|
|
|
4252
4754
|
{
|
|
4253
4755
|
id: "memory",
|
|
4254
4756
|
name: "Memory",
|
|
4255
|
-
render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ (0,
|
|
4757
|
+
render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MemoryPanel, { snapshots: snaps, selectedIndex: idx, size, style: fillHeight ? { height: "100%" } : void 0 })
|
|
4256
4758
|
},
|
|
4257
4759
|
{
|
|
4258
4760
|
id: "narrative",
|
|
4259
4761
|
name: "Narrative",
|
|
4260
|
-
render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ (0,
|
|
4762
|
+
render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(NarrativePanel, { snapshots: snaps, selectedIndex: idx, narrativeEntries, narrative, size, style: fillHeight ? { height: "100%" } : void 0 })
|
|
4261
4763
|
}
|
|
4262
4764
|
];
|
|
4263
4765
|
const allViews = [...builtInViews, ...extraViews ?? []];
|
|
4264
|
-
const [activeViewId, setActiveViewId] = (0,
|
|
4766
|
+
const [activeViewId, setActiveViewId] = (0, import_react24.useState)(allViews[0]?.id ?? "memory");
|
|
4265
4767
|
const viewIds = allViews.map((v2) => v2.id).join(",");
|
|
4266
|
-
(0,
|
|
4768
|
+
(0, import_react24.useEffect)(() => {
|
|
4267
4769
|
if (!allViews.find((v2) => v2.id === activeViewId)) {
|
|
4268
4770
|
setActiveViewId(allViews[0]?.id ?? "memory");
|
|
4269
4771
|
}
|
|
4270
4772
|
}, [viewIds]);
|
|
4271
4773
|
const activeView = allViews.find((v2) => v2.id === activeViewId) ?? allViews[0];
|
|
4272
|
-
return /* @__PURE__ */ (0,
|
|
4273
|
-
/* @__PURE__ */ (0,
|
|
4774
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: [
|
|
4775
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { display: "flex", borderBottom: `1px solid ${theme.border}`, flexShrink: 0, overflowX: "auto" }, children: allViews.map((view) => {
|
|
4274
4776
|
const active = view.id === activeViewId;
|
|
4275
|
-
return /* @__PURE__ */ (0,
|
|
4777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4276
4778
|
"button",
|
|
4277
4779
|
{
|
|
4278
4780
|
onClick: () => setActiveViewId(view.id),
|
|
@@ -4296,7 +4798,7 @@ var DetailsContent = (0, import_react20.memo)(function DetailsContent2({
|
|
|
4296
4798
|
view.id
|
|
4297
4799
|
);
|
|
4298
4800
|
}) }),
|
|
4299
|
-
/* @__PURE__ */ (0,
|
|
4801
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: activeView?.render({ snapshots, selectedIndex }) })
|
|
4300
4802
|
] });
|
|
4301
4803
|
});
|
|
4302
4804
|
function resolveSubflowLevel(parentSpec, parentSnapshots, subflowNodeName, narrativeEntries) {
|
|
@@ -4336,8 +4838,125 @@ function hasSubflowNodes(node) {
|
|
|
4336
4838
|
if (node.next && hasSubflowNodes(node.next)) return true;
|
|
4337
4839
|
return false;
|
|
4338
4840
|
}
|
|
4841
|
+
function buildDataTrace(commitLog, targetRuntimeStageId, maxDepth = 10) {
|
|
4842
|
+
const log = commitLog;
|
|
4843
|
+
if (!log?.length) return [];
|
|
4844
|
+
const idxMap = /* @__PURE__ */ new Map();
|
|
4845
|
+
for (let i = 0; i < log.length; i++) idxMap.set(log[i].runtimeStageId, i);
|
|
4846
|
+
const startIdx = idxMap.get(targetRuntimeStageId);
|
|
4847
|
+
if (startIdx === void 0) return [];
|
|
4848
|
+
const startCommit = log[startIdx];
|
|
4849
|
+
const frames = [];
|
|
4850
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4851
|
+
let current = startCommit;
|
|
4852
|
+
let currentIdx = startIdx;
|
|
4853
|
+
let depth = 0;
|
|
4854
|
+
while (current && depth <= maxDepth) {
|
|
4855
|
+
if (visited.has(current.runtimeStageId)) break;
|
|
4856
|
+
visited.add(current.runtimeStageId);
|
|
4857
|
+
frames.push({
|
|
4858
|
+
runtimeStageId: current.runtimeStageId,
|
|
4859
|
+
stageId: current.stageId,
|
|
4860
|
+
stageName: current.stage,
|
|
4861
|
+
keysWritten: current.trace.map((t) => t.path),
|
|
4862
|
+
linkedBy: depth === 0 ? "" : current.trace[0]?.path ?? "",
|
|
4863
|
+
depth
|
|
4864
|
+
});
|
|
4865
|
+
if (currentIdx > 0) {
|
|
4866
|
+
currentIdx--;
|
|
4867
|
+
current = log[currentIdx];
|
|
4868
|
+
depth++;
|
|
4869
|
+
} else {
|
|
4870
|
+
break;
|
|
4871
|
+
}
|
|
4872
|
+
}
|
|
4873
|
+
return frames;
|
|
4874
|
+
}
|
|
4875
|
+
var RightPanel = (0, import_react24.memo)(function RightPanel2({
|
|
4876
|
+
mode,
|
|
4877
|
+
onModeChange,
|
|
4878
|
+
snapshots,
|
|
4879
|
+
selectedIndex,
|
|
4880
|
+
runtimeSnapshot,
|
|
4881
|
+
activeTab,
|
|
4882
|
+
allTabs,
|
|
4883
|
+
activeNarrativeEntries,
|
|
4884
|
+
activeNarrative,
|
|
4885
|
+
recorderViews,
|
|
4886
|
+
autoRecorderViews,
|
|
4887
|
+
size,
|
|
4888
|
+
onNavigateToStage
|
|
4889
|
+
}) {
|
|
4890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4891
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: {
|
|
4892
|
+
display: "flex",
|
|
4893
|
+
borderBottom: `1px solid ${theme.border}`,
|
|
4894
|
+
flexShrink: 0,
|
|
4895
|
+
background: theme.bgSecondary
|
|
4896
|
+
}, children: ["insights", "what"].map((m) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4897
|
+
"button",
|
|
4898
|
+
{
|
|
4899
|
+
onClick: () => onModeChange(m),
|
|
4900
|
+
style: {
|
|
4901
|
+
flex: 1,
|
|
4902
|
+
padding: "7px 12px",
|
|
4903
|
+
fontSize: 11,
|
|
4904
|
+
fontWeight: mode === m ? 700 : 500,
|
|
4905
|
+
textTransform: "uppercase",
|
|
4906
|
+
letterSpacing: "0.06em",
|
|
4907
|
+
color: mode === m ? theme.primary : theme.textMuted,
|
|
4908
|
+
background: "transparent",
|
|
4909
|
+
border: "none",
|
|
4910
|
+
borderBottom: mode === m ? `2px solid ${theme.primary}` : "2px solid transparent",
|
|
4911
|
+
cursor: "pointer",
|
|
4912
|
+
fontFamily: "inherit"
|
|
4913
|
+
},
|
|
4914
|
+
children: m === "insights" ? "Insights" : "Inspector"
|
|
4915
|
+
},
|
|
4916
|
+
m
|
|
4917
|
+
)) }),
|
|
4918
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: "hidden" }, children: mode === "insights" ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4919
|
+
InsightPanel,
|
|
4920
|
+
{
|
|
4921
|
+
mode: "tabs",
|
|
4922
|
+
expandedId: activeTab,
|
|
4923
|
+
insights: allTabs.filter((t) => t.id !== "result" && t.id !== "memory").map((tab) => ({
|
|
4924
|
+
id: tab.id,
|
|
4925
|
+
name: insightName(tab.name),
|
|
4926
|
+
render: () => {
|
|
4927
|
+
if (tab.id === "narrative") return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(NarrativePanel, { snapshots, selectedIndex, narrativeEntries: activeNarrativeEntries, narrative: activeNarrative, size, style: { height: "100%" } });
|
|
4928
|
+
const customView = recorderViews?.find((v2) => v2.id === tab.id);
|
|
4929
|
+
if (customView?.render) return customView.render({ snapshots, selectedIndex });
|
|
4930
|
+
const autoView = autoRecorderViews.find((v2) => v2.id === tab.id);
|
|
4931
|
+
if (autoView) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(KeyedRecorderView, { data: autoView.data, description: autoView.description, preferredOperation: autoView.preferredOperation, snapshots, selectedIndex });
|
|
4932
|
+
return null;
|
|
4933
|
+
}
|
|
4934
|
+
}))
|
|
4935
|
+
}
|
|
4936
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4937
|
+
InspectorPanel,
|
|
4938
|
+
{
|
|
4939
|
+
snapshots,
|
|
4940
|
+
selectedIndex,
|
|
4941
|
+
dataTraceFrames: runtimeSnapshot?.commitLog ? buildDataTrace(runtimeSnapshot.commitLog, snapshots[selectedIndex]?.runtimeStageId ?? "") : [],
|
|
4942
|
+
selectedStageId: snapshots[selectedIndex]?.runtimeStageId,
|
|
4943
|
+
onNavigateToStage
|
|
4944
|
+
}
|
|
4945
|
+
) })
|
|
4946
|
+
] });
|
|
4947
|
+
});
|
|
4948
|
+
function insightName(name) {
|
|
4949
|
+
const map = {
|
|
4950
|
+
"Narrative": "Story",
|
|
4951
|
+
"Memory": "State",
|
|
4952
|
+
"Metrics": "Performance",
|
|
4953
|
+
"Quality": "Quality",
|
|
4954
|
+
"Cost": "Cost"
|
|
4955
|
+
};
|
|
4956
|
+
return map[name] ?? name;
|
|
4957
|
+
}
|
|
4339
4958
|
function defaultRenderFlowchart({ spec: s, snapshots: snaps, selectedIndex, onNodeClick }) {
|
|
4340
|
-
return /* @__PURE__ */ (0,
|
|
4959
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4341
4960
|
TracedFlowchartView,
|
|
4342
4961
|
{
|
|
4343
4962
|
spec: s,
|
|
@@ -4369,7 +4988,7 @@ function ExplainableShell({
|
|
|
4369
4988
|
className,
|
|
4370
4989
|
style
|
|
4371
4990
|
}) {
|
|
4372
|
-
const derivedFromRuntime = (0,
|
|
4991
|
+
const derivedFromRuntime = (0, import_react24.useMemo)(() => {
|
|
4373
4992
|
if (!runtimeSnapshot) return null;
|
|
4374
4993
|
try {
|
|
4375
4994
|
const snaps = toVisualizationSnapshots(runtimeSnapshot, narrativeEntries);
|
|
@@ -4390,26 +5009,29 @@ function ExplainableShell({
|
|
|
4390
5009
|
const leftLabel = panelLabels?.topology ?? "Topology";
|
|
4391
5010
|
const rightLabel = panelLabels?.details ?? "Details";
|
|
4392
5011
|
const bottomLabel = panelLabels?.timeline ?? "Timeline";
|
|
4393
|
-
const shellRef = (0,
|
|
4394
|
-
const [isNarrow, setIsNarrow] = (0,
|
|
4395
|
-
(0,
|
|
5012
|
+
const shellRef = (0, import_react24.useRef)(null);
|
|
5013
|
+
const [isNarrow, setIsNarrow] = (0, import_react24.useState)(false);
|
|
5014
|
+
const [isMedium, setIsMedium] = (0, import_react24.useState)(false);
|
|
5015
|
+
(0, import_react24.useEffect)(() => {
|
|
4396
5016
|
const el = shellRef.current;
|
|
4397
5017
|
if (!el) return;
|
|
4398
5018
|
const ro = new ResizeObserver(([entry]) => {
|
|
4399
|
-
|
|
5019
|
+
const w = entry.contentRect.width;
|
|
5020
|
+
setIsNarrow(w < 640);
|
|
5021
|
+
setIsMedium(w >= 640 && w < 960);
|
|
4400
5022
|
window.dispatchEvent(new Event("resize"));
|
|
4401
5023
|
});
|
|
4402
5024
|
ro.observe(el);
|
|
4403
5025
|
return () => ro.disconnect();
|
|
4404
5026
|
}, []);
|
|
4405
|
-
const autoRecorderViews = (0,
|
|
5027
|
+
const autoRecorderViews = (0, import_react24.useMemo)(() => {
|
|
4406
5028
|
const recorders = runtimeSnapshot?.recorders;
|
|
4407
5029
|
if (!recorders?.length) return [];
|
|
4408
5030
|
const explicitIds = new Set((recorderViews ?? []).map((v2) => v2.id));
|
|
4409
5031
|
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 }));
|
|
4410
5032
|
}, [runtimeSnapshot, recorderViews]);
|
|
4411
5033
|
const hasNarrative = !!(narrative?.length || narrativeEntries?.length);
|
|
4412
|
-
const allTabs = (0,
|
|
5034
|
+
const allTabs = (0, import_react24.useMemo)(() => {
|
|
4413
5035
|
const tabs2 = [
|
|
4414
5036
|
{ id: "result", name: "Result", description: "Final output and console logs" },
|
|
4415
5037
|
{ id: "memory", name: "Memory", description: "Accumulator \u2014 progressive shared state at each stage" }
|
|
@@ -4428,37 +5050,38 @@ function ExplainableShell({
|
|
|
4428
5050
|
}, [hasNarrative, recorderViews, autoRecorderViews, hideTabsProp]);
|
|
4429
5051
|
const validTabIds = new Set(allTabs.map((t) => t.id));
|
|
4430
5052
|
const resolvedDefault = defaultTab && validTabIds.has(defaultTab) ? defaultTab : allTabs[0]?.id ?? "result";
|
|
4431
|
-
const [activeTab, setActiveTab] = (0,
|
|
4432
|
-
const [snapshotIdx, setSnapshotIdx] = (0,
|
|
4433
|
-
const [drillDownStack, setDrillDownStack] = (0,
|
|
4434
|
-
const [rightExpanded, setRightExpanded] = (0,
|
|
4435
|
-
const [
|
|
4436
|
-
const [
|
|
4437
|
-
(0,
|
|
5053
|
+
const [activeTab, setActiveTab] = (0, import_react24.useState)(resolvedDefault);
|
|
5054
|
+
const [snapshotIdx, setSnapshotIdx] = (0, import_react24.useState)(0);
|
|
5055
|
+
const [drillDownStack, setDrillDownStack] = (0, import_react24.useState)([]);
|
|
5056
|
+
const [rightExpanded, setRightExpanded] = (0, import_react24.useState)(defaultExpanded?.details ?? true);
|
|
5057
|
+
const [rightPanelMode, setRightPanelMode] = (0, import_react24.useState)("insights");
|
|
5058
|
+
const [leftExpanded, setLeftExpanded] = (0, import_react24.useState)(defaultExpanded?.topology ?? false);
|
|
5059
|
+
const [timelineExpanded, setTimelineExpanded] = (0, import_react24.useState)(defaultExpanded?.timeline ?? false);
|
|
5060
|
+
(0, import_react24.useEffect)(() => {
|
|
4438
5061
|
if (isNarrow) {
|
|
4439
5062
|
setLeftExpanded(false);
|
|
4440
5063
|
setRightExpanded(false);
|
|
4441
5064
|
setTimelineExpanded(false);
|
|
4442
5065
|
}
|
|
4443
5066
|
}, [isNarrow]);
|
|
4444
|
-
const triggerReflow = (0,
|
|
5067
|
+
const triggerReflow = (0, import_react24.useCallback)(() => {
|
|
4445
5068
|
requestAnimationFrame(() => window.dispatchEvent(new Event("resize")));
|
|
4446
5069
|
setTimeout(() => window.dispatchEvent(new Event("resize")), 320);
|
|
4447
5070
|
}, []);
|
|
4448
|
-
const toggleLeft = (0,
|
|
5071
|
+
const toggleLeft = (0, import_react24.useCallback)((v2) => {
|
|
4449
5072
|
setLeftExpanded(v2);
|
|
4450
5073
|
triggerReflow();
|
|
4451
5074
|
}, [triggerReflow]);
|
|
4452
|
-
const toggleRight = (0,
|
|
5075
|
+
const toggleRight = (0, import_react24.useCallback)((v2) => {
|
|
4453
5076
|
setRightExpanded(v2);
|
|
4454
5077
|
triggerReflow();
|
|
4455
5078
|
}, [triggerReflow]);
|
|
4456
|
-
const toggleTimeline = (0,
|
|
5079
|
+
const toggleTimeline = (0, import_react24.useCallback)(() => {
|
|
4457
5080
|
setTimelineExpanded((p) => !p);
|
|
4458
5081
|
triggerReflow();
|
|
4459
5082
|
}, [triggerReflow]);
|
|
4460
5083
|
const isInSubflow = drillDownStack.length > 0;
|
|
4461
|
-
const currentLevel = (0,
|
|
5084
|
+
const currentLevel = (0, import_react24.useMemo)(() => {
|
|
4462
5085
|
if (drillDownStack.length > 0) {
|
|
4463
5086
|
const top = drillDownStack[drillDownStack.length - 1];
|
|
4464
5087
|
return { spec: top.spec, snapshots: top.snapshots };
|
|
@@ -4468,7 +5091,7 @@ function ExplainableShell({
|
|
|
4468
5091
|
const activeSnapshots = currentLevel.snapshots;
|
|
4469
5092
|
const activeSpec = currentLevel.spec;
|
|
4470
5093
|
const safeIdx = activeSnapshots.length > 0 ? Math.max(0, Math.min(snapshotIdx, activeSnapshots.length - 1)) : 0;
|
|
4471
|
-
const activeNarrative = (0,
|
|
5094
|
+
const activeNarrative = (0, import_react24.useMemo)(() => {
|
|
4472
5095
|
if (!isInSubflow) return narrative;
|
|
4473
5096
|
const lines = [];
|
|
4474
5097
|
for (const snap of activeSnapshots) {
|
|
@@ -4478,25 +5101,25 @@ function ExplainableShell({
|
|
|
4478
5101
|
return lines.length > 0 ? lines : void 0;
|
|
4479
5102
|
}, [isInSubflow, narrative, activeSnapshots]);
|
|
4480
5103
|
const activeNarrativeEntries = isInSubflow ? void 0 : narrativeEntries;
|
|
4481
|
-
const breadcrumbs = (0,
|
|
5104
|
+
const breadcrumbs = (0, import_react24.useMemo)(() => {
|
|
4482
5105
|
const root = { label: title || "Flowchart", spec, description: spec?.description };
|
|
4483
5106
|
return [root, ...drillDownStack.map((e) => ({ label: e.label, spec: e.spec, description: void 0 }))];
|
|
4484
5107
|
}, [spec, title, drillDownStack]);
|
|
4485
|
-
const showTreeSidebar = (0,
|
|
4486
|
-
const rootOverlay = (0,
|
|
5108
|
+
const showTreeSidebar = (0, import_react24.useMemo)(() => !!spec && hasSubflowNodes(spec), [spec]);
|
|
5109
|
+
const rootOverlay = (0, import_react24.useMemo)(() => {
|
|
4487
5110
|
if (isInSubflow || !snapshots.length) return { activeStage: void 0, doneStages: void 0 };
|
|
4488
5111
|
const doneStages = new Set(snapshots.slice(0, safeIdx).map((s) => s.stageLabel));
|
|
4489
5112
|
const activeStage = snapshots[safeIdx]?.stageLabel ?? null;
|
|
4490
5113
|
return { activeStage, doneStages };
|
|
4491
5114
|
}, [isInSubflow, snapshots, safeIdx]);
|
|
4492
|
-
const handleTabChange = (0,
|
|
5115
|
+
const handleTabChange = (0, import_react24.useCallback)((tab) => {
|
|
4493
5116
|
setActiveTab(tab);
|
|
4494
5117
|
setDrillDownStack([]);
|
|
4495
5118
|
}, []);
|
|
4496
|
-
const handleSnapshotChange = (0,
|
|
5119
|
+
const handleSnapshotChange = (0, import_react24.useCallback)((idx) => {
|
|
4497
5120
|
if (typeof idx === "number") setSnapshotIdx(idx);
|
|
4498
5121
|
}, []);
|
|
4499
|
-
const handleDrillDown = (0,
|
|
5122
|
+
const handleDrillDown = (0, import_react24.useCallback)(
|
|
4500
5123
|
(nodeName) => {
|
|
4501
5124
|
if (!activeSpec) return;
|
|
4502
5125
|
const entry = resolveSubflowLevel(activeSpec, activeSnapshots, nodeName, narrativeEntries);
|
|
@@ -4507,14 +5130,14 @@ function ExplainableShell({
|
|
|
4507
5130
|
},
|
|
4508
5131
|
[activeSpec, activeSnapshots, narrativeEntries, snapshotIdx]
|
|
4509
5132
|
);
|
|
4510
|
-
const handleBreadcrumbNavigate = (0,
|
|
5133
|
+
const handleBreadcrumbNavigate = (0, import_react24.useCallback)((level) => {
|
|
4511
5134
|
setDrillDownStack((prev) => {
|
|
4512
5135
|
const popped = level === 0 ? prev[0] : prev[level];
|
|
4513
5136
|
if (popped) setSnapshotIdx(popped.parentSnapshotIdx);
|
|
4514
5137
|
return level === 0 ? [] : prev.slice(0, level);
|
|
4515
5138
|
});
|
|
4516
5139
|
}, []);
|
|
4517
|
-
const handleNodeClick = (0,
|
|
5140
|
+
const handleNodeClick = (0, import_react24.useCallback)(
|
|
4518
5141
|
(indexOrId) => {
|
|
4519
5142
|
if (typeof indexOrId === "number") {
|
|
4520
5143
|
setSnapshotIdx(indexOrId);
|
|
@@ -4532,7 +5155,7 @@ function ExplainableShell({
|
|
|
4532
5155
|
},
|
|
4533
5156
|
[activeSpec, activeSnapshots, handleDrillDown]
|
|
4534
5157
|
);
|
|
4535
|
-
const handleTreeNodeSelect = (0,
|
|
5158
|
+
const handleTreeNodeSelect = (0, import_react24.useCallback)(
|
|
4536
5159
|
(name, isSubflow) => {
|
|
4537
5160
|
if (isSubflow && spec) {
|
|
4538
5161
|
setDrillDownStack([]);
|
|
@@ -4551,31 +5174,31 @@ function ExplainableShell({
|
|
|
4551
5174
|
);
|
|
4552
5175
|
const tabLabels = new Map(allTabs.map((t) => [t.id, t.name]));
|
|
4553
5176
|
if (unstyled) {
|
|
4554
|
-
return /* @__PURE__ */ (0,
|
|
4555
|
-
/* @__PURE__ */ (0,
|
|
4556
|
-
/* @__PURE__ */ (0,
|
|
4557
|
-
activeTab === "result" && /* @__PURE__ */ (0,
|
|
4558
|
-
(activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ (0,
|
|
4559
|
-
/* @__PURE__ */ (0,
|
|
4560
|
-
isInSubflow && /* @__PURE__ */ (0,
|
|
5177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className, style, "data-fp": "explainable-shell", children: [
|
|
5178
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { "data-fp": "shell-tabs", children: allTabs.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("button", { "data-fp": "shell-tab", "data-active": tab.id === activeTab, onClick: () => handleTabChange(tab.id), children: tab.name }, tab.id)) }),
|
|
5179
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { "data-fp": "shell-content", "data-tab": activeTab, children: [
|
|
5180
|
+
activeTab === "result" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ResultPanel, { data: resultData ?? null, logs, hideConsole, unstyled: true }),
|
|
5181
|
+
(activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
5182
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TimeTravelControls, { snapshots: activeSnapshots, selectedIndex: safeIdx, onIndexChange: handleSnapshotChange, unstyled: true }),
|
|
5183
|
+
isInSubflow && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
|
|
4561
5184
|
activeSpec && effectiveRenderFlowchart?.({ spec: activeSpec, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick }),
|
|
4562
|
-
/* @__PURE__ */ (0,
|
|
4563
|
-
/* @__PURE__ */ (0,
|
|
4564
|
-
/* @__PURE__ */ (0,
|
|
5185
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, unstyled: true }),
|
|
5186
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, narrative: activeNarrative, unstyled: true }),
|
|
5187
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, unstyled: true })
|
|
4565
5188
|
] })
|
|
4566
5189
|
] })
|
|
4567
5190
|
] });
|
|
4568
5191
|
}
|
|
4569
5192
|
const showTopology = !!effectiveRenderFlowchart && !!activeSpec;
|
|
4570
|
-
const detailsContent = (0,
|
|
5193
|
+
const detailsContent = (0, import_react24.useMemo)(() => {
|
|
4571
5194
|
if (activeTab === "result") {
|
|
4572
|
-
return /* @__PURE__ */ (0,
|
|
5195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ResultPanel, { data: resultData ?? null, logs, hideConsole, size });
|
|
4573
5196
|
}
|
|
4574
5197
|
if (activeTab === "memory") {
|
|
4575
|
-
return /* @__PURE__ */ (0,
|
|
5198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, size, style: { height: "100%" } });
|
|
4576
5199
|
}
|
|
4577
5200
|
if (activeTab === "narrative") {
|
|
4578
|
-
return /* @__PURE__ */ (0,
|
|
5201
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, narrative: activeNarrative, size, style: { height: "100%" } });
|
|
4579
5202
|
}
|
|
4580
5203
|
const customView = recorderViews?.find((v2) => v2.id === activeTab);
|
|
4581
5204
|
if (customView?.render) {
|
|
@@ -4583,7 +5206,7 @@ function ExplainableShell({
|
|
|
4583
5206
|
}
|
|
4584
5207
|
const autoView = autoRecorderViews.find((v2) => v2.id === activeTab);
|
|
4585
5208
|
if (autoView) {
|
|
4586
|
-
return /* @__PURE__ */ (0,
|
|
5209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4587
5210
|
KeyedRecorderView,
|
|
4588
5211
|
{
|
|
4589
5212
|
data: autoView.data,
|
|
@@ -4596,8 +5219,8 @@ function ExplainableShell({
|
|
|
4596
5219
|
}
|
|
4597
5220
|
return null;
|
|
4598
5221
|
}, [activeTab, resultData, logs, hideConsole, size, activeSnapshots, safeIdx, activeNarrativeEntries, activeNarrative, recorderViews, autoRecorderViews]);
|
|
4599
|
-
const detailsPanel = /* @__PURE__ */ (0,
|
|
4600
|
-
/* @__PURE__ */ (0,
|
|
5222
|
+
const detailsPanel = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflow: "hidden" }, children: [
|
|
5223
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: {
|
|
4601
5224
|
display: "flex",
|
|
4602
5225
|
borderBottom: `1px solid ${theme.border}`,
|
|
4603
5226
|
background: theme.bgSecondary,
|
|
@@ -4605,7 +5228,7 @@ function ExplainableShell({
|
|
|
4605
5228
|
overflowX: "auto"
|
|
4606
5229
|
}, children: allTabs.map((tab) => {
|
|
4607
5230
|
const active = tab.id === activeTab;
|
|
4608
|
-
return /* @__PURE__ */ (0,
|
|
5231
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4609
5232
|
"button",
|
|
4610
5233
|
{
|
|
4611
5234
|
onClick: () => handleTabChange(tab.id),
|
|
@@ -4629,9 +5252,9 @@ function ExplainableShell({
|
|
|
4629
5252
|
tab.id
|
|
4630
5253
|
);
|
|
4631
5254
|
}) }),
|
|
4632
|
-
/* @__PURE__ */ (0,
|
|
5255
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: detailsContent })
|
|
4633
5256
|
] });
|
|
4634
|
-
return /* @__PURE__ */ (0,
|
|
5257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4635
5258
|
"div",
|
|
4636
5259
|
{
|
|
4637
5260
|
ref: shellRef,
|
|
@@ -4649,7 +5272,7 @@ function ExplainableShell({
|
|
|
4649
5272
|
},
|
|
4650
5273
|
"data-fp": "explainable-shell",
|
|
4651
5274
|
children: [
|
|
4652
|
-
/* @__PURE__ */ (0,
|
|
5275
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4653
5276
|
TimeTravelControls,
|
|
4654
5277
|
{
|
|
4655
5278
|
snapshots: activeSnapshots,
|
|
@@ -4658,19 +5281,19 @@ function ExplainableShell({
|
|
|
4658
5281
|
size
|
|
4659
5282
|
}
|
|
4660
5283
|
),
|
|
4661
|
-
isInSubflow && /* @__PURE__ */ (0,
|
|
4662
|
-
/* @__PURE__ */ (0,
|
|
5284
|
+
isInSubflow && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
|
|
5285
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: isNarrow ? "auto" : "hidden", display: "flex", flexDirection: "column" }, children: isNarrow ? (
|
|
4663
5286
|
/* ── Mobile: stacked vertical ── */
|
|
4664
|
-
/* @__PURE__ */ (0,
|
|
4665
|
-
showTopology && /* @__PURE__ */ (0,
|
|
5287
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
5288
|
+
showTopology && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { height: 350, flexShrink: 0, overflow: "hidden" }, children: effectiveRenderFlowchart({
|
|
4666
5289
|
spec: activeSpec,
|
|
4667
5290
|
snapshots: activeSnapshots,
|
|
4668
5291
|
selectedIndex: safeIdx,
|
|
4669
5292
|
onNodeClick: handleNodeClick
|
|
4670
5293
|
}) }),
|
|
4671
|
-
showTreeSidebar && /* @__PURE__ */ (0,
|
|
4672
|
-
/* @__PURE__ */ (0,
|
|
4673
|
-
leftExpanded && /* @__PURE__ */ (0,
|
|
5294
|
+
showTreeSidebar && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
5295
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(HLinePill, { label: leftLabel, expanded: leftExpanded, onClick: () => toggleLeft(!leftExpanded) }),
|
|
5296
|
+
leftExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { maxHeight: 180, overflow: "auto", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4674
5297
|
SubflowTree,
|
|
4675
5298
|
{
|
|
4676
5299
|
spec,
|
|
@@ -4680,17 +5303,17 @@ function ExplainableShell({
|
|
|
4680
5303
|
}
|
|
4681
5304
|
) })
|
|
4682
5305
|
] }),
|
|
4683
|
-
/* @__PURE__ */ (0,
|
|
4684
|
-
rightExpanded && /* @__PURE__ */ (0,
|
|
4685
|
-
/* @__PURE__ */ (0,
|
|
4686
|
-
timelineExpanded && /* @__PURE__ */ (0,
|
|
5306
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(HLinePill, { label: rightLabel, expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
|
|
5307
|
+
rightExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { maxHeight: 350, flexShrink: 0, overflow: "hidden" }, children: detailsPanel }),
|
|
5308
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(HLinePill, { label: bottomLabel, detail: `${activeSnapshots.length} stages`, expanded: timelineExpanded, onClick: toggleTimeline }),
|
|
5309
|
+
timelineExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flexShrink: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, size }) })
|
|
4687
5310
|
] })
|
|
4688
|
-
) :
|
|
4689
|
-
/* ── Desktop
|
|
4690
|
-
/* @__PURE__ */ (0,
|
|
4691
|
-
/* @__PURE__ */ (0,
|
|
4692
|
-
showTreeSidebar && (leftExpanded ? /* @__PURE__ */ (0,
|
|
4693
|
-
/* @__PURE__ */ (0,
|
|
5311
|
+
) : (
|
|
5312
|
+
/* ── Desktop: two-column — Flowchart | Right Panel ── */
|
|
5313
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
5314
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { flex: 1, display: "flex", overflow: "hidden" }, children: [
|
|
5315
|
+
showTreeSidebar && (leftExpanded ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { width: 180, flexShrink: 0, display: "flex", flexDirection: "row", overflow: "hidden" }, children: [
|
|
5316
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4694
5317
|
SubflowTree,
|
|
4695
5318
|
{
|
|
4696
5319
|
spec,
|
|
@@ -4699,28 +5322,45 @@ function ExplainableShell({
|
|
|
4699
5322
|
onNodeSelect: handleTreeNodeSelect
|
|
4700
5323
|
}
|
|
4701
5324
|
) }),
|
|
4702
|
-
/* @__PURE__ */ (0,
|
|
4703
|
-
] }) : /* @__PURE__ */ (0,
|
|
4704
|
-
/* @__PURE__ */ (0,
|
|
5325
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(VLinePill, { label: "Topology", expanded: true, side: "left", onClick: () => toggleLeft(false) })
|
|
5326
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(VLinePill, { label: "Topology", expanded: false, side: "left", onClick: () => toggleLeft(true) })),
|
|
5327
|
+
showTopology ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: "hidden", minWidth: 0 }, children: effectiveRenderFlowchart({
|
|
4705
5328
|
spec: activeSpec,
|
|
4706
5329
|
snapshots: activeSnapshots,
|
|
4707
5330
|
selectedIndex: safeIdx,
|
|
4708
5331
|
onNodeClick: handleNodeClick
|
|
4709
|
-
}) }),
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
5332
|
+
}) }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1 } }),
|
|
5333
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(VLinePill, { label: "Details", expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
|
|
5334
|
+
rightExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { width: "42%", minWidth: 320, maxWidth: 550, display: "flex", flexDirection: "column", overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5335
|
+
RightPanel,
|
|
5336
|
+
{
|
|
5337
|
+
mode: rightPanelMode,
|
|
5338
|
+
onModeChange: setRightPanelMode,
|
|
5339
|
+
snapshots: activeSnapshots,
|
|
5340
|
+
selectedIndex: safeIdx,
|
|
5341
|
+
runtimeSnapshot,
|
|
5342
|
+
activeTab,
|
|
5343
|
+
allTabs,
|
|
5344
|
+
activeNarrativeEntries,
|
|
5345
|
+
activeNarrative,
|
|
5346
|
+
recorderViews,
|
|
5347
|
+
autoRecorderViews,
|
|
5348
|
+
size,
|
|
5349
|
+
onNavigateToStage: (id) => {
|
|
5350
|
+
const idx = activeSnapshots.findIndex((s) => s.runtimeStageId === id);
|
|
5351
|
+
if (idx >= 0) setSnapshotIdx(idx);
|
|
5352
|
+
}
|
|
5353
|
+
}
|
|
5354
|
+
) })
|
|
4714
5355
|
] }),
|
|
4715
|
-
/* @__PURE__ */ (0,
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4719
|
-
|
|
4720
|
-
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
timelineExpanded && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { flexShrink: 0, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, size }) })
|
|
5356
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5357
|
+
CompactTimeline,
|
|
5358
|
+
{
|
|
5359
|
+
snapshots: activeSnapshots,
|
|
5360
|
+
selectedIndex: safeIdx,
|
|
5361
|
+
defaultExpanded: timelineExpanded
|
|
5362
|
+
}
|
|
5363
|
+
)
|
|
4724
5364
|
] })
|
|
4725
5365
|
) })
|
|
4726
5366
|
]
|
|
@@ -4729,9 +5369,13 @@ function ExplainableShell({
|
|
|
4729
5369
|
}
|
|
4730
5370
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4731
5371
|
0 && (module.exports = {
|
|
5372
|
+
CompactTimeline,
|
|
5373
|
+
DataTracePanel,
|
|
4732
5374
|
ExplainableShell,
|
|
4733
5375
|
FootprintTheme,
|
|
4734
5376
|
GanttTimeline,
|
|
5377
|
+
InsightPanel,
|
|
5378
|
+
InspectorPanel,
|
|
4735
5379
|
MemoryInspector,
|
|
4736
5380
|
MemoryPanel,
|
|
4737
5381
|
NarrativeLog,
|