footprint-explainable-ui 0.14.11 → 0.15.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 +696 -148
- 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 +678 -134
- 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,490 @@ 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.jsx)("div", { style: { padding: 12, color: theme.textMuted, fontSize: 13 }, children: "Select a stage to see its data dependency chain." });
|
|
4018
|
+
}
|
|
4019
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { padding: "8px 0", fontSize: 13 }, children: [
|
|
4020
|
+
fromStageName && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4021
|
+
"div",
|
|
4022
|
+
{
|
|
4023
|
+
style: {
|
|
4024
|
+
padding: "4px 12px 8px",
|
|
4025
|
+
fontSize: 11,
|
|
4026
|
+
color: theme.textMuted,
|
|
4027
|
+
textTransform: "uppercase",
|
|
4028
|
+
letterSpacing: "0.5px",
|
|
4029
|
+
fontWeight: 600
|
|
4030
|
+
},
|
|
4031
|
+
children: [
|
|
4032
|
+
"Data trace from ",
|
|
4033
|
+
fromStageName
|
|
4034
|
+
]
|
|
4035
|
+
}
|
|
4036
|
+
),
|
|
4037
|
+
frames.map((frame, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4038
|
+
DataTraceFrame,
|
|
4039
|
+
{
|
|
4040
|
+
frame,
|
|
4041
|
+
isFirst: i === 0,
|
|
4042
|
+
isLast: i === frames.length - 1,
|
|
4043
|
+
isSelected: frame.runtimeStageId === selectedStageId,
|
|
4044
|
+
onClick: onFrameClick
|
|
4045
|
+
},
|
|
4046
|
+
frame.runtimeStageId
|
|
4047
|
+
))
|
|
4048
|
+
] });
|
|
4049
|
+
});
|
|
4050
|
+
var DataTraceFrame = (0, import_react20.memo)(function DataTraceFrame2({
|
|
4051
|
+
frame,
|
|
4052
|
+
isFirst,
|
|
4053
|
+
isLast,
|
|
4054
|
+
isSelected,
|
|
4055
|
+
onClick
|
|
4056
|
+
}) {
|
|
4057
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4058
|
+
"button",
|
|
4059
|
+
{
|
|
4060
|
+
onClick: () => onClick?.(frame.runtimeStageId),
|
|
4061
|
+
style: {
|
|
4062
|
+
display: "block",
|
|
4063
|
+
width: "100%",
|
|
4064
|
+
textAlign: "left",
|
|
4065
|
+
border: "none",
|
|
4066
|
+
background: isSelected ? "var(--fp-accent-bg, rgba(99,102,241,0.12))" : "transparent",
|
|
4067
|
+
padding: "6px 12px 6px 16px",
|
|
4068
|
+
cursor: onClick ? "pointer" : "default",
|
|
4069
|
+
borderLeft: isSelected ? "3px solid var(--fp-accent, #6366f1)" : "3px solid transparent",
|
|
4070
|
+
color: "inherit",
|
|
4071
|
+
fontSize: 13
|
|
4072
|
+
},
|
|
4073
|
+
children: [
|
|
4074
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
4075
|
+
!isFirst && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { color: theme.textMuted, fontSize: 11 }, children: "\u2191" }),
|
|
4076
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4077
|
+
"span",
|
|
4078
|
+
{
|
|
4079
|
+
style: {
|
|
4080
|
+
fontWeight: isFirst ? 600 : 400,
|
|
4081
|
+
color: isFirst ? "var(--fp-accent, #6366f1)" : theme.textPrimary
|
|
4082
|
+
},
|
|
4083
|
+
children: frame.stageName
|
|
4084
|
+
}
|
|
4085
|
+
),
|
|
4086
|
+
isLast && !isFirst && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
4087
|
+
"span",
|
|
4088
|
+
{
|
|
4089
|
+
style: {
|
|
4090
|
+
fontSize: 10,
|
|
4091
|
+
color: theme.textMuted,
|
|
4092
|
+
fontStyle: "italic"
|
|
4093
|
+
},
|
|
4094
|
+
children: "(origin)"
|
|
4095
|
+
}
|
|
4096
|
+
)
|
|
4097
|
+
] }),
|
|
4098
|
+
frame.keysWritten.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4099
|
+
"div",
|
|
4100
|
+
{
|
|
4101
|
+
style: {
|
|
4102
|
+
fontSize: 11,
|
|
4103
|
+
color: theme.textMuted,
|
|
4104
|
+
paddingLeft: isFirst ? 0 : 18,
|
|
4105
|
+
marginTop: 2
|
|
4106
|
+
},
|
|
4107
|
+
children: [
|
|
4108
|
+
"wrote:",
|
|
4109
|
+
" ",
|
|
4110
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { style: { color: theme.textSecondary }, children: frame.keysWritten.join(", ") })
|
|
4111
|
+
]
|
|
4112
|
+
}
|
|
4113
|
+
),
|
|
4114
|
+
frame.linkedBy && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
|
|
4115
|
+
"div",
|
|
4116
|
+
{
|
|
4117
|
+
style: {
|
|
4118
|
+
fontSize: 11,
|
|
4119
|
+
color: "var(--fp-accent, #6366f1)",
|
|
4120
|
+
paddingLeft: 18,
|
|
4121
|
+
marginTop: 1
|
|
4122
|
+
},
|
|
4123
|
+
children: [
|
|
4124
|
+
"\u2190 via ",
|
|
4125
|
+
frame.linkedBy
|
|
4126
|
+
]
|
|
4127
|
+
}
|
|
4128
|
+
)
|
|
4129
|
+
]
|
|
4130
|
+
}
|
|
4131
|
+
);
|
|
4132
|
+
});
|
|
4133
|
+
|
|
4134
|
+
// src/components/InspectorPanel/InspectorPanel.tsx
|
|
4135
|
+
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
4136
|
+
var InspectorPanel = (0, import_react21.memo)(function InspectorPanel2({
|
|
4137
|
+
snapshots,
|
|
4138
|
+
selectedIndex,
|
|
4139
|
+
dataTraceFrames,
|
|
4140
|
+
selectedStageId,
|
|
4141
|
+
onNavigateToStage
|
|
4142
|
+
}) {
|
|
4143
|
+
const [tab, setTab] = (0, import_react21.useState)("state");
|
|
4144
|
+
const currentSnapshot = snapshots[selectedIndex];
|
|
4145
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4146
|
+
"div",
|
|
4147
|
+
{
|
|
4148
|
+
style: {
|
|
4149
|
+
display: "flex",
|
|
4150
|
+
flexDirection: "column",
|
|
4151
|
+
height: "100%",
|
|
4152
|
+
overflow: "hidden"
|
|
4153
|
+
},
|
|
4154
|
+
children: [
|
|
4155
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4156
|
+
"div",
|
|
4157
|
+
{
|
|
4158
|
+
style: {
|
|
4159
|
+
display: "flex",
|
|
4160
|
+
borderBottom: `1px solid ${theme.border}`,
|
|
4161
|
+
flexShrink: 0
|
|
4162
|
+
},
|
|
4163
|
+
children: [
|
|
4164
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4165
|
+
TabButton,
|
|
4166
|
+
{
|
|
4167
|
+
active: tab === "state",
|
|
4168
|
+
onClick: () => setTab("state"),
|
|
4169
|
+
label: "State"
|
|
4170
|
+
}
|
|
4171
|
+
),
|
|
4172
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4173
|
+
TabButton,
|
|
4174
|
+
{
|
|
4175
|
+
active: tab === "trace",
|
|
4176
|
+
onClick: () => setTab("trace"),
|
|
4177
|
+
label: "Data Trace",
|
|
4178
|
+
badge: dataTraceFrames.length > 0 ? String(dataTraceFrames.length) : void 0
|
|
4179
|
+
}
|
|
4180
|
+
)
|
|
4181
|
+
]
|
|
4182
|
+
}
|
|
4183
|
+
),
|
|
4184
|
+
/* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { style: { flex: 1, overflow: "auto" }, children: [
|
|
4185
|
+
tab === "state" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4186
|
+
MemoryPanel,
|
|
4187
|
+
{
|
|
4188
|
+
snapshots,
|
|
4189
|
+
selectedIndex
|
|
4190
|
+
}
|
|
4191
|
+
),
|
|
4192
|
+
tab === "trace" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4193
|
+
DataTracePanel,
|
|
4194
|
+
{
|
|
4195
|
+
frames: dataTraceFrames,
|
|
4196
|
+
selectedStageId,
|
|
4197
|
+
onFrameClick: onNavigateToStage,
|
|
4198
|
+
fromStageName: currentSnapshot?.stageName
|
|
4199
|
+
}
|
|
4200
|
+
)
|
|
4201
|
+
] })
|
|
4202
|
+
]
|
|
4203
|
+
}
|
|
4204
|
+
);
|
|
4205
|
+
});
|
|
4206
|
+
function TabButton({
|
|
4207
|
+
active,
|
|
4208
|
+
onClick,
|
|
4209
|
+
label,
|
|
4210
|
+
badge
|
|
4211
|
+
}) {
|
|
4212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
|
|
4213
|
+
"button",
|
|
4214
|
+
{
|
|
4215
|
+
onClick,
|
|
4216
|
+
style: {
|
|
4217
|
+
padding: "8px 14px",
|
|
4218
|
+
border: "none",
|
|
4219
|
+
borderBottom: active ? "2px solid var(--fp-accent, #6366f1)" : "2px solid transparent",
|
|
4220
|
+
background: "transparent",
|
|
4221
|
+
color: active ? "var(--fp-accent, #6366f1)" : theme.textMuted,
|
|
4222
|
+
fontWeight: active ? 600 : 400,
|
|
4223
|
+
fontSize: 12,
|
|
4224
|
+
cursor: "pointer",
|
|
4225
|
+
display: "flex",
|
|
4226
|
+
alignItems: "center",
|
|
4227
|
+
gap: 4
|
|
4228
|
+
},
|
|
4229
|
+
children: [
|
|
4230
|
+
label,
|
|
4231
|
+
badge && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
|
|
4232
|
+
"span",
|
|
4233
|
+
{
|
|
4234
|
+
style: {
|
|
4235
|
+
fontSize: 10,
|
|
4236
|
+
background: active ? "var(--fp-accent, #6366f1)" : theme.textMuted,
|
|
4237
|
+
color: "#fff",
|
|
4238
|
+
borderRadius: 8,
|
|
4239
|
+
padding: "1px 5px",
|
|
4240
|
+
fontWeight: 600
|
|
4241
|
+
},
|
|
4242
|
+
children: badge
|
|
4243
|
+
}
|
|
4244
|
+
)
|
|
4245
|
+
]
|
|
4246
|
+
}
|
|
4247
|
+
);
|
|
4248
|
+
}
|
|
4249
|
+
|
|
4250
|
+
// src/components/InsightPanel/InsightPanel.tsx
|
|
4251
|
+
var import_react22 = require("react");
|
|
4252
|
+
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
4253
|
+
var InsightPanel = (0, import_react22.memo)(function InsightPanel2({
|
|
4254
|
+
insights,
|
|
4255
|
+
expandedId,
|
|
4256
|
+
mode
|
|
4257
|
+
}) {
|
|
4258
|
+
if (insights.length === 0) {
|
|
4259
|
+
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." });
|
|
4260
|
+
}
|
|
4261
|
+
if (mode === "grid") {
|
|
4262
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InsightGrid, { insights });
|
|
4263
|
+
}
|
|
4264
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(InsightTabs, { insights, defaultId: expandedId });
|
|
4265
|
+
});
|
|
4266
|
+
var InsightTabs = (0, import_react22.memo)(function InsightTabs2({
|
|
4267
|
+
insights,
|
|
4268
|
+
defaultId
|
|
4269
|
+
}) {
|
|
4270
|
+
const [activeId, setActiveId] = (0, import_react22.useState)(defaultId ?? insights[0]?.id);
|
|
4271
|
+
const active = insights.find((i) => i.id === activeId) ?? insights[0];
|
|
4272
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4273
|
+
"div",
|
|
4274
|
+
{
|
|
4275
|
+
style: {
|
|
4276
|
+
display: "flex",
|
|
4277
|
+
flexDirection: "column",
|
|
4278
|
+
height: "100%",
|
|
4279
|
+
overflow: "hidden"
|
|
4280
|
+
},
|
|
4281
|
+
children: [
|
|
4282
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4283
|
+
"div",
|
|
4284
|
+
{
|
|
4285
|
+
style: {
|
|
4286
|
+
display: "flex",
|
|
4287
|
+
borderBottom: `1px solid ${theme.border}`,
|
|
4288
|
+
flexShrink: 0,
|
|
4289
|
+
overflowX: "auto"
|
|
4290
|
+
},
|
|
4291
|
+
children: insights.map((insight) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4292
|
+
"button",
|
|
4293
|
+
{
|
|
4294
|
+
onClick: () => setActiveId(insight.id),
|
|
4295
|
+
style: {
|
|
4296
|
+
padding: "8px 12px",
|
|
4297
|
+
border: "none",
|
|
4298
|
+
borderBottom: activeId === insight.id ? "2px solid var(--fp-accent, #6366f1)" : "2px solid transparent",
|
|
4299
|
+
background: "transparent",
|
|
4300
|
+
color: activeId === insight.id ? "var(--fp-accent, #6366f1)" : theme.textMuted,
|
|
4301
|
+
fontWeight: activeId === insight.id ? 600 : 400,
|
|
4302
|
+
fontSize: 12,
|
|
4303
|
+
cursor: "pointer",
|
|
4304
|
+
whiteSpace: "nowrap"
|
|
4305
|
+
},
|
|
4306
|
+
children: insight.name
|
|
4307
|
+
},
|
|
4308
|
+
insight.id
|
|
4309
|
+
))
|
|
4310
|
+
}
|
|
4311
|
+
),
|
|
4312
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: active?.render() })
|
|
4313
|
+
]
|
|
4314
|
+
}
|
|
4315
|
+
);
|
|
4316
|
+
});
|
|
4317
|
+
var InsightGrid = (0, import_react22.memo)(function InsightGrid2({
|
|
4318
|
+
insights
|
|
4319
|
+
}) {
|
|
4320
|
+
const cols = insights.length <= 2 ? 1 : 2;
|
|
4321
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4322
|
+
"div",
|
|
4323
|
+
{
|
|
4324
|
+
style: {
|
|
4325
|
+
display: "grid",
|
|
4326
|
+
gridTemplateColumns: `repeat(${cols}, 1fr)`,
|
|
4327
|
+
height: "100%",
|
|
4328
|
+
overflow: "auto",
|
|
4329
|
+
gap: 1,
|
|
4330
|
+
background: theme.border
|
|
4331
|
+
},
|
|
4332
|
+
children: insights.map((insight) => /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4333
|
+
"div",
|
|
4334
|
+
{
|
|
4335
|
+
style: {
|
|
4336
|
+
background: "var(--fp-bg, #1a1b26)",
|
|
4337
|
+
display: "flex",
|
|
4338
|
+
flexDirection: "column",
|
|
4339
|
+
overflow: "hidden"
|
|
4340
|
+
},
|
|
4341
|
+
children: [
|
|
4342
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
|
|
4343
|
+
"div",
|
|
4344
|
+
{
|
|
4345
|
+
style: {
|
|
4346
|
+
padding: "6px 10px",
|
|
4347
|
+
fontSize: 11,
|
|
4348
|
+
fontWeight: 600,
|
|
4349
|
+
color: theme.textMuted,
|
|
4350
|
+
textTransform: "uppercase",
|
|
4351
|
+
letterSpacing: "0.5px",
|
|
4352
|
+
borderBottom: `1px solid ${theme.border}`,
|
|
4353
|
+
flexShrink: 0
|
|
4354
|
+
},
|
|
4355
|
+
children: [
|
|
4356
|
+
insight.name,
|
|
4357
|
+
insight.summary && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
4358
|
+
"span",
|
|
4359
|
+
{
|
|
4360
|
+
style: {
|
|
4361
|
+
marginLeft: 8,
|
|
4362
|
+
fontWeight: 400,
|
|
4363
|
+
fontSize: 10,
|
|
4364
|
+
color: theme.textMuted
|
|
4365
|
+
},
|
|
4366
|
+
children: insight.summary
|
|
4367
|
+
}
|
|
4368
|
+
)
|
|
4369
|
+
]
|
|
4370
|
+
}
|
|
4371
|
+
),
|
|
4372
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: insight.render() })
|
|
4373
|
+
]
|
|
4374
|
+
},
|
|
4375
|
+
insight.id
|
|
4376
|
+
))
|
|
4377
|
+
}
|
|
4378
|
+
);
|
|
4379
|
+
});
|
|
4380
|
+
|
|
4381
|
+
// src/components/CompactTimeline/CompactTimeline.tsx
|
|
4382
|
+
var import_react23 = require("react");
|
|
4383
|
+
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4384
|
+
var CompactTimeline = (0, import_react23.memo)(function CompactTimeline2({
|
|
4385
|
+
snapshots,
|
|
4386
|
+
selectedIndex,
|
|
4387
|
+
defaultExpanded = false
|
|
4388
|
+
}) {
|
|
4389
|
+
const [expanded, setExpanded] = (0, import_react23.useState)(defaultExpanded);
|
|
4390
|
+
if (snapshots.length === 0) return null;
|
|
4391
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { style: { borderTop: `1px solid ${theme.border}` }, children: [
|
|
4392
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4393
|
+
"button",
|
|
4394
|
+
{
|
|
4395
|
+
onClick: () => setExpanded((e) => !e),
|
|
4396
|
+
style: {
|
|
4397
|
+
width: "100%",
|
|
4398
|
+
display: "flex",
|
|
4399
|
+
alignItems: "center",
|
|
4400
|
+
gap: 8,
|
|
4401
|
+
padding: "6px 12px",
|
|
4402
|
+
border: "none",
|
|
4403
|
+
background: "transparent",
|
|
4404
|
+
cursor: "pointer",
|
|
4405
|
+
fontSize: 11,
|
|
4406
|
+
color: theme.textMuted,
|
|
4407
|
+
fontWeight: 600,
|
|
4408
|
+
textTransform: "uppercase",
|
|
4409
|
+
letterSpacing: "0.5px"
|
|
4410
|
+
},
|
|
4411
|
+
children: [
|
|
4412
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { style: { fontSize: 10 }, children: expanded ? "\u25BC" : "\u25B8" }),
|
|
4413
|
+
"Timeline",
|
|
4414
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { style: { fontWeight: 400, fontSize: 10 }, children: [
|
|
4415
|
+
snapshots.length,
|
|
4416
|
+
" stages"
|
|
4417
|
+
] }),
|
|
4418
|
+
!expanded && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4419
|
+
"div",
|
|
4420
|
+
{
|
|
4421
|
+
style: {
|
|
4422
|
+
flex: 1,
|
|
4423
|
+
display: "flex",
|
|
4424
|
+
alignItems: "center",
|
|
4425
|
+
gap: 2,
|
|
4426
|
+
marginLeft: 8
|
|
4427
|
+
},
|
|
4428
|
+
children: [
|
|
4429
|
+
snapshots.map((snap, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4430
|
+
"div",
|
|
4431
|
+
{
|
|
4432
|
+
style: {
|
|
4433
|
+
width: i === selectedIndex ? 8 : 5,
|
|
4434
|
+
height: i === selectedIndex ? 8 : 5,
|
|
4435
|
+
borderRadius: "50%",
|
|
4436
|
+
background: i < selectedIndex ? "var(--fp-success, #22c55e)" : i === selectedIndex ? "var(--fp-accent, #6366f1)" : theme.textMuted + "40",
|
|
4437
|
+
transition: "all 0.15s",
|
|
4438
|
+
flexShrink: 0
|
|
4439
|
+
},
|
|
4440
|
+
title: snap.stageName
|
|
4441
|
+
},
|
|
4442
|
+
i
|
|
4443
|
+
)),
|
|
4444
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4445
|
+
"div",
|
|
4446
|
+
{
|
|
4447
|
+
style: {
|
|
4448
|
+
flex: 1,
|
|
4449
|
+
height: 1,
|
|
4450
|
+
background: theme.textMuted + "30",
|
|
4451
|
+
marginLeft: -2,
|
|
4452
|
+
marginRight: 4
|
|
4453
|
+
}
|
|
4454
|
+
}
|
|
4455
|
+
)
|
|
4456
|
+
]
|
|
4457
|
+
}
|
|
4458
|
+
)
|
|
4459
|
+
]
|
|
4460
|
+
}
|
|
4461
|
+
),
|
|
4462
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { style: { padding: "0 12px 8px" }, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4463
|
+
GanttTimeline,
|
|
4464
|
+
{
|
|
4465
|
+
snapshots,
|
|
4466
|
+
selectedIndex
|
|
4467
|
+
}
|
|
4468
|
+
) })
|
|
4469
|
+
] });
|
|
4470
|
+
});
|
|
4471
|
+
|
|
4472
|
+
// src/components/ExplainableShell/ExplainableShell.tsx
|
|
4473
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
4474
|
+
var HLinePill = (0, import_react24.memo)(function HLinePill2({
|
|
4003
4475
|
label,
|
|
4004
4476
|
detail,
|
|
4005
4477
|
expanded,
|
|
4006
4478
|
onClick
|
|
4007
4479
|
}) {
|
|
4008
|
-
return /* @__PURE__ */ (0,
|
|
4480
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: {
|
|
4009
4481
|
display: "flex",
|
|
4010
4482
|
alignItems: "center",
|
|
4011
4483
|
gap: 0,
|
|
4012
4484
|
padding: "0"
|
|
4013
4485
|
}, children: [
|
|
4014
|
-
/* @__PURE__ */ (0,
|
|
4015
|
-
/* @__PURE__ */ (0,
|
|
4486
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, height: 1, background: theme.border } }),
|
|
4487
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4016
4488
|
"button",
|
|
4017
4489
|
{
|
|
4018
4490
|
onClick,
|
|
@@ -4036,31 +4508,31 @@ var HLinePill = (0, import_react20.memo)(function HLinePill2({
|
|
|
4036
4508
|
transition: "color 0.15s ease"
|
|
4037
4509
|
},
|
|
4038
4510
|
children: [
|
|
4039
|
-
/* @__PURE__ */ (0,
|
|
4511
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 7 }, children: expanded ? "\u25BC" : "\u25B6" }),
|
|
4040
4512
|
label,
|
|
4041
|
-
detail && /* @__PURE__ */ (0,
|
|
4513
|
+
detail && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontWeight: 400, opacity: 0.5, fontSize: 9 }, children: detail })
|
|
4042
4514
|
]
|
|
4043
4515
|
}
|
|
4044
4516
|
),
|
|
4045
|
-
/* @__PURE__ */ (0,
|
|
4517
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, height: 1, background: theme.border } })
|
|
4046
4518
|
] });
|
|
4047
4519
|
});
|
|
4048
|
-
var VLinePill = (0,
|
|
4520
|
+
var VLinePill = (0, import_react24.memo)(function VLinePill2({
|
|
4049
4521
|
label,
|
|
4050
4522
|
expanded,
|
|
4051
4523
|
side = "right",
|
|
4052
4524
|
onClick
|
|
4053
4525
|
}) {
|
|
4054
4526
|
const arrow = side === "right" ? expanded ? "\u25B6" : "\u25C0" : expanded ? "\u25C0" : "\u25B6";
|
|
4055
|
-
return /* @__PURE__ */ (0,
|
|
4527
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: {
|
|
4056
4528
|
display: "flex",
|
|
4057
4529
|
flexDirection: "column",
|
|
4058
4530
|
alignItems: "center",
|
|
4059
4531
|
gap: 0,
|
|
4060
4532
|
padding: "0"
|
|
4061
4533
|
}, children: [
|
|
4062
|
-
/* @__PURE__ */ (0,
|
|
4063
|
-
/* @__PURE__ */ (0,
|
|
4534
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, width: 1, background: theme.border } }),
|
|
4535
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4064
4536
|
"button",
|
|
4065
4537
|
{
|
|
4066
4538
|
onClick,
|
|
@@ -4085,12 +4557,12 @@ var VLinePill = (0, import_react20.memo)(function VLinePill2({
|
|
|
4085
4557
|
transition: "color 0.15s ease"
|
|
4086
4558
|
},
|
|
4087
4559
|
children: [
|
|
4088
|
-
/* @__PURE__ */ (0,
|
|
4560
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: 7, writingMode: "horizontal-tb" }, children: arrow }),
|
|
4089
4561
|
label
|
|
4090
4562
|
]
|
|
4091
4563
|
}
|
|
4092
4564
|
),
|
|
4093
|
-
/* @__PURE__ */ (0,
|
|
4565
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, width: 1, background: theme.border } })
|
|
4094
4566
|
] });
|
|
4095
4567
|
});
|
|
4096
4568
|
function detectKeyedSteps(data) {
|
|
@@ -4127,9 +4599,9 @@ function KeyedRecorderView({
|
|
|
4127
4599
|
snapshots,
|
|
4128
4600
|
selectedIndex
|
|
4129
4601
|
}) {
|
|
4130
|
-
const [showAggregate, setShowAggregate] = (0,
|
|
4131
|
-
const detected = (0,
|
|
4132
|
-
const visibleKeys = (0,
|
|
4602
|
+
const [showAggregate, setShowAggregate] = (0, import_react24.useState)(false);
|
|
4603
|
+
const detected = (0, import_react24.useMemo)(() => detectKeyedSteps(data), [data]);
|
|
4604
|
+
const visibleKeys = (0, import_react24.useMemo)(() => {
|
|
4133
4605
|
const keys = /* @__PURE__ */ new Set();
|
|
4134
4606
|
for (let i = 0; i <= selectedIndex && i < snapshots.length; i++) {
|
|
4135
4607
|
const snap = snapshots[i];
|
|
@@ -4144,7 +4616,7 @@ function KeyedRecorderView({
|
|
|
4144
4616
|
}, [snapshots, selectedIndex, detected?.keyType]);
|
|
4145
4617
|
const isAtEnd = selectedIndex >= snapshots.length - 1;
|
|
4146
4618
|
if (!detected) {
|
|
4147
|
-
return /* @__PURE__ */ (0,
|
|
4619
|
+
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
4620
|
}
|
|
4149
4621
|
const steps = detected.steps;
|
|
4150
4622
|
const hints = extractRenderHints(data);
|
|
@@ -4158,13 +4630,13 @@ function KeyedRecorderView({
|
|
|
4158
4630
|
}
|
|
4159
4631
|
}
|
|
4160
4632
|
const grandTotal = hints?.grandTotal ?? 0;
|
|
4161
|
-
return /* @__PURE__ */ (0,
|
|
4162
|
-
description && /* @__PURE__ */ (0,
|
|
4163
|
-
/* @__PURE__ */ (0,
|
|
4633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { overflow: "auto", height: "100%", display: "flex", flexDirection: "column" }, children: [
|
|
4634
|
+
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 }),
|
|
4635
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { padding: 12, flex: 1, overflow: "auto" }, children: [
|
|
4164
4636
|
preferredOperation === "aggregate" ? (
|
|
4165
4637
|
/* AGGREGATE: collect silently during scrub, button at end to reveal total */
|
|
4166
|
-
/* @__PURE__ */ (0,
|
|
4167
|
-
isAtEnd ? /* @__PURE__ */ (0,
|
|
4638
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4639
|
+
isAtEnd ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { marginBottom: 16 }, children: !showAggregate ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4168
4640
|
"button",
|
|
4169
4641
|
{
|
|
4170
4642
|
onClick: () => setShowAggregate(true),
|
|
@@ -4182,35 +4654,35 @@ function KeyedRecorderView({
|
|
|
4182
4654
|
},
|
|
4183
4655
|
children: "Aggregate \u2014 Show Grand Total"
|
|
4184
4656
|
}
|
|
4185
|
-
) : /* @__PURE__ */ (0,
|
|
4186
|
-
/* @__PURE__ */ (0,
|
|
4187
|
-
numFieldKey && /* @__PURE__ */ (0,
|
|
4657
|
+
) : /* @__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: [
|
|
4658
|
+
/* @__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" }),
|
|
4659
|
+
numFieldKey && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: 26, fontWeight: 700, color: theme.success }, children: [
|
|
4188
4660
|
grandTotal < 1 ? grandTotal.toFixed(3) : grandTotal.toFixed(1),
|
|
4189
|
-
/* @__PURE__ */ (0,
|
|
4661
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { fontSize: 11, color: theme.textMuted, fontWeight: 400, marginLeft: 8 }, children: [
|
|
4190
4662
|
numFieldKey,
|
|
4191
4663
|
" \xB7 ",
|
|
4192
4664
|
allKeys.length,
|
|
4193
4665
|
" steps"
|
|
4194
4666
|
] })
|
|
4195
4667
|
] })
|
|
4196
|
-
] }) }) : /* @__PURE__ */ (0,
|
|
4197
|
-
/* @__PURE__ */ (0,
|
|
4198
|
-
/* @__PURE__ */ (0,
|
|
4668
|
+
] }) }) : /* @__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: [
|
|
4669
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { fontSize: 10, color: theme.textMuted, textTransform: "uppercase", letterSpacing: "0.08em", fontWeight: 600 }, children: "Collecting data..." }),
|
|
4670
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { fontSize: 11, color: theme.textMuted, marginTop: 4 }, children: [
|
|
4199
4671
|
visibleEntries.length,
|
|
4200
4672
|
" of ",
|
|
4201
4673
|
allKeys.length,
|
|
4202
4674
|
" steps collected. Scrub to end to aggregate."
|
|
4203
4675
|
] })
|
|
4204
4676
|
] }),
|
|
4205
|
-
/* @__PURE__ */ (0,
|
|
4677
|
+
/* @__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
4678
|
] })
|
|
4207
4679
|
) : preferredOperation === "accumulate" ? (
|
|
4208
4680
|
/* 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,
|
|
4681
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4682
|
+
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: [
|
|
4683
|
+
/* @__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" }),
|
|
4684
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontWeight: 700, fontSize: 18, color: theme.primary }, children: runningTotal < 1 ? runningTotal.toFixed(3) : runningTotal.toFixed(1) }),
|
|
4685
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("span", { style: { color: theme.textMuted, marginLeft: 8, fontSize: 10 }, children: [
|
|
4214
4686
|
numFieldKey,
|
|
4215
4687
|
" \xB7 ",
|
|
4216
4688
|
visibleEntries.length,
|
|
@@ -4219,27 +4691,27 @@ function KeyedRecorderView({
|
|
|
4219
4691
|
" steps"
|
|
4220
4692
|
] })
|
|
4221
4693
|
] }),
|
|
4222
|
-
/* @__PURE__ */ (0,
|
|
4694
|
+
/* @__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
4695
|
] })
|
|
4224
4696
|
) : (
|
|
4225
4697
|
/* TRANSLATE: per-step entries prominent, no totals */
|
|
4226
|
-
/* @__PURE__ */ (0,
|
|
4698
|
+
/* @__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
4699
|
),
|
|
4228
4700
|
visibleEntries.map((key) => {
|
|
4229
4701
|
const entry = steps[key];
|
|
4230
4702
|
const label = entry.stageName ?? key;
|
|
4231
4703
|
const numVal = numFieldKey ? entry[numFieldKey] : void 0;
|
|
4232
|
-
return /* @__PURE__ */ (0,
|
|
4233
|
-
/* @__PURE__ */ (0,
|
|
4234
|
-
/* @__PURE__ */ (0,
|
|
4235
|
-
numVal !== void 0 && /* @__PURE__ */ (0,
|
|
4704
|
+
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: [
|
|
4705
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { color: theme.textMuted, width: 140, flexShrink: 0, fontSize: 10 }, children: key }),
|
|
4706
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontWeight: 600, flex: 1 }, children: label }),
|
|
4707
|
+
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
4708
|
] }, key);
|
|
4237
4709
|
}),
|
|
4238
|
-
visibleEntries.length === 0 && /* @__PURE__ */ (0,
|
|
4710
|
+
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
4711
|
] })
|
|
4240
4712
|
] });
|
|
4241
4713
|
}
|
|
4242
|
-
var DetailsContent = (0,
|
|
4714
|
+
var DetailsContent = (0, import_react24.memo)(function DetailsContent2({
|
|
4243
4715
|
snapshots,
|
|
4244
4716
|
selectedIndex,
|
|
4245
4717
|
narrativeEntries,
|
|
@@ -4252,27 +4724,27 @@ var DetailsContent = (0, import_react20.memo)(function DetailsContent2({
|
|
|
4252
4724
|
{
|
|
4253
4725
|
id: "memory",
|
|
4254
4726
|
name: "Memory",
|
|
4255
|
-
render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ (0,
|
|
4727
|
+
render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MemoryPanel, { snapshots: snaps, selectedIndex: idx, size, style: fillHeight ? { height: "100%" } : void 0 })
|
|
4256
4728
|
},
|
|
4257
4729
|
{
|
|
4258
4730
|
id: "narrative",
|
|
4259
4731
|
name: "Narrative",
|
|
4260
|
-
render: ({ snapshots: snaps, selectedIndex: idx }) => /* @__PURE__ */ (0,
|
|
4732
|
+
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
4733
|
}
|
|
4262
4734
|
];
|
|
4263
4735
|
const allViews = [...builtInViews, ...extraViews ?? []];
|
|
4264
|
-
const [activeViewId, setActiveViewId] = (0,
|
|
4736
|
+
const [activeViewId, setActiveViewId] = (0, import_react24.useState)(allViews[0]?.id ?? "memory");
|
|
4265
4737
|
const viewIds = allViews.map((v2) => v2.id).join(",");
|
|
4266
|
-
(0,
|
|
4738
|
+
(0, import_react24.useEffect)(() => {
|
|
4267
4739
|
if (!allViews.find((v2) => v2.id === activeViewId)) {
|
|
4268
4740
|
setActiveViewId(allViews[0]?.id ?? "memory");
|
|
4269
4741
|
}
|
|
4270
4742
|
}, [viewIds]);
|
|
4271
4743
|
const activeView = allViews.find((v2) => v2.id === activeViewId) ?? allViews[0];
|
|
4272
|
-
return /* @__PURE__ */ (0,
|
|
4273
|
-
/* @__PURE__ */ (0,
|
|
4744
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }, children: [
|
|
4745
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { display: "flex", borderBottom: `1px solid ${theme.border}`, flexShrink: 0, overflowX: "auto" }, children: allViews.map((view) => {
|
|
4274
4746
|
const active = view.id === activeViewId;
|
|
4275
|
-
return /* @__PURE__ */ (0,
|
|
4747
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4276
4748
|
"button",
|
|
4277
4749
|
{
|
|
4278
4750
|
onClick: () => setActiveViewId(view.id),
|
|
@@ -4296,7 +4768,7 @@ var DetailsContent = (0, import_react20.memo)(function DetailsContent2({
|
|
|
4296
4768
|
view.id
|
|
4297
4769
|
);
|
|
4298
4770
|
}) }),
|
|
4299
|
-
/* @__PURE__ */ (0,
|
|
4771
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: activeView?.render({ snapshots, selectedIndex }) })
|
|
4300
4772
|
] });
|
|
4301
4773
|
});
|
|
4302
4774
|
function resolveSubflowLevel(parentSpec, parentSnapshots, subflowNodeName, narrativeEntries) {
|
|
@@ -4336,8 +4808,52 @@ function hasSubflowNodes(node) {
|
|
|
4336
4808
|
if (node.next && hasSubflowNodes(node.next)) return true;
|
|
4337
4809
|
return false;
|
|
4338
4810
|
}
|
|
4811
|
+
function buildDataTrace(commitLog, targetRuntimeStageId, maxDepth = 10) {
|
|
4812
|
+
const log = commitLog;
|
|
4813
|
+
if (!log?.length) return [];
|
|
4814
|
+
const idxMap = /* @__PURE__ */ new Map();
|
|
4815
|
+
for (let i = 0; i < log.length; i++) idxMap.set(log[i].runtimeStageId, i);
|
|
4816
|
+
const startIdx = idxMap.get(targetRuntimeStageId);
|
|
4817
|
+
if (startIdx === void 0) return [];
|
|
4818
|
+
const startCommit = log[startIdx];
|
|
4819
|
+
const frames = [];
|
|
4820
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4821
|
+
let current = startCommit;
|
|
4822
|
+
let currentIdx = startIdx;
|
|
4823
|
+
let depth = 0;
|
|
4824
|
+
while (current && depth <= maxDepth) {
|
|
4825
|
+
if (visited.has(current.runtimeStageId)) break;
|
|
4826
|
+
visited.add(current.runtimeStageId);
|
|
4827
|
+
frames.push({
|
|
4828
|
+
runtimeStageId: current.runtimeStageId,
|
|
4829
|
+
stageId: current.stageId,
|
|
4830
|
+
stageName: current.stage,
|
|
4831
|
+
keysWritten: current.trace.map((t) => t.path),
|
|
4832
|
+
linkedBy: depth === 0 ? "" : current.trace[0]?.path ?? "",
|
|
4833
|
+
depth
|
|
4834
|
+
});
|
|
4835
|
+
if (currentIdx > 0) {
|
|
4836
|
+
currentIdx--;
|
|
4837
|
+
current = log[currentIdx];
|
|
4838
|
+
depth++;
|
|
4839
|
+
} else {
|
|
4840
|
+
break;
|
|
4841
|
+
}
|
|
4842
|
+
}
|
|
4843
|
+
return frames;
|
|
4844
|
+
}
|
|
4845
|
+
function insightName(name) {
|
|
4846
|
+
const map = {
|
|
4847
|
+
"Narrative": "Story",
|
|
4848
|
+
"Memory": "State",
|
|
4849
|
+
"Metrics": "Performance",
|
|
4850
|
+
"Quality": "Quality",
|
|
4851
|
+
"Cost": "Cost"
|
|
4852
|
+
};
|
|
4853
|
+
return map[name] ?? name;
|
|
4854
|
+
}
|
|
4339
4855
|
function defaultRenderFlowchart({ spec: s, snapshots: snaps, selectedIndex, onNodeClick }) {
|
|
4340
|
-
return /* @__PURE__ */ (0,
|
|
4856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4341
4857
|
TracedFlowchartView,
|
|
4342
4858
|
{
|
|
4343
4859
|
spec: s,
|
|
@@ -4369,7 +4885,7 @@ function ExplainableShell({
|
|
|
4369
4885
|
className,
|
|
4370
4886
|
style
|
|
4371
4887
|
}) {
|
|
4372
|
-
const derivedFromRuntime = (0,
|
|
4888
|
+
const derivedFromRuntime = (0, import_react24.useMemo)(() => {
|
|
4373
4889
|
if (!runtimeSnapshot) return null;
|
|
4374
4890
|
try {
|
|
4375
4891
|
const snaps = toVisualizationSnapshots(runtimeSnapshot, narrativeEntries);
|
|
@@ -4390,26 +4906,29 @@ function ExplainableShell({
|
|
|
4390
4906
|
const leftLabel = panelLabels?.topology ?? "Topology";
|
|
4391
4907
|
const rightLabel = panelLabels?.details ?? "Details";
|
|
4392
4908
|
const bottomLabel = panelLabels?.timeline ?? "Timeline";
|
|
4393
|
-
const shellRef = (0,
|
|
4394
|
-
const [isNarrow, setIsNarrow] = (0,
|
|
4395
|
-
(0,
|
|
4909
|
+
const shellRef = (0, import_react24.useRef)(null);
|
|
4910
|
+
const [isNarrow, setIsNarrow] = (0, import_react24.useState)(false);
|
|
4911
|
+
const [isMedium, setIsMedium] = (0, import_react24.useState)(false);
|
|
4912
|
+
(0, import_react24.useEffect)(() => {
|
|
4396
4913
|
const el = shellRef.current;
|
|
4397
4914
|
if (!el) return;
|
|
4398
4915
|
const ro = new ResizeObserver(([entry]) => {
|
|
4399
|
-
|
|
4916
|
+
const w = entry.contentRect.width;
|
|
4917
|
+
setIsNarrow(w < 640);
|
|
4918
|
+
setIsMedium(w >= 640 && w < 960);
|
|
4400
4919
|
window.dispatchEvent(new Event("resize"));
|
|
4401
4920
|
});
|
|
4402
4921
|
ro.observe(el);
|
|
4403
4922
|
return () => ro.disconnect();
|
|
4404
4923
|
}, []);
|
|
4405
|
-
const autoRecorderViews = (0,
|
|
4924
|
+
const autoRecorderViews = (0, import_react24.useMemo)(() => {
|
|
4406
4925
|
const recorders = runtimeSnapshot?.recorders;
|
|
4407
4926
|
if (!recorders?.length) return [];
|
|
4408
4927
|
const explicitIds = new Set((recorderViews ?? []).map((v2) => v2.id));
|
|
4409
4928
|
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
4929
|
}, [runtimeSnapshot, recorderViews]);
|
|
4411
4930
|
const hasNarrative = !!(narrative?.length || narrativeEntries?.length);
|
|
4412
|
-
const allTabs = (0,
|
|
4931
|
+
const allTabs = (0, import_react24.useMemo)(() => {
|
|
4413
4932
|
const tabs2 = [
|
|
4414
4933
|
{ id: "result", name: "Result", description: "Final output and console logs" },
|
|
4415
4934
|
{ id: "memory", name: "Memory", description: "Accumulator \u2014 progressive shared state at each stage" }
|
|
@@ -4428,37 +4947,37 @@ function ExplainableShell({
|
|
|
4428
4947
|
}, [hasNarrative, recorderViews, autoRecorderViews, hideTabsProp]);
|
|
4429
4948
|
const validTabIds = new Set(allTabs.map((t) => t.id));
|
|
4430
4949
|
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 [leftExpanded, setLeftExpanded] = (0,
|
|
4436
|
-
const [timelineExpanded, setTimelineExpanded] = (0,
|
|
4437
|
-
(0,
|
|
4950
|
+
const [activeTab, setActiveTab] = (0, import_react24.useState)(resolvedDefault);
|
|
4951
|
+
const [snapshotIdx, setSnapshotIdx] = (0, import_react24.useState)(0);
|
|
4952
|
+
const [drillDownStack, setDrillDownStack] = (0, import_react24.useState)([]);
|
|
4953
|
+
const [rightExpanded, setRightExpanded] = (0, import_react24.useState)(defaultExpanded?.details ?? true);
|
|
4954
|
+
const [leftExpanded, setLeftExpanded] = (0, import_react24.useState)(defaultExpanded?.topology ?? false);
|
|
4955
|
+
const [timelineExpanded, setTimelineExpanded] = (0, import_react24.useState)(defaultExpanded?.timeline ?? false);
|
|
4956
|
+
(0, import_react24.useEffect)(() => {
|
|
4438
4957
|
if (isNarrow) {
|
|
4439
4958
|
setLeftExpanded(false);
|
|
4440
4959
|
setRightExpanded(false);
|
|
4441
4960
|
setTimelineExpanded(false);
|
|
4442
4961
|
}
|
|
4443
4962
|
}, [isNarrow]);
|
|
4444
|
-
const triggerReflow = (0,
|
|
4963
|
+
const triggerReflow = (0, import_react24.useCallback)(() => {
|
|
4445
4964
|
requestAnimationFrame(() => window.dispatchEvent(new Event("resize")));
|
|
4446
4965
|
setTimeout(() => window.dispatchEvent(new Event("resize")), 320);
|
|
4447
4966
|
}, []);
|
|
4448
|
-
const toggleLeft = (0,
|
|
4967
|
+
const toggleLeft = (0, import_react24.useCallback)((v2) => {
|
|
4449
4968
|
setLeftExpanded(v2);
|
|
4450
4969
|
triggerReflow();
|
|
4451
4970
|
}, [triggerReflow]);
|
|
4452
|
-
const toggleRight = (0,
|
|
4971
|
+
const toggleRight = (0, import_react24.useCallback)((v2) => {
|
|
4453
4972
|
setRightExpanded(v2);
|
|
4454
4973
|
triggerReflow();
|
|
4455
4974
|
}, [triggerReflow]);
|
|
4456
|
-
const toggleTimeline = (0,
|
|
4975
|
+
const toggleTimeline = (0, import_react24.useCallback)(() => {
|
|
4457
4976
|
setTimelineExpanded((p) => !p);
|
|
4458
4977
|
triggerReflow();
|
|
4459
4978
|
}, [triggerReflow]);
|
|
4460
4979
|
const isInSubflow = drillDownStack.length > 0;
|
|
4461
|
-
const currentLevel = (0,
|
|
4980
|
+
const currentLevel = (0, import_react24.useMemo)(() => {
|
|
4462
4981
|
if (drillDownStack.length > 0) {
|
|
4463
4982
|
const top = drillDownStack[drillDownStack.length - 1];
|
|
4464
4983
|
return { spec: top.spec, snapshots: top.snapshots };
|
|
@@ -4468,7 +4987,7 @@ function ExplainableShell({
|
|
|
4468
4987
|
const activeSnapshots = currentLevel.snapshots;
|
|
4469
4988
|
const activeSpec = currentLevel.spec;
|
|
4470
4989
|
const safeIdx = activeSnapshots.length > 0 ? Math.max(0, Math.min(snapshotIdx, activeSnapshots.length - 1)) : 0;
|
|
4471
|
-
const activeNarrative = (0,
|
|
4990
|
+
const activeNarrative = (0, import_react24.useMemo)(() => {
|
|
4472
4991
|
if (!isInSubflow) return narrative;
|
|
4473
4992
|
const lines = [];
|
|
4474
4993
|
for (const snap of activeSnapshots) {
|
|
@@ -4478,25 +4997,25 @@ function ExplainableShell({
|
|
|
4478
4997
|
return lines.length > 0 ? lines : void 0;
|
|
4479
4998
|
}, [isInSubflow, narrative, activeSnapshots]);
|
|
4480
4999
|
const activeNarrativeEntries = isInSubflow ? void 0 : narrativeEntries;
|
|
4481
|
-
const breadcrumbs = (0,
|
|
5000
|
+
const breadcrumbs = (0, import_react24.useMemo)(() => {
|
|
4482
5001
|
const root = { label: title || "Flowchart", spec, description: spec?.description };
|
|
4483
5002
|
return [root, ...drillDownStack.map((e) => ({ label: e.label, spec: e.spec, description: void 0 }))];
|
|
4484
5003
|
}, [spec, title, drillDownStack]);
|
|
4485
|
-
const showTreeSidebar = (0,
|
|
4486
|
-
const rootOverlay = (0,
|
|
5004
|
+
const showTreeSidebar = (0, import_react24.useMemo)(() => !!spec && hasSubflowNodes(spec), [spec]);
|
|
5005
|
+
const rootOverlay = (0, import_react24.useMemo)(() => {
|
|
4487
5006
|
if (isInSubflow || !snapshots.length) return { activeStage: void 0, doneStages: void 0 };
|
|
4488
5007
|
const doneStages = new Set(snapshots.slice(0, safeIdx).map((s) => s.stageLabel));
|
|
4489
5008
|
const activeStage = snapshots[safeIdx]?.stageLabel ?? null;
|
|
4490
5009
|
return { activeStage, doneStages };
|
|
4491
5010
|
}, [isInSubflow, snapshots, safeIdx]);
|
|
4492
|
-
const handleTabChange = (0,
|
|
5011
|
+
const handleTabChange = (0, import_react24.useCallback)((tab) => {
|
|
4493
5012
|
setActiveTab(tab);
|
|
4494
5013
|
setDrillDownStack([]);
|
|
4495
5014
|
}, []);
|
|
4496
|
-
const handleSnapshotChange = (0,
|
|
5015
|
+
const handleSnapshotChange = (0, import_react24.useCallback)((idx) => {
|
|
4497
5016
|
if (typeof idx === "number") setSnapshotIdx(idx);
|
|
4498
5017
|
}, []);
|
|
4499
|
-
const handleDrillDown = (0,
|
|
5018
|
+
const handleDrillDown = (0, import_react24.useCallback)(
|
|
4500
5019
|
(nodeName) => {
|
|
4501
5020
|
if (!activeSpec) return;
|
|
4502
5021
|
const entry = resolveSubflowLevel(activeSpec, activeSnapshots, nodeName, narrativeEntries);
|
|
@@ -4507,14 +5026,14 @@ function ExplainableShell({
|
|
|
4507
5026
|
},
|
|
4508
5027
|
[activeSpec, activeSnapshots, narrativeEntries, snapshotIdx]
|
|
4509
5028
|
);
|
|
4510
|
-
const handleBreadcrumbNavigate = (0,
|
|
5029
|
+
const handleBreadcrumbNavigate = (0, import_react24.useCallback)((level) => {
|
|
4511
5030
|
setDrillDownStack((prev) => {
|
|
4512
5031
|
const popped = level === 0 ? prev[0] : prev[level];
|
|
4513
5032
|
if (popped) setSnapshotIdx(popped.parentSnapshotIdx);
|
|
4514
5033
|
return level === 0 ? [] : prev.slice(0, level);
|
|
4515
5034
|
});
|
|
4516
5035
|
}, []);
|
|
4517
|
-
const handleNodeClick = (0,
|
|
5036
|
+
const handleNodeClick = (0, import_react24.useCallback)(
|
|
4518
5037
|
(indexOrId) => {
|
|
4519
5038
|
if (typeof indexOrId === "number") {
|
|
4520
5039
|
setSnapshotIdx(indexOrId);
|
|
@@ -4532,7 +5051,7 @@ function ExplainableShell({
|
|
|
4532
5051
|
},
|
|
4533
5052
|
[activeSpec, activeSnapshots, handleDrillDown]
|
|
4534
5053
|
);
|
|
4535
|
-
const handleTreeNodeSelect = (0,
|
|
5054
|
+
const handleTreeNodeSelect = (0, import_react24.useCallback)(
|
|
4536
5055
|
(name, isSubflow) => {
|
|
4537
5056
|
if (isSubflow && spec) {
|
|
4538
5057
|
setDrillDownStack([]);
|
|
@@ -4551,31 +5070,31 @@ function ExplainableShell({
|
|
|
4551
5070
|
);
|
|
4552
5071
|
const tabLabels = new Map(allTabs.map((t) => [t.id, t.name]));
|
|
4553
5072
|
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,
|
|
5073
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className, style, "data-fp": "explainable-shell", children: [
|
|
5074
|
+
/* @__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)) }),
|
|
5075
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { "data-fp": "shell-content", "data-tab": activeTab, children: [
|
|
5076
|
+
activeTab === "result" && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ResultPanel, { data: resultData ?? null, logs, hideConsole, unstyled: true }),
|
|
5077
|
+
(activeTab === "explainable" || activeTab === "ai-compatible") && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
5078
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(TimeTravelControls, { snapshots: activeSnapshots, selectedIndex: safeIdx, onIndexChange: handleSnapshotChange, unstyled: true }),
|
|
5079
|
+
isInSubflow && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
|
|
4561
5080
|
activeSpec && effectiveRenderFlowchart?.({ spec: activeSpec, snapshots: activeSnapshots, selectedIndex: safeIdx, onNodeClick: handleNodeClick }),
|
|
4562
|
-
/* @__PURE__ */ (0,
|
|
4563
|
-
/* @__PURE__ */ (0,
|
|
4564
|
-
/* @__PURE__ */ (0,
|
|
5081
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, unstyled: true }),
|
|
5082
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, narrative: activeNarrative, unstyled: true }),
|
|
5083
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(GanttTimeline, { snapshots: activeSnapshots, selectedIndex: safeIdx, onSelect: handleSnapshotChange, unstyled: true })
|
|
4565
5084
|
] })
|
|
4566
5085
|
] })
|
|
4567
5086
|
] });
|
|
4568
5087
|
}
|
|
4569
5088
|
const showTopology = !!effectiveRenderFlowchart && !!activeSpec;
|
|
4570
|
-
const detailsContent = (0,
|
|
5089
|
+
const detailsContent = (0, import_react24.useMemo)(() => {
|
|
4571
5090
|
if (activeTab === "result") {
|
|
4572
|
-
return /* @__PURE__ */ (0,
|
|
5091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(ResultPanel, { data: resultData ?? null, logs, hideConsole, size });
|
|
4573
5092
|
}
|
|
4574
5093
|
if (activeTab === "memory") {
|
|
4575
|
-
return /* @__PURE__ */ (0,
|
|
5094
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, size, style: { height: "100%" } });
|
|
4576
5095
|
}
|
|
4577
5096
|
if (activeTab === "narrative") {
|
|
4578
|
-
return /* @__PURE__ */ (0,
|
|
5097
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, narrative: activeNarrative, size, style: { height: "100%" } });
|
|
4579
5098
|
}
|
|
4580
5099
|
const customView = recorderViews?.find((v2) => v2.id === activeTab);
|
|
4581
5100
|
if (customView?.render) {
|
|
@@ -4583,7 +5102,7 @@ function ExplainableShell({
|
|
|
4583
5102
|
}
|
|
4584
5103
|
const autoView = autoRecorderViews.find((v2) => v2.id === activeTab);
|
|
4585
5104
|
if (autoView) {
|
|
4586
|
-
return /* @__PURE__ */ (0,
|
|
5105
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4587
5106
|
KeyedRecorderView,
|
|
4588
5107
|
{
|
|
4589
5108
|
data: autoView.data,
|
|
@@ -4596,8 +5115,8 @@ function ExplainableShell({
|
|
|
4596
5115
|
}
|
|
4597
5116
|
return null;
|
|
4598
5117
|
}, [activeTab, resultData, logs, hideConsole, size, activeSnapshots, safeIdx, activeNarrativeEntries, activeNarrative, recorderViews, autoRecorderViews]);
|
|
4599
|
-
const detailsPanel = /* @__PURE__ */ (0,
|
|
4600
|
-
/* @__PURE__ */ (0,
|
|
5118
|
+
const detailsPanel = /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { display: "flex", flexDirection: "column", height: "100%", overflow: "hidden" }, children: [
|
|
5119
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: {
|
|
4601
5120
|
display: "flex",
|
|
4602
5121
|
borderBottom: `1px solid ${theme.border}`,
|
|
4603
5122
|
background: theme.bgSecondary,
|
|
@@ -4605,7 +5124,7 @@ function ExplainableShell({
|
|
|
4605
5124
|
overflowX: "auto"
|
|
4606
5125
|
}, children: allTabs.map((tab) => {
|
|
4607
5126
|
const active = tab.id === activeTab;
|
|
4608
|
-
return /* @__PURE__ */ (0,
|
|
5127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4609
5128
|
"button",
|
|
4610
5129
|
{
|
|
4611
5130
|
onClick: () => handleTabChange(tab.id),
|
|
@@ -4629,9 +5148,9 @@ function ExplainableShell({
|
|
|
4629
5148
|
tab.id
|
|
4630
5149
|
);
|
|
4631
5150
|
}) }),
|
|
4632
|
-
/* @__PURE__ */ (0,
|
|
5151
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: "auto" }, children: detailsContent })
|
|
4633
5152
|
] });
|
|
4634
|
-
return /* @__PURE__ */ (0,
|
|
5153
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
4635
5154
|
"div",
|
|
4636
5155
|
{
|
|
4637
5156
|
ref: shellRef,
|
|
@@ -4649,7 +5168,7 @@ function ExplainableShell({
|
|
|
4649
5168
|
},
|
|
4650
5169
|
"data-fp": "explainable-shell",
|
|
4651
5170
|
children: [
|
|
4652
|
-
/* @__PURE__ */ (0,
|
|
5171
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4653
5172
|
TimeTravelControls,
|
|
4654
5173
|
{
|
|
4655
5174
|
snapshots: activeSnapshots,
|
|
@@ -4658,19 +5177,19 @@ function ExplainableShell({
|
|
|
4658
5177
|
size
|
|
4659
5178
|
}
|
|
4660
5179
|
),
|
|
4661
|
-
isInSubflow && /* @__PURE__ */ (0,
|
|
4662
|
-
/* @__PURE__ */ (0,
|
|
5180
|
+
isInSubflow && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(SubflowBreadcrumb, { breadcrumbs, onNavigate: handleBreadcrumbNavigate }),
|
|
5181
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: isNarrow ? "auto" : "hidden", display: "flex", flexDirection: "column" }, children: isNarrow ? (
|
|
4663
5182
|
/* ── Mobile: stacked vertical ── */
|
|
4664
|
-
/* @__PURE__ */ (0,
|
|
4665
|
-
showTopology && /* @__PURE__ */ (0,
|
|
5183
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
5184
|
+
showTopology && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { height: 350, flexShrink: 0, overflow: "hidden" }, children: effectiveRenderFlowchart({
|
|
4666
5185
|
spec: activeSpec,
|
|
4667
5186
|
snapshots: activeSnapshots,
|
|
4668
5187
|
selectedIndex: safeIdx,
|
|
4669
5188
|
onNodeClick: handleNodeClick
|
|
4670
5189
|
}) }),
|
|
4671
|
-
showTreeSidebar && /* @__PURE__ */ (0,
|
|
4672
|
-
/* @__PURE__ */ (0,
|
|
4673
|
-
leftExpanded && /* @__PURE__ */ (0,
|
|
5190
|
+
showTreeSidebar && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
5191
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(HLinePill, { label: leftLabel, expanded: leftExpanded, onClick: () => toggleLeft(!leftExpanded) }),
|
|
5192
|
+
leftExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { maxHeight: 180, overflow: "auto", flexShrink: 0 }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4674
5193
|
SubflowTree,
|
|
4675
5194
|
{
|
|
4676
5195
|
spec,
|
|
@@ -4680,47 +5199,72 @@ function ExplainableShell({
|
|
|
4680
5199
|
}
|
|
4681
5200
|
) })
|
|
4682
5201
|
] }),
|
|
4683
|
-
/* @__PURE__ */ (0,
|
|
4684
|
-
rightExpanded && /* @__PURE__ */ (0,
|
|
4685
|
-
/* @__PURE__ */ (0,
|
|
4686
|
-
timelineExpanded && /* @__PURE__ */ (0,
|
|
5202
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(HLinePill, { label: rightLabel, expanded: rightExpanded, onClick: () => toggleRight(!rightExpanded) }),
|
|
5203
|
+
rightExpanded && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { maxHeight: 350, flexShrink: 0, overflow: "hidden" }, children: detailsPanel }),
|
|
5204
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(HLinePill, { label: bottomLabel, detail: `${activeSnapshots.length} stages`, expanded: timelineExpanded, onClick: toggleTimeline }),
|
|
5205
|
+
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
5206
|
] })
|
|
4688
|
-
) :
|
|
4689
|
-
/* ── Desktop
|
|
4690
|
-
/* @__PURE__ */ (0,
|
|
4691
|
-
/* @__PURE__ */ (0,
|
|
4692
|
-
|
|
4693
|
-
/* @__PURE__ */ (0,
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
5207
|
+
) : (
|
|
5208
|
+
/* ── Desktop: responsive layout ── */
|
|
5209
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
5210
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { flex: 1, display: "flex", overflow: "hidden" }, children: [
|
|
5211
|
+
showTopology && !isMedium && (leftExpanded ? /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { style: { width: 280, flexShrink: 0, display: "flex", flexDirection: "row", overflow: "hidden" }, children: [
|
|
5212
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: "hidden" }, children: effectiveRenderFlowchart({
|
|
5213
|
+
spec: activeSpec,
|
|
5214
|
+
snapshots: activeSnapshots,
|
|
5215
|
+
selectedIndex: safeIdx,
|
|
5216
|
+
onNodeClick: handleNodeClick
|
|
5217
|
+
}) }),
|
|
5218
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(VLinePill, { label: leftLabel, expanded: true, side: "left", onClick: () => toggleLeft(false) })
|
|
5219
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(VLinePill, { label: leftLabel, expanded: false, side: "left", onClick: () => toggleLeft(true) })),
|
|
5220
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: {
|
|
5221
|
+
width: isMedium ? "50%" : 300,
|
|
5222
|
+
flexShrink: isMedium ? 1 : 0,
|
|
5223
|
+
flex: isMedium ? 1 : void 0,
|
|
5224
|
+
overflow: "hidden",
|
|
5225
|
+
borderRight: `1px solid ${theme.border}`
|
|
5226
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5227
|
+
InspectorPanel,
|
|
5228
|
+
{
|
|
5229
|
+
snapshots: activeSnapshots,
|
|
5230
|
+
selectedIndex: safeIdx,
|
|
5231
|
+
dataTraceFrames: runtimeSnapshot?.commitLog ? buildDataTrace(runtimeSnapshot.commitLog, activeSnapshots[safeIdx]?.runtimeStageId ?? "") : [],
|
|
5232
|
+
selectedStageId: activeSnapshots[safeIdx]?.runtimeStageId,
|
|
5233
|
+
onNavigateToStage: (id) => {
|
|
5234
|
+
const idx = activeSnapshots.findIndex((s) => s.runtimeStageId === id);
|
|
5235
|
+
if (idx >= 0) setSnapshotIdx(idx);
|
|
4700
5236
|
}
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
5237
|
+
}
|
|
5238
|
+
) }),
|
|
5239
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { style: { flex: 1, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5240
|
+
InsightPanel,
|
|
5241
|
+
{
|
|
5242
|
+
mode: !leftExpanded && !isMedium ? "grid" : "tabs",
|
|
5243
|
+
expandedId: activeTab,
|
|
5244
|
+
insights: allTabs.filter((t) => t.id !== "result").map((tab) => ({
|
|
5245
|
+
id: tab.id,
|
|
5246
|
+
name: insightName(tab.name),
|
|
5247
|
+
render: () => {
|
|
5248
|
+
if (tab.id === "memory") return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(MemoryPanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, size, style: { height: "100%" } });
|
|
5249
|
+
if (tab.id === "narrative") return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(NarrativePanel, { snapshots: activeSnapshots, selectedIndex: safeIdx, narrativeEntries: activeNarrativeEntries, narrative: activeNarrative, size, style: { height: "100%" } });
|
|
5250
|
+
const customView = recorderViews?.find((v2) => v2.id === tab.id);
|
|
5251
|
+
if (customView?.render) return customView.render({ snapshots: activeSnapshots, selectedIndex: safeIdx });
|
|
5252
|
+
const autoView = autoRecorderViews.find((v2) => v2.id === tab.id);
|
|
5253
|
+
if (autoView) return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(KeyedRecorderView, { data: autoView.data, description: autoView.description, preferredOperation: autoView.preferredOperation, snapshots: activeSnapshots, selectedIndex: safeIdx });
|
|
5254
|
+
return null;
|
|
5255
|
+
}
|
|
5256
|
+
}))
|
|
5257
|
+
}
|
|
5258
|
+
) })
|
|
5259
|
+
] }),
|
|
5260
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
5261
|
+
CompactTimeline,
|
|
5262
|
+
{
|
|
4706
5263
|
snapshots: activeSnapshots,
|
|
4707
5264
|
selectedIndex: safeIdx,
|
|
4708
|
-
|
|
4709
|
-
}
|
|
4710
|
-
|
|
4711
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VLinePill, { label: rightLabel, expanded: true, onClick: () => toggleRight(false) }),
|
|
4712
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { flex: 1, overflow: "hidden" }, children: detailsPanel })
|
|
4713
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VLinePill, { label: rightLabel, expanded: false, onClick: () => toggleRight(true) })
|
|
4714
|
-
] }),
|
|
4715
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HLinePill, { label: bottomLabel, detail: `${activeSnapshots.length} stages`, expanded: timelineExpanded, onClick: toggleTimeline }),
|
|
4716
|
-
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 }) })
|
|
4717
|
-
] })
|
|
4718
|
-
) : (
|
|
4719
|
-
/* ── Desktop without topology: details panel takes full width ── */
|
|
4720
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
|
|
4721
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { style: { flex: 1, overflow: "hidden" }, children: detailsPanel }),
|
|
4722
|
-
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(HLinePill, { label: bottomLabel, detail: `${activeSnapshots.length} stages`, expanded: timelineExpanded, onClick: toggleTimeline }),
|
|
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 }) })
|
|
5265
|
+
defaultExpanded: timelineExpanded
|
|
5266
|
+
}
|
|
5267
|
+
)
|
|
4724
5268
|
] })
|
|
4725
5269
|
) })
|
|
4726
5270
|
]
|
|
@@ -4729,9 +5273,13 @@ function ExplainableShell({
|
|
|
4729
5273
|
}
|
|
4730
5274
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4731
5275
|
0 && (module.exports = {
|
|
5276
|
+
CompactTimeline,
|
|
5277
|
+
DataTracePanel,
|
|
4732
5278
|
ExplainableShell,
|
|
4733
5279
|
FootprintTheme,
|
|
4734
5280
|
GanttTimeline,
|
|
5281
|
+
InsightPanel,
|
|
5282
|
+
InspectorPanel,
|
|
4735
5283
|
MemoryInspector,
|
|
4736
5284
|
MemoryPanel,
|
|
4737
5285
|
NarrativeLog,
|