@pipelex/mthds-ui 0.6.4 → 0.7.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/{chunk-FHRUYFGV.js → chunk-ILX53OYM.js} +374 -98
- package/dist/chunk-ILX53OYM.js.map +1 -0
- package/dist/chunk-L24K3TZU.js +1 -0
- package/dist/graph/index.d.ts +62 -7
- package/dist/graph/index.js +20 -4
- package/dist/graph/react/detail/DetailPanel.css +146 -87
- package/dist/graph/react/graph-core.css +153 -76
- package/dist/graph/react/index.css +169 -168
- package/dist/graph/react/index.css.map +1 -1
- package/dist/graph/react/index.d.ts +32 -3
- package/dist/graph/react/index.js +392 -215
- package/dist/graph/react/index.js.map +1 -1
- package/dist/graph/react/stuff/StuffViewer.css +38 -11
- package/dist/graph/react/viewer/GraphToolbar.css +22 -24
- package/dist/index.d.ts +2 -2
- package/dist/index.js +20 -4
- package/dist/shiki/index.d.ts +16 -3
- package/dist/shiki/index.js +226 -15
- package/dist/shiki/index.js.map +1 -1
- package/dist/standalone/graph-standalone.html +368 -207
- package/dist/standalone/graph-viewer.css +359 -198
- package/dist/standalone/graph-viewer.js +9 -9
- package/dist/{types-C7rr1Egj.d.ts → types-DJTrDxjV.d.ts} +29 -10
- package/package.json +3 -1
- package/dist/chunk-FHRUYFGV.js.map +0 -1
- package/dist/chunk-IZ4FH2WM.js +0 -1
- /package/dist/{chunk-IZ4FH2WM.js.map → chunk-L24K3TZU.js.map} +0 -0
|
@@ -5,6 +5,19 @@ import {
|
|
|
5
5
|
} from "./chunk-2NMEKWO5.js";
|
|
6
6
|
|
|
7
7
|
// src/graph/types.ts
|
|
8
|
+
var PIPE_TYPE_PRESENCE = {
|
|
9
|
+
PipeLLM: true,
|
|
10
|
+
PipeExtract: true,
|
|
11
|
+
PipeCompose: true,
|
|
12
|
+
PipeImgGen: true,
|
|
13
|
+
PipeSearch: true,
|
|
14
|
+
PipeFunc: true,
|
|
15
|
+
PipeSequence: true,
|
|
16
|
+
PipeParallel: true,
|
|
17
|
+
PipeCondition: true,
|
|
18
|
+
PipeBatch: true
|
|
19
|
+
};
|
|
20
|
+
var KNOWN_PIPE_TYPES = new Set(Object.keys(PIPE_TYPE_PRESENCE));
|
|
8
21
|
var NODE_TYPE_PIPE_CARD = "pipeCard";
|
|
9
22
|
var NODE_TYPE_STUFF = "default";
|
|
10
23
|
var NODE_TYPE_CONTROLLER = "controllerGroup";
|
|
@@ -39,6 +52,10 @@ var FOLD_MODE = {
|
|
|
39
52
|
/** Renderer decides — reserved for future heuristics; currently behaves like EXPANDED. */
|
|
40
53
|
AUTO: "auto"
|
|
41
54
|
};
|
|
55
|
+
var GRAPH_THEME = {
|
|
56
|
+
DARK: "dark",
|
|
57
|
+
LIGHT: "light"
|
|
58
|
+
};
|
|
42
59
|
var CONTROLLER_PADDING_X = 40;
|
|
43
60
|
var CONTROLLER_PADDING_TOP = 48;
|
|
44
61
|
var CONTROLLER_PADDING_BOTTOM = 20;
|
|
@@ -60,6 +77,161 @@ function nodeHeight(n) {
|
|
|
60
77
|
return ((_b = n.data) == null ? void 0 : _b.isStuff) ? 60 : 70;
|
|
61
78
|
}
|
|
62
79
|
|
|
80
|
+
// src/graph/validateGraphSpec.ts
|
|
81
|
+
var GraphSpecValidationError = class extends Error {
|
|
82
|
+
constructor(path, detail) {
|
|
83
|
+
const location = path === "" ? "<root>" : path;
|
|
84
|
+
super(`GraphSpec validation failed at ${location}: ${detail}`);
|
|
85
|
+
this.name = "GraphSpecValidationError";
|
|
86
|
+
this.path = path;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
var PIPE_STATUSES = /* @__PURE__ */ new Set([
|
|
90
|
+
"succeeded",
|
|
91
|
+
"failed",
|
|
92
|
+
"running",
|
|
93
|
+
"scheduled",
|
|
94
|
+
"skipped",
|
|
95
|
+
"canceled"
|
|
96
|
+
]);
|
|
97
|
+
var EDGE_KINDS = /* @__PURE__ */ new Set([
|
|
98
|
+
"contains",
|
|
99
|
+
"data",
|
|
100
|
+
"control",
|
|
101
|
+
"selected_outcome",
|
|
102
|
+
"batch_item",
|
|
103
|
+
"batch_aggregate",
|
|
104
|
+
"parallel_combine"
|
|
105
|
+
]);
|
|
106
|
+
function isPlainObject(value) {
|
|
107
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
108
|
+
}
|
|
109
|
+
function describe(value) {
|
|
110
|
+
if (value === null) return "null";
|
|
111
|
+
if (value === void 0) return "undefined";
|
|
112
|
+
if (Array.isArray(value)) return "an array";
|
|
113
|
+
return `a ${typeof value}`;
|
|
114
|
+
}
|
|
115
|
+
function fail(path, detail) {
|
|
116
|
+
throw new GraphSpecValidationError(path, detail);
|
|
117
|
+
}
|
|
118
|
+
function requireNonEmptyString(value, path) {
|
|
119
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
120
|
+
fail(path, `expected a non-empty string, got ${describe(value)}`);
|
|
121
|
+
}
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
function validateIoItem(item, path) {
|
|
125
|
+
if (!isPlainObject(item)) {
|
|
126
|
+
fail(path, `expected an object, got ${describe(item)}`);
|
|
127
|
+
}
|
|
128
|
+
requireNonEmptyString(item.name, `${path}.name`);
|
|
129
|
+
}
|
|
130
|
+
function validateNode(node, path) {
|
|
131
|
+
if (!isPlainObject(node)) {
|
|
132
|
+
fail(path, `expected an object, got ${describe(node)}`);
|
|
133
|
+
}
|
|
134
|
+
requireNonEmptyString(node.id, `${path}.id`);
|
|
135
|
+
if (node.kind !== "controller" && node.kind !== "operator") {
|
|
136
|
+
fail(
|
|
137
|
+
`${path}.kind`,
|
|
138
|
+
`expected "controller" or "operator" \u2014 a real pipelex run emits only pipe-call nodes, got ${JSON.stringify(node.kind)}`
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
if (typeof node.status !== "string" || !PIPE_STATUSES.has(node.status)) {
|
|
142
|
+
fail(
|
|
143
|
+
`${path}.status`,
|
|
144
|
+
`expected one of ${[...PIPE_STATUSES].join(", ")}, got ${JSON.stringify(node.status)}`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
requireNonEmptyString(node.pipe_code, `${path}.pipe_code`);
|
|
148
|
+
const pipeType = requireNonEmptyString(node.pipe_type, `${path}.pipe_type`);
|
|
149
|
+
if (!KNOWN_PIPE_TYPES.has(pipeType)) {
|
|
150
|
+
fail(
|
|
151
|
+
`${path}.pipe_type`,
|
|
152
|
+
`unrecognized pipe class "${pipeType}" \u2014 add it to PipeOperatorType or PipeControllerType in types.ts`
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
requireNonEmptyString(node.description, `${path}.description`);
|
|
156
|
+
requireNonEmptyString(node.domain_code, `${path}.domain_code`);
|
|
157
|
+
let io = node.io;
|
|
158
|
+
if (io === void 0) {
|
|
159
|
+
io = { inputs: [], outputs: [] };
|
|
160
|
+
node.io = io;
|
|
161
|
+
}
|
|
162
|
+
if (!isPlainObject(io)) {
|
|
163
|
+
fail(`${path}.io`, `expected an object, got ${describe(io)}`);
|
|
164
|
+
}
|
|
165
|
+
if (io.inputs === void 0) {
|
|
166
|
+
io.inputs = [];
|
|
167
|
+
} else if (!Array.isArray(io.inputs)) {
|
|
168
|
+
fail(`${path}.io.inputs`, `expected an array, got ${describe(io.inputs)}`);
|
|
169
|
+
}
|
|
170
|
+
if (io.outputs === void 0) {
|
|
171
|
+
io.outputs = [];
|
|
172
|
+
} else if (!Array.isArray(io.outputs)) {
|
|
173
|
+
fail(`${path}.io.outputs`, `expected an array, got ${describe(io.outputs)}`);
|
|
174
|
+
}
|
|
175
|
+
io.inputs.forEach((item, j) => validateIoItem(item, `${path}.io.inputs[${j}]`));
|
|
176
|
+
io.outputs.forEach((item, j) => validateIoItem(item, `${path}.io.outputs[${j}]`));
|
|
177
|
+
}
|
|
178
|
+
function validateEdge(edge, path) {
|
|
179
|
+
if (!isPlainObject(edge)) {
|
|
180
|
+
fail(path, `expected an object, got ${describe(edge)}`);
|
|
181
|
+
}
|
|
182
|
+
requireNonEmptyString(edge.id, `${path}.id`);
|
|
183
|
+
requireNonEmptyString(edge.source, `${path}.source`);
|
|
184
|
+
requireNonEmptyString(edge.target, `${path}.target`);
|
|
185
|
+
if (typeof edge.kind !== "string" || !EDGE_KINDS.has(edge.kind)) {
|
|
186
|
+
fail(
|
|
187
|
+
`${path}.kind`,
|
|
188
|
+
`expected one of ${[...EDGE_KINDS].join(", ")}, got ${JSON.stringify(edge.kind)}`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function validateGraphSpec(raw) {
|
|
193
|
+
if (!isPlainObject(raw)) {
|
|
194
|
+
fail("", `expected a GraphSpec object, got ${describe(raw)}`);
|
|
195
|
+
}
|
|
196
|
+
if (!Array.isArray(raw.nodes)) {
|
|
197
|
+
fail("nodes", `expected an array, got ${describe(raw.nodes)}`);
|
|
198
|
+
}
|
|
199
|
+
if (!Array.isArray(raw.edges)) {
|
|
200
|
+
fail("edges", `expected an array, got ${describe(raw.edges)}`);
|
|
201
|
+
}
|
|
202
|
+
if (!isPlainObject(raw.meta)) {
|
|
203
|
+
fail("meta", `expected an object, got ${describe(raw.meta)}`);
|
|
204
|
+
}
|
|
205
|
+
if (raw.meta.format !== "mthds") {
|
|
206
|
+
fail(
|
|
207
|
+
"meta.format",
|
|
208
|
+
`expected "mthds" (this does not look like pipelex GraphSpec JSON), got ${JSON.stringify(raw.meta.format)}`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
if (raw.pipe_registry !== void 0 && !isPlainObject(raw.pipe_registry)) {
|
|
212
|
+
fail("pipe_registry", `expected an object when present, got ${describe(raw.pipe_registry)}`);
|
|
213
|
+
}
|
|
214
|
+
if (raw.concept_registry !== void 0 && !isPlainObject(raw.concept_registry)) {
|
|
215
|
+
fail(
|
|
216
|
+
"concept_registry",
|
|
217
|
+
`expected an object when present, got ${describe(raw.concept_registry)}`
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
raw.nodes.forEach((node, i) => validateNode(node, `nodes[${i}]`));
|
|
221
|
+
raw.edges.forEach((edge, i) => validateEdge(edge, `edges[${i}]`));
|
|
222
|
+
return raw;
|
|
223
|
+
}
|
|
224
|
+
function asPipeCallNode(node, path = "node") {
|
|
225
|
+
if (node.kind !== "controller" && node.kind !== "operator") {
|
|
226
|
+
fail(
|
|
227
|
+
`${path}.kind`,
|
|
228
|
+
`expected a pipe-call node ("controller" or "operator"), got ${JSON.stringify(node.kind)}`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
requireNonEmptyString(node.pipe_code, `${path}.pipe_code`);
|
|
232
|
+
return node;
|
|
233
|
+
}
|
|
234
|
+
|
|
63
235
|
// src/graph/graphAnalysis.ts
|
|
64
236
|
function buildDataflowAnalysis(graphspec) {
|
|
65
237
|
if (!graphspec) return null;
|
|
@@ -77,9 +249,9 @@ function buildDataflowAnalysis(graphspec) {
|
|
|
77
249
|
}
|
|
78
250
|
const controllerNodeIds = new Set(Object.keys(containmentTree));
|
|
79
251
|
for (const node of graphspec.nodes) {
|
|
80
|
-
const nodeIo = node.io
|
|
252
|
+
const nodeIo = node.io;
|
|
81
253
|
const isController = controllerNodeIds.has(node.id);
|
|
82
|
-
for (const output of nodeIo.outputs
|
|
254
|
+
for (const output of nodeIo.outputs) {
|
|
83
255
|
if (output.digest && !stuffRegistry[output.digest]) {
|
|
84
256
|
stuffRegistry[output.digest] = {
|
|
85
257
|
name: output.name,
|
|
@@ -91,7 +263,7 @@ function buildDataflowAnalysis(graphspec) {
|
|
|
91
263
|
stuffProducers[output.digest] = node.id;
|
|
92
264
|
}
|
|
93
265
|
}
|
|
94
|
-
for (const input of nodeIo.inputs
|
|
266
|
+
for (const input of nodeIo.inputs) {
|
|
95
267
|
if (input.digest && !stuffRegistry[input.digest]) {
|
|
96
268
|
stuffRegistry[input.digest] = {
|
|
97
269
|
name: input.name,
|
|
@@ -115,7 +287,6 @@ function buildDataflowAnalysis(graphspec) {
|
|
|
115
287
|
};
|
|
116
288
|
}
|
|
117
289
|
function buildChildToControllerMap(graphspec, analysis) {
|
|
118
|
-
var _a;
|
|
119
290
|
const childToController = {};
|
|
120
291
|
for (const [ctrlId, children] of Object.entries(analysis.containmentTree)) {
|
|
121
292
|
for (const childId of children) {
|
|
@@ -133,7 +304,7 @@ function buildChildToControllerMap(graphspec, analysis) {
|
|
|
133
304
|
if (!analysis.controllerNodeIds.has(node.id)) continue;
|
|
134
305
|
const parentCtrlId = childToController[node.id];
|
|
135
306
|
if (!parentCtrlId) continue;
|
|
136
|
-
for (const output of
|
|
307
|
+
for (const output of node.io.outputs) {
|
|
137
308
|
if (!output.digest) continue;
|
|
138
309
|
const stuffId = "stuff_" + output.digest;
|
|
139
310
|
if (!childToController[stuffId]) {
|
|
@@ -214,55 +385,20 @@ function resolveConceptRef(spec, codeOrRef) {
|
|
|
214
385
|
}
|
|
215
386
|
|
|
216
387
|
// src/graph/pipeCardPayload.ts
|
|
217
|
-
function
|
|
218
|
-
const code = pipeCode || "this step";
|
|
219
|
-
const verb = {
|
|
220
|
-
PipeLLM: "Analyze and generate output using",
|
|
221
|
-
PipeExtract: "Extract content from",
|
|
222
|
-
PipeCompose: "Compose output using",
|
|
223
|
-
PipeImgGen: "Generate image for",
|
|
224
|
-
PipeSearch: "Search the web for",
|
|
225
|
-
PipeFunc: "Process data in"
|
|
226
|
-
};
|
|
227
|
-
return `${verb[pipeType] || "Execute"} ${code.replace(/_/g, " ")}`;
|
|
228
|
-
}
|
|
229
|
-
function buildPipeCardPayload(node, graphspec, analysis) {
|
|
230
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
231
|
-
const pipeType = node.pipe_type;
|
|
232
|
-
const pipeCode = node.pipe_code || node.id;
|
|
233
|
-
const isController = analysis.controllerNodeIds.has(node.id);
|
|
234
|
-
const inputs = ((_b = (_a = node.io) == null ? void 0 : _a.inputs) != null ? _b : []).map((i) => {
|
|
235
|
-
var _a2, _b2;
|
|
236
|
-
return {
|
|
237
|
-
name: (_a2 = i.name) != null ? _a2 : "",
|
|
238
|
-
concept: (_b2 = i.concept) != null ? _b2 : ""
|
|
239
|
-
};
|
|
240
|
-
});
|
|
241
|
-
const outputs = ((_d = (_c = node.io) == null ? void 0 : _c.outputs) != null ? _d : []).map((o) => {
|
|
242
|
-
var _a2, _b2;
|
|
243
|
-
return {
|
|
244
|
-
name: (_a2 = o.name) != null ? _a2 : "",
|
|
245
|
-
concept: (_b2 = o.concept) != null ? _b2 : ""
|
|
246
|
-
};
|
|
247
|
-
});
|
|
248
|
-
const registryDescription = node.pipe_code ? (_f = (_e = graphspec.pipe_registry) == null ? void 0 : _e[node.pipe_code]) == null ? void 0 : _f.description : void 0;
|
|
249
|
-
let description;
|
|
250
|
-
if (node.description) {
|
|
251
|
-
description = node.description;
|
|
252
|
-
} else if (registryDescription) {
|
|
253
|
-
description = registryDescription;
|
|
254
|
-
} else if (isController) {
|
|
255
|
-
description = void 0;
|
|
256
|
-
} else {
|
|
257
|
-
description = defaultDescription(pipeType, node.pipe_code);
|
|
258
|
-
}
|
|
388
|
+
function buildPipeCardPayload(node) {
|
|
259
389
|
return {
|
|
260
|
-
pipeCode,
|
|
261
|
-
pipeType,
|
|
262
|
-
description,
|
|
263
|
-
status:
|
|
264
|
-
inputs
|
|
265
|
-
|
|
390
|
+
pipeCode: node.pipe_code,
|
|
391
|
+
pipeType: node.pipe_type,
|
|
392
|
+
description: node.description,
|
|
393
|
+
status: node.status,
|
|
394
|
+
inputs: node.io.inputs.map((i) => {
|
|
395
|
+
var _a;
|
|
396
|
+
return { name: i.name, concept: (_a = i.concept) != null ? _a : "" };
|
|
397
|
+
}),
|
|
398
|
+
outputs: node.io.outputs.map((o) => {
|
|
399
|
+
var _a;
|
|
400
|
+
return { name: o.name, concept: (_a = o.concept) != null ? _a : "" };
|
|
401
|
+
})
|
|
266
402
|
};
|
|
267
403
|
}
|
|
268
404
|
|
|
@@ -285,20 +421,21 @@ function buildDataflowGraph(graphspec, analysis, edgeType) {
|
|
|
285
421
|
}
|
|
286
422
|
for (const node of graphspec.nodes) {
|
|
287
423
|
if (!participatingPipes.has(node.id)) continue;
|
|
288
|
-
const
|
|
289
|
-
const
|
|
290
|
-
const
|
|
424
|
+
const pipeNode = asPipeCallNode(node, `nodes[${node.id}]`);
|
|
425
|
+
const isFailed = pipeNode.status === "failed";
|
|
426
|
+
const label = pipeNode.pipe_code;
|
|
427
|
+
const pipeCardData = buildPipeCardPayload(pipeNode);
|
|
291
428
|
nodes.push({
|
|
292
|
-
id:
|
|
429
|
+
id: pipeNode.id,
|
|
293
430
|
type: NODE_TYPE_PIPE_CARD,
|
|
294
431
|
data: {
|
|
295
432
|
labelDescriptor: { kind: "pipe", label, isFailed },
|
|
296
|
-
nodeData:
|
|
433
|
+
nodeData: pipeNode,
|
|
297
434
|
isPipe: true,
|
|
298
435
|
isStuff: false,
|
|
299
436
|
labelText: label,
|
|
300
437
|
pipeCode: pipeCardData.pipeCode,
|
|
301
|
-
pipeType:
|
|
438
|
+
pipeType: pipeNode.pipe_type,
|
|
302
439
|
pipeCardData
|
|
303
440
|
},
|
|
304
441
|
position: { x: 0, y: 0 }
|
|
@@ -306,7 +443,7 @@ function buildDataflowGraph(graphspec, analysis, edgeType) {
|
|
|
306
443
|
}
|
|
307
444
|
for (const [digest, stuffInfo] of Object.entries(analysis.stuffRegistry)) {
|
|
308
445
|
const stuffId = stuffNodeId(digest);
|
|
309
|
-
const label = stuffInfo.name
|
|
446
|
+
const label = stuffInfo.name;
|
|
310
447
|
const concept = stuffInfo.concept || "";
|
|
311
448
|
const textWidth = Math.max(label.length, concept.length) * STUFF_CHAR_WIDTH_PX + STUFF_LABEL_PADDING;
|
|
312
449
|
const stuffWidth = Math.max(MIN_STUFF_WIDTH, textWidth);
|
|
@@ -377,7 +514,7 @@ function buildDataflowGraph(graphspec, analysis, edgeType) {
|
|
|
377
514
|
const sourceId = stuffNodeId(edge.source_stuff_digest);
|
|
378
515
|
const targetId = stuffNodeId(edge.target_stuff_digest);
|
|
379
516
|
edges.push({
|
|
380
|
-
id: edge.id
|
|
517
|
+
id: edge.id,
|
|
381
518
|
source: sourceId,
|
|
382
519
|
target: targetId,
|
|
383
520
|
type: "smoothstep",
|
|
@@ -402,7 +539,7 @@ function buildDataflowGraph(graphspec, analysis, edgeType) {
|
|
|
402
539
|
const targetId = stuffNodeId(edge.target_stuff_digest);
|
|
403
540
|
const isBatchItem = edge.kind === "batch_item";
|
|
404
541
|
edges.push({
|
|
405
|
-
id: edge.id
|
|
542
|
+
id: edge.id,
|
|
406
543
|
source: sourceId,
|
|
407
544
|
target: targetId,
|
|
408
545
|
type: edgeType,
|
|
@@ -548,7 +685,7 @@ function applyFolds(graphData, analysis, graphspec, foldedSet, onToggleFold) {
|
|
|
548
685
|
if (outermostFoldedAncestor(folded, childToCtrl, foldedSet)) continue;
|
|
549
686
|
const specNode = findSpecNode(graphspec, folded);
|
|
550
687
|
if (!specNode) continue;
|
|
551
|
-
const payload = buildPipeCardPayload(specNode,
|
|
688
|
+
const payload = buildPipeCardPayload(asPipeCallNode(specNode, folded));
|
|
552
689
|
if (onToggleFold) {
|
|
553
690
|
payload.onExpand = (options) => onToggleFold(folded, options);
|
|
554
691
|
}
|
|
@@ -1096,7 +1233,7 @@ function buildControllerNodes(graphspec, analysis, layoutedNodes, controllerPosi
|
|
|
1096
1233
|
const controllerInfo = {};
|
|
1097
1234
|
for (const node of graphspec.nodes) {
|
|
1098
1235
|
if (analysis.controllerNodeIds.has(node.id)) {
|
|
1099
|
-
controllerInfo[node.id] = node;
|
|
1236
|
+
controllerInfo[node.id] = asPipeCallNode(node, `nodes[${node.id}]`);
|
|
1100
1237
|
}
|
|
1101
1238
|
}
|
|
1102
1239
|
const depthCache = {};
|
|
@@ -1168,8 +1305,14 @@ function buildControllerNodes(graphspec, analysis, layoutedNodes, controllerPosi
|
|
|
1168
1305
|
groupW = maxX - minX + 2 * padX;
|
|
1169
1306
|
groupH = maxY - minY + padTop + padBottom;
|
|
1170
1307
|
}
|
|
1171
|
-
const info = controllerInfo[controllerId]
|
|
1172
|
-
|
|
1308
|
+
const info = controllerInfo[controllerId];
|
|
1309
|
+
if (!info) {
|
|
1310
|
+
throw new GraphSpecValidationError(
|
|
1311
|
+
`nodes[${controllerId}]`,
|
|
1312
|
+
`controller "${controllerId}" is referenced by a "contains" edge but has no corresponding node in graphspec.nodes`
|
|
1313
|
+
);
|
|
1314
|
+
}
|
|
1315
|
+
const pipeCode = info.pipe_code;
|
|
1173
1316
|
const groupNode = {
|
|
1174
1317
|
id: controllerId,
|
|
1175
1318
|
type: NODE_TYPE_CONTROLLER,
|
|
@@ -1319,50 +1462,176 @@ function applyControllers(layoutedNodes, layoutedEdges, graphspec, analysis, sho
|
|
|
1319
1462
|
}
|
|
1320
1463
|
|
|
1321
1464
|
// src/graph/graphConfig.ts
|
|
1465
|
+
var FONT_TOKENS = {
|
|
1466
|
+
"--font-sans": '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
1467
|
+
"--font-mono": '"JetBrains Mono", "Monaco", "Menlo", monospace'
|
|
1468
|
+
};
|
|
1469
|
+
var DARK_PALETTE_COLORS = __spreadProps(__spreadValues({}, FONT_TOKENS), {
|
|
1470
|
+
// Surfaces
|
|
1471
|
+
"--surface-page": "#0a0a0a",
|
|
1472
|
+
"--surface-panel": "#111118",
|
|
1473
|
+
"--surface-overlay": "rgba(17, 17, 24, 0.8)",
|
|
1474
|
+
"--surface-overlay-hover": "rgba(30, 30, 40, 0.9)",
|
|
1475
|
+
"--surface-overlay-disabled": "rgba(17, 17, 24, 0.6)",
|
|
1476
|
+
"--surface-elevated": "rgba(255, 255, 255, 0.06)",
|
|
1477
|
+
"--surface-elevated-hover": "rgba(255, 255, 255, 0.1)",
|
|
1478
|
+
"--surface-sunken": "rgba(255, 255, 255, 0.03)",
|
|
1479
|
+
"--surface-pill": "rgba(255, 255, 255, 0.06)",
|
|
1480
|
+
"--surface-pill-border": "rgba(255, 255, 255, 0.08)",
|
|
1481
|
+
// Borders
|
|
1482
|
+
"--border-subtle": "rgba(255, 255, 255, 0.06)",
|
|
1483
|
+
"--border-default": "rgba(255, 255, 255, 0.1)",
|
|
1484
|
+
"--border-strong": "rgba(255, 255, 255, 0.18)",
|
|
1485
|
+
"--border-dashed": "rgba(255, 255, 255, 0.15)",
|
|
1486
|
+
// Text
|
|
1487
|
+
"--text-primary": "#f8fafc",
|
|
1488
|
+
"--text-default": "#e2e8f0",
|
|
1489
|
+
"--text-secondary": "#cbd5e1",
|
|
1490
|
+
"--text-muted": "#94a3b8",
|
|
1491
|
+
"--text-dim": "#64748b",
|
|
1492
|
+
"--text-on-accent": "#0e0e0e",
|
|
1493
|
+
// Effects
|
|
1494
|
+
"--shadow-sm": "0 2px 8px rgba(0, 0, 0, 0.4)",
|
|
1495
|
+
"--shadow-md": "0 4px 16px rgba(0, 0, 0, 0.6)",
|
|
1496
|
+
"--shadow-lg": "0 8px 24px rgba(0, 0, 0, 0.5)",
|
|
1497
|
+
"--focus-ring": "rgba(59, 130, 246, 0.6)",
|
|
1498
|
+
// Domain-semantic colors (graph nodes/edges)
|
|
1499
|
+
"--color-pipe": "#ff6b6b",
|
|
1500
|
+
"--color-pipe-bg": "rgba(224,108,117,0.18)",
|
|
1501
|
+
"--color-pipe-text": "#ffffff",
|
|
1502
|
+
"--color-stuff": "#4ECDC4",
|
|
1503
|
+
"--color-stuff-bg": "rgba(78,205,196,0.12)",
|
|
1504
|
+
"--color-stuff-border": "#9ddcfd",
|
|
1505
|
+
"--color-stuff-text": "#98FB98",
|
|
1506
|
+
"--color-stuff-text-dim": "#9ddcfd",
|
|
1507
|
+
"--color-edge": "#FFFACD",
|
|
1508
|
+
"--color-batch-item": "#bd93f9",
|
|
1509
|
+
"--color-batch-aggregate": "#50fa7b",
|
|
1510
|
+
"--color-parallel-combine": "#d6a4ff",
|
|
1511
|
+
"--color-success": "#50FA7B",
|
|
1512
|
+
"--color-success-bg": "rgba(80,250,123,0.15)",
|
|
1513
|
+
"--color-error": "#FF5555",
|
|
1514
|
+
"--color-error-bg": "rgba(255,85,85,0.15)",
|
|
1515
|
+
"--color-error-border": "rgba(255,85,85,0.2)",
|
|
1516
|
+
"--color-accent": "#8BE9FD",
|
|
1517
|
+
"--color-accent-strong": "#3b82f6",
|
|
1518
|
+
"--color-warning": "#FFB86C",
|
|
1519
|
+
// Controller-group palette (tinted borders/backgrounds per controller type)
|
|
1520
|
+
"--ctrl-sequence-border": "rgba(148, 163, 184, 0.25)",
|
|
1521
|
+
"--ctrl-sequence-bg": "rgba(148, 163, 184, 0.03)",
|
|
1522
|
+
"--ctrl-sequence-text": "#94a3b8",
|
|
1523
|
+
"--ctrl-parallel-border": "rgba(139, 233, 253, 0.35)",
|
|
1524
|
+
"--ctrl-parallel-bg": "rgba(139, 233, 253, 0.03)",
|
|
1525
|
+
"--ctrl-parallel-text": "#8be9fd",
|
|
1526
|
+
"--ctrl-condition-border": "rgba(251, 191, 36, 0.35)",
|
|
1527
|
+
"--ctrl-condition-bg": "rgba(251, 191, 36, 0.03)",
|
|
1528
|
+
"--ctrl-condition-text": "#fbbf24",
|
|
1529
|
+
"--ctrl-batch-border": "rgba(167, 139, 250, 0.35)",
|
|
1530
|
+
"--ctrl-batch-bg": "rgba(167, 139, 250, 0.03)",
|
|
1531
|
+
"--ctrl-batch-text": "#a78bfa",
|
|
1532
|
+
"--ctrl-folded-bg": "rgba(148, 163, 184, 0.25)",
|
|
1533
|
+
"--ctrl-folded-border": "rgba(148, 163, 184, 0.4)",
|
|
1534
|
+
// Legacy aliases — kept so existing inline styles in graph builders keep
|
|
1535
|
+
// working until they're migrated. New code should use the semantic tokens.
|
|
1536
|
+
"--color-bg": "#0a0a0a",
|
|
1537
|
+
"--color-bg-dots": "rgba(255, 255, 255, 0.35)",
|
|
1538
|
+
"--color-text-muted": "#94a3b8",
|
|
1539
|
+
"--color-controller-text": "#94a3b8"
|
|
1540
|
+
});
|
|
1541
|
+
var LIGHT_PALETTE_COLORS = __spreadProps(__spreadValues({}, FONT_TOKENS), {
|
|
1542
|
+
// Surfaces — chart stays a soft off-white, panels slightly cooler
|
|
1543
|
+
"--surface-page": "#f8fafc",
|
|
1544
|
+
"--surface-panel": "#ffffff",
|
|
1545
|
+
"--surface-overlay": "rgba(255, 255, 255, 0.92)",
|
|
1546
|
+
"--surface-overlay-hover": "rgba(241, 245, 249, 0.96)",
|
|
1547
|
+
"--surface-overlay-disabled": "rgba(255, 255, 255, 0.7)",
|
|
1548
|
+
"--surface-elevated": "rgba(15, 23, 42, 0.05)",
|
|
1549
|
+
"--surface-elevated-hover": "rgba(15, 23, 42, 0.09)",
|
|
1550
|
+
"--surface-sunken": "rgba(15, 23, 42, 0.03)",
|
|
1551
|
+
"--surface-pill": "rgba(15, 23, 42, 0.05)",
|
|
1552
|
+
"--surface-pill-border": "rgba(15, 23, 42, 0.1)",
|
|
1553
|
+
// Borders
|
|
1554
|
+
"--border-subtle": "rgba(15, 23, 42, 0.08)",
|
|
1555
|
+
"--border-default": "rgba(15, 23, 42, 0.12)",
|
|
1556
|
+
"--border-strong": "rgba(15, 23, 42, 0.22)",
|
|
1557
|
+
"--border-dashed": "rgba(15, 23, 42, 0.18)",
|
|
1558
|
+
// Text
|
|
1559
|
+
"--text-primary": "#020617",
|
|
1560
|
+
"--text-default": "#0f172a",
|
|
1561
|
+
"--text-secondary": "#1e293b",
|
|
1562
|
+
"--text-muted": "#475569",
|
|
1563
|
+
"--text-dim": "#64748b",
|
|
1564
|
+
"--text-on-accent": "#ffffff",
|
|
1565
|
+
// Effects
|
|
1566
|
+
"--shadow-sm": "0 2px 8px rgba(15, 23, 42, 0.08)",
|
|
1567
|
+
"--shadow-md": "0 4px 16px rgba(15, 23, 42, 0.14)",
|
|
1568
|
+
"--shadow-lg": "0 8px 24px rgba(15, 23, 42, 0.15)",
|
|
1569
|
+
"--focus-ring": "rgba(2, 132, 199, 0.5)",
|
|
1570
|
+
// Domain-semantic colors — darker for contrast on light backgrounds
|
|
1571
|
+
"--color-pipe": "#dc2626",
|
|
1572
|
+
"--color-pipe-bg": "rgba(220, 38, 38, 0.1)",
|
|
1573
|
+
"--color-pipe-text": "#ffffff",
|
|
1574
|
+
"--color-stuff": "#0891b2",
|
|
1575
|
+
"--color-stuff-bg": "rgba(8, 145, 178, 0.08)",
|
|
1576
|
+
"--color-stuff-border": "#0e7490",
|
|
1577
|
+
"--color-stuff-text": "#0f172a",
|
|
1578
|
+
"--color-stuff-text-dim": "#475569",
|
|
1579
|
+
"--color-edge": "#64748b",
|
|
1580
|
+
"--color-batch-item": "#7c3aed",
|
|
1581
|
+
"--color-batch-aggregate": "#15803d",
|
|
1582
|
+
"--color-parallel-combine": "#6d28d9",
|
|
1583
|
+
"--color-success": "#15803d",
|
|
1584
|
+
"--color-success-bg": "rgba(21, 128, 61, 0.12)",
|
|
1585
|
+
"--color-error": "#dc2626",
|
|
1586
|
+
"--color-error-bg": "rgba(220, 38, 38, 0.1)",
|
|
1587
|
+
"--color-error-border": "rgba(220, 38, 38, 0.25)",
|
|
1588
|
+
"--color-accent": "#0284c7",
|
|
1589
|
+
"--color-accent-strong": "#0284c7",
|
|
1590
|
+
"--color-warning": "#d97706",
|
|
1591
|
+
// Controller-group palette
|
|
1592
|
+
"--ctrl-sequence-border": "rgba(71, 85, 105, 0.3)",
|
|
1593
|
+
"--ctrl-sequence-bg": "rgba(71, 85, 105, 0.04)",
|
|
1594
|
+
"--ctrl-sequence-text": "#475569",
|
|
1595
|
+
"--ctrl-parallel-border": "rgba(8, 145, 178, 0.4)",
|
|
1596
|
+
"--ctrl-parallel-bg": "rgba(8, 145, 178, 0.05)",
|
|
1597
|
+
"--ctrl-parallel-text": "#0e7490",
|
|
1598
|
+
"--ctrl-condition-border": "rgba(217, 119, 6, 0.4)",
|
|
1599
|
+
"--ctrl-condition-bg": "rgba(217, 119, 6, 0.05)",
|
|
1600
|
+
"--ctrl-condition-text": "#b45309",
|
|
1601
|
+
"--ctrl-batch-border": "rgba(124, 58, 237, 0.4)",
|
|
1602
|
+
"--ctrl-batch-bg": "rgba(124, 58, 237, 0.05)",
|
|
1603
|
+
"--ctrl-batch-text": "#6d28d9",
|
|
1604
|
+
"--ctrl-folded-bg": "rgba(71, 85, 105, 0.18)",
|
|
1605
|
+
"--ctrl-folded-border": "rgba(71, 85, 105, 0.35)",
|
|
1606
|
+
// Legacy aliases
|
|
1607
|
+
"--color-bg": "#f8fafc",
|
|
1608
|
+
"--color-bg-dots": "rgba(15, 23, 42, 0.18)",
|
|
1609
|
+
"--color-text-muted": "#475569",
|
|
1610
|
+
"--color-controller-text": "#475569"
|
|
1611
|
+
});
|
|
1612
|
+
function getPaletteForTheme(theme) {
|
|
1613
|
+
return theme === GRAPH_THEME.LIGHT ? LIGHT_PALETTE_COLORS : DARK_PALETTE_COLORS;
|
|
1614
|
+
}
|
|
1322
1615
|
var DEFAULT_GRAPH_CONFIG = {
|
|
1323
1616
|
direction: "LR",
|
|
1324
1617
|
showControllers: false,
|
|
1325
1618
|
foldMode: FOLD_MODE.EXPANDED,
|
|
1619
|
+
theme: GRAPH_THEME.DARK,
|
|
1326
1620
|
nodesep: 50,
|
|
1327
1621
|
ranksep: 100,
|
|
1328
1622
|
edgeType: EDGE_TYPE.DEFAULT,
|
|
1329
1623
|
initialZoom: null,
|
|
1330
|
-
panToTop: true
|
|
1331
|
-
paletteColors
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
"--color-pipe-bg": "rgba(224,108,117,0.18)",
|
|
1335
|
-
"--color-pipe-text": "#ffffff",
|
|
1336
|
-
"--color-stuff": "#4ECDC4",
|
|
1337
|
-
"--color-stuff-bg": "rgba(78,205,196,0.12)",
|
|
1338
|
-
"--color-stuff-border": "#9ddcfd",
|
|
1339
|
-
"--color-stuff-text": "#98FB98",
|
|
1340
|
-
"--color-stuff-text-dim": "#9ddcfd",
|
|
1341
|
-
"--color-edge": "#FFFACD",
|
|
1342
|
-
"--color-batch-item": "#bd93f9",
|
|
1343
|
-
"--color-batch-aggregate": "#50fa7b",
|
|
1344
|
-
"--color-parallel-combine": "#d6a4ff",
|
|
1345
|
-
"--color-success": "#50FA7B",
|
|
1346
|
-
"--color-success-bg": "rgba(80,250,123,0.15)",
|
|
1347
|
-
"--color-error": "#FF5555",
|
|
1348
|
-
"--color-error-bg": "rgba(255,85,85,0.15)",
|
|
1349
|
-
"--color-accent": "#8BE9FD",
|
|
1350
|
-
"--color-warning": "#FFB86C",
|
|
1351
|
-
// Base theme vars used by graph-core.css
|
|
1352
|
-
"--color-bg": "#0a0a0a",
|
|
1353
|
-
"--color-bg-dots": "rgba(255, 255, 255, 0.35)",
|
|
1354
|
-
"--color-text-muted": "#94a3b8",
|
|
1355
|
-
"--color-controller-text": "#94a3b8",
|
|
1356
|
-
"--font-sans": '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
1357
|
-
"--font-mono": '"JetBrains Mono", "Monaco", "Menlo", monospace',
|
|
1358
|
-
"--shadow-lg": "0 8px 24px rgba(0, 0, 0, 0.5)"
|
|
1359
|
-
}
|
|
1624
|
+
panToTop: true
|
|
1625
|
+
// `paletteColors` intentionally omitted from the default. The viewer derives
|
|
1626
|
+
// the palette from the active `theme`. Consumers only set `paletteColors` to
|
|
1627
|
+
// override specific tokens (sparse merge on top of the theme palette).
|
|
1360
1628
|
};
|
|
1361
1629
|
function getPaletteColors() {
|
|
1362
|
-
return
|
|
1630
|
+
return DARK_PALETTE_COLORS;
|
|
1363
1631
|
}
|
|
1364
1632
|
|
|
1365
1633
|
export {
|
|
1634
|
+
KNOWN_PIPE_TYPES,
|
|
1366
1635
|
NODE_TYPE_PIPE_CARD,
|
|
1367
1636
|
NODE_TYPE_STUFF,
|
|
1368
1637
|
NODE_TYPE_CONTROLLER,
|
|
@@ -1373,12 +1642,16 @@ export {
|
|
|
1373
1642
|
GRAPH_DIRECTION,
|
|
1374
1643
|
EDGE_TYPE,
|
|
1375
1644
|
FOLD_MODE,
|
|
1645
|
+
GRAPH_THEME,
|
|
1376
1646
|
CONTROLLER_PADDING_X,
|
|
1377
1647
|
CONTROLLER_PADDING_TOP,
|
|
1378
1648
|
CONTROLLER_PADDING_BOTTOM,
|
|
1379
1649
|
ARROW_CLOSED_MARKER,
|
|
1380
1650
|
nodeWidth,
|
|
1381
1651
|
nodeHeight,
|
|
1652
|
+
GraphSpecValidationError,
|
|
1653
|
+
validateGraphSpec,
|
|
1654
|
+
asPipeCallNode,
|
|
1382
1655
|
buildDataflowAnalysis,
|
|
1383
1656
|
buildChildToControllerMap,
|
|
1384
1657
|
getPipeBlueprint,
|
|
@@ -1400,7 +1673,10 @@ export {
|
|
|
1400
1673
|
MAX_VISIBLE_CONTROLLER_CHILDREN,
|
|
1401
1674
|
buildControllerNodes,
|
|
1402
1675
|
applyControllers,
|
|
1676
|
+
DARK_PALETTE_COLORS,
|
|
1677
|
+
LIGHT_PALETTE_COLORS,
|
|
1678
|
+
getPaletteForTheme,
|
|
1403
1679
|
DEFAULT_GRAPH_CONFIG,
|
|
1404
1680
|
getPaletteColors
|
|
1405
1681
|
};
|
|
1406
|
-
//# sourceMappingURL=chunk-
|
|
1682
|
+
//# sourceMappingURL=chunk-ILX53OYM.js.map
|